{"version":3,"mappings":"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QAAS,CACP,KAAM,YACN,SAAU,cACV,MAAO,8BACP,UAAW,CACT,KAAM,CACJ,KAAM,UACN,SAAU,sBACV,MAAO,wCACP,UAAW,CAAC,CACd,EACA,KAAM,CACJ,KAAM,eACN,SAAU,2BACV,MAAO,6CACP,UAAW,CAAC,CACd,CACF,CACF,EACA,OAAQ,CACN,KAAM,WACN,SAAU,aACV,MAAO,6BACP,UAAW,CAAC,CACd,CACF,CACF,EACA,MAAO,CACL,KAAM,UACN,SAAU,SACV,MAAO,sBACP,UAAW,CACT,QAAS,CACP,KAAM,YACN,SAAU,gBACV,MAAO,gCACP,UAAW,CAAC,CACd,EACA,OAAQ,CACN,KAAM,WACN,SAAU,eACV,MAAO,+BACP,UAAW,CAAC,CACd,EACA,OAAQ,CACN,KAAM,WACN,SAAU,eACV,MAAO,+BACP,UAAW,CAAC,CACd,EACA,SAAU,CACR,KAAM,aACN,SAAU,iBACV,MAAO,iCACP,UAAW,CAAC,CACd,CACF,CACF,EACA,QAAS,CACP,KAAM,YACN,SAAU,WACV,MAAO,wBACP,UAAW,CACT,MAAO,CACL,KAAM,QACN,SAAU,gBACV,MAAO,gCACP,UAAW,CAAC,CACd,EACA,YAAa,CACX,KAAM,eACN,SAAU,uBACV,MAAO,uCACP,UAAW,CAAC,CACd,EACA,gBAAiB,CACf,KAAM,mBACN,SAAU,2BACV,MAAO,2CACP,UAAW,CAAC,CACd,EACA,2BAA4B,CAC1B,KAAM,+BACN,SAAU,uCACV,MAAO,uDACP,UAAW,CAAC,CACd,EACA,gBAAiB,CACf,KAAM,mBACN,SAAU,2BACV,MAAO,2CACP,UAAW,CAAC,CACd,EACA,QAAS,CACP,KAAM,UACN,SAAU,kBACV,MAAO,kCACP,UAAW,CAAC,CACd,EACA,aAAc,CACZ,KAAM,gBACN,SAAU,wBACV,MAAO,wCACP,UAAW,CAAC,CACd,EACA,MAAO,CACL,KAAM,oBACN,SAAU,4BACV,MAAO,4CACP,UAAW,CAAC,CACd,EACA,QAAS,CACP,KAAM,UACN,SAAU,kBACV,MAAO,kCACP,UAAW,CAAC,CACd,EACA,SAAU,CACR,KAAM,W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","names":["BHPalette","orange","teal","grey","FontWeight","defaultTheme","createTheme","theme","colors.grey","green","mapColor","color","mapVariant","variant","mapComponent","component","Literal","fontWeight","sx","children","typographyProps","useTheme","mappedVariant","mappedColor","mappedComponent","fontSize","defaultFontWeight","props","jsx","Typography","FullScreenSpinner","jsxs","Fragment","LinearProgress","InlineSpinner","Box","BoxSpinner","circularSize","CircularProgress","ModalSpinner","rest","Modal","Spinner","spinnerProps","BookingStep","Country","StorageKey","compare","left","right","caseSensitive","hasLeft","hasRight","options","areEqual","strings","capitalizeFirstLetter","value","bookingTimeoutMills","clearStateFromLocalStorage","storeStateInLocalStorage","state","restoreStateFromLocalStorage","currentPracticeId","json","practiceId","lastUpdatedMillis","timeSlotIso","reservation","unconfirmedReservation","appointment","modelRest","now","DateTime","timeSlot","model","startTime","endTime","timeZone","reservationRest","BookingStorageService","ProviderOnlineStatusCodes","routes","BHB_ROOT_ROUTE","RouteMap","path","query","absolute","url","urlJoin","qs","stepOrRoute","route","locationId","BookingStore","__publicField","delta","runInAction","key","appointmentTypeId","_a","x","step","forceReplace","replace","makeObservable","observable","computed","action","reaction","toJS","_b","bookingStorage","next","saveForLaterFavorite","id","appointmentType","at","practice","appointmentTypes","providers","restored","requestedStep","isNewPatient","isAppointmentForUser","dependantId","_c","hasPatient","nextScreen","DEFAULT_NOTIFICATION_TIMEOUT_MILLIS","_NotificationStore","titleOrMessage","details","timeoutMillis","type","expiresAtMillis","message","existing","n","hasTitleAndMessage","notification","NotificationStore","define_import_meta_env_default","providerOnlineStatusOrder","providerSortOnProviderOnlineStatus","a","b","sortProvidersForTimeSlotSelector","sortProvidersForPracticeTeam","getCountry","timezones","timezone","getSortedDates","dates","as","isObjectEmpty","obj","o","createAddressValidationSchema","isRequired","yup.object","yup.string","con","country","AddressRestrictions","LocalCountry","getDefaultAddress","DateTimeSchema","BaseSchema","originalValue","dateTime","ref","name","Reference","exprValue","castValue","min","defaults","limit","max","resolvedMax","yupExtensions","PersonMeta","person","lastNameResult","PersonValidationSchema","DateOfBirthSchema","MobileNumberValidationSchema","DependantValidationSchema","yup.boolean","Environment","UserPreferencesStore","config","useAccount","notificationStore","userPreferencesStore","bookingStore","RootStore","StoreContext","createContext","StoreContextProvider","useRootStore","useContext","useBookingStore","useNotificationStore","useUserPreferencesStore","NotificationTally","count","hide","SlideRight","Slide","Toast","observer","onDismiss","autoHideDuration","handleDismiss","handleClose","event","reason","hasTitle","messageVariant","Snackbar","Alert","Notifications","store","useCallback","useAppInsightsPageViewTracker","appInsightPlugin","useAppInsightsContext","location","useLocation","useEffect","DEFAULT_PAGE_TITLE","getRouteTitle","getRouteNesting","acc","item","i","getRoutesTitles","aNesting","routesTitles","usePageTitle","overridePageTitle","match","rt","Layout","lazy","__vitePreload","modules","AppModule","allowAnonymous","Component","Authenticated","spinnerMessage","AppRoutes","Suspense","Routes","resolveComponent","Route","hasMessage","error","ErrorBox","title","errorMessage","text","ErrorBoundaryFallback","queryClient","QueryClient","ReactQueryProvider","QueryClientProvider","useIsMobileView","useUserAgent","VHRATIO","useWindowHeightResize","isMobile","documentHeight","initAppInsights","appInsightConfig","AppInsightsReactPlugin","ApplicationInsights","useAnalyticsInit","gaMeasurementId","ReactGA","useAnalyticsEffect","effect","deps","HOTJAR_VERSION","initHotJar","siteId","Hotjar","configure","App","AppInsightsContext","CssBaseline","ThemeProvider","MsalProvider","getAppInstance","LocalizationProvider","AdapterLuxon","Router","ErrorBoundary","reportWebVitals","onPerfEntry","getCLS","getFID","getFCP","getLCP","getTTFB","ReactDOM","StrictMode"],"sources":["../../src/components/theme.tsx","../../src/components/Literal.tsx","../../src/components/Spinner.tsx","../../src/core/domain/booking/Enums.ts","../../src/core/store/Storage.ts","../../src/core/strings.ts","../../src/core/services/booking/BookingStorageService.ts","../../src/modules/bhb/pages/select-appointment-slot/types.ts","../../src/core/routes/routes.ts","../../src/modules/bhb/RouteMap.ts","../../src/core/store/BookingStore.ts","../../src/core/store/NotificationStore.ts","../../src/config.ts","../../src/pages/common/utils.ts","../../src/core/domain/Address.ts","../../src/core/validation/yupExtensions.ts","../../src/core/domain/Person.ts","../../src/core/domain/Dependant.ts","../../src/core/domain/Environment.ts","../../src/core/store/UserPreferencesStore.ts","../../src/core/store/RootStore.tsx","../../src/layout/Notifications.tsx","../../src/core/analytics/app-insights/app-insights.hooks.ts","../../src/core/routes/routes.types.ts","../../src/core/routes/routes.utils.ts","../../src/core/hooks/usePageTitle.ts","../../src/AppRoutes.tsx","../../src/components/ErrorBox.tsx","../../src/components/ErrorBoundaryFallback.tsx","../../src/core/services/ReactQueryProvider.tsx","../../src/components/hooks/useIsMobileView.tsx","../../src/components/hooks/useWindowHeightResize.tsx","../../src/core/analytics/app-insights/app-insights.utils.ts","../../src/core/analytics/google-analytics/google-analytics.hooks.ts","../../src/core/analytics/hotjar/hot-jar.utils.ts","../../src/App.tsx","../../src/reportWebVitals.ts","../../src/index.tsx"],"sourcesContent":["import { CSSProperties } from \"react\";\n\nimport \"@mui/lab/themeAugmentation\";\nimport { colors } from \"@mui/material\";\nimport { green, grey, orange, teal } from \"@mui/material/colors\";\nimport { createTheme } from \"@mui/material/styles\";\n\n// https://www.figma.com/file/sY2JlDgKlr8E9pxKLWR8Y4/Manage-Account?node-id=131%3A865\n// For colour swatches, see: https://next.material-ui.com/customization/color/#color-palette\nexport const BHPalette = {\n primary: orange[800],\n secondary: teal[700],\n\n grey: {\n header: \"#FEFEFE\",\n subheader: grey[50],\n separator: grey[200]\n },\n\n accents: {\n secondaryActive: teal[50]\n },\n\n body: {\n BHW: grey[100]\n },\n\n custom: {\n byline: \"#5c5c5c\"\n },\n\n text: {\n dark: {\n primary: \"rgba(0, 0, 0, .87)\",\n secondary: \"rgba(0, 0, 0, .54)\",\n disabled: \"rgba(0, 0, 0, .38)\"\n },\n light: {\n primary: \"rgba(255, 255, 255, 1)\",\n secondary: \"rgba(255, 255, 255, .7)\",\n disabled: \"rgba(255, 255, 255, .5)\"\n }\n }\n};\n\nexport enum FontWeight {\n /** Equivalent of FontWeight 400 */\n regular = 400,\n /** Equivalent of FontWeight 500 */\n medium = 500\n}\n\n// Custom breakpoints for main BHW web app.\ndeclare module \"@mui/material/styles\" {\n interface BreakpointOverrides {\n baseLayoutXL: true; // adds the `baseLayoutXL` breakpoint\n baseLayoutL: true;\n baseLayoutMD: true;\n baseLayoutSM: true;\n }\n}\n\nconst defaultTheme = createTheme();\n\n// Apply the theme to the default Material UI theme\nexport const theme = createTheme({\n components: {\n MuiModal: {\n styleOverrides: {\n root: {\n \".MuiPaper-root\": { borderRadius: \"20px\" },\n \".MuiDialogTitle-root\": { paddingTop: 24 },\n \".MuiDialogContent-root\": { paddingBottom: 24 }\n }\n }\n },\n MuiButton: {\n styleOverrides: {\n root: {\n textTransform: \"none\"\n }\n }\n },\n MuiToolbar: {\n styleOverrides: {\n dense: {\n height: 60,\n minHeight: 60\n }\n }\n },\n MuiCalendarPicker: {\n styleOverrides: {\n root: {\n \".MuiPickersDay-root.Mui-disabled\": {\n color: colors.grey[300]\n },\n // Targets the day of week buttons (most specific class found)\n \".MuiTypography-root\": {\n color: colors.grey[900]\n }\n }\n }\n }\n },\n breakpoints: {\n values: {\n ...defaultTheme.breakpoints.values,\n baseLayoutXL: 1920,\n baseLayoutL: 1440,\n baseLayoutMD: 1366,\n baseLayoutSM: 1024\n }\n },\n palette: {\n text: {\n ...BHPalette.text.dark\n },\n primary: {\n main: BHPalette.primary,\n light: orange[50]\n },\n secondary: {\n main: BHPalette.secondary,\n 50: BHPalette.accents.secondaryActive,\n dark: teal[900]\n },\n header: {\n main: BHPalette.grey.header,\n sub: BHPalette.grey.subheader,\n byline: BHPalette.custom.byline\n },\n background: {\n default: BHPalette.body.BHW\n },\n separator: BHPalette.grey.separator,\n accent: {\n iconBackground: green[800],\n text: \"#1E1E1E\",\n containerBackground: green[800]\n }\n },\n typography: {\n headline: {\n fontSize: \"24px\",\n fontWeight: FontWeight.regular\n },\n title1: {\n fontSize: \"20px\",\n fontWeight: FontWeight.medium\n },\n title2: {\n fontSize: \"20px\",\n fontWeight: FontWeight.regular\n },\n body1: {\n fontSize: \"14px\",\n fontWeight: FontWeight.regular\n },\n body2: {\n fontSize: \"13px\",\n fontWeight: FontWeight.medium\n },\n body3: {\n fontSize: \"16px\",\n fontWeight: FontWeight.regular\n },\n body4: {\n fontSize: \"14px\",\n fontWeight: FontWeight.medium\n },\n button: {\n fontSize: \"14px\",\n fontWeight: FontWeight.medium\n }\n }\n});\n\n// Augment the declared theme with the added typography variants\ndeclare module \"@mui/material/styles\" {\n interface PaletteOptions {\n header: {\n main: string;\n sub: string;\n byline: string;\n };\n separator: string;\n accent: {\n iconBackground: string;\n containerBackground: string;\n text: string;\n };\n }\n\n interface Palette {\n header: PaletteOptions[\"header\"];\n separator: string;\n accent: PaletteOptions[\"accent\"];\n }\n\n interface TypographyVariants {\n headline: CSSProperties;\n title1: CSSProperties;\n title2: CSSProperties;\n body3: CSSProperties;\n }\n\n // allow configuration using `createTheme`\n interface TypographyVariantsOptions {\n headline?: CSSProperties;\n title1?: CSSProperties;\n title2?: CSSProperties;\n body3?: CSSProperties;\n body4?: CSSProperties;\n }\n}\n","import { BHPalette, FontWeight } from \"components/theme\";\nimport { ElementType, PropsWithChildren } from \"react\";\n\nimport { Typography, TypographyProps, useTheme } from \"@mui/material\";\nimport { Variant } from \"@mui/material/styles/createTypography\";\n\ntype FontColor = \"p\" | \"s\" | \"d\";\ntype TextVariant =\n | \"headline\"\n | \"title1\"\n | \"title2\"\n | \"body1\"\n | \"body2\"\n | \"body3\"\n | \"body4\"\n | \"button\";\n\nexport interface LiteralProps\n extends Omit {\n /**\n * The theme font color to use - [P]rimary, [S]econdary, or [D]isabled\n * @default: 'p'\n */\n color?: FontColor | string;\n\n /**\n * The variant to use to dictate the default component, font size and weight.\n *\n * @remarks By default, the variants map to the following component | font size | font weight\n * ```\n * headline: h1 | 24px | regular\n * title1: h2 | 20px | medium\n * title2: h3 | 20px | regular\n * body1: span | 14px | regular\n * body2: span | 13px | medium\n * body3: span | 16px | regular\n * body4: span | 14px | medium\n * button: span | 20px | medium | uppercase\n * ```\n * @default: 'body1'\n */\n variant?: TextVariant;\n\n /**\n * Optionally override the font weight.\n */\n fontWeight?: FontWeight;\n\n /**\n * The component to render.\n * @default: 'span'\n */\n component?: ElementType;\n}\n\nconst mapColor = (color?: FontColor | string): string => {\n if (!color) return BHPalette.text.dark.primary;\n\n switch (color) {\n case \"s\":\n return BHPalette.text.dark.secondary;\n case \"d\":\n return BHPalette.text.dark.disabled;\n case \"p\":\n return BHPalette.text.dark.primary;\n default:\n return color;\n }\n};\n\nconst mapVariant = (variant?: TextVariant): Variant => {\n switch (variant) {\n case \"headline\":\n return \"h1\";\n case \"title1\":\n return \"h2\";\n case \"title2\":\n return \"h3\";\n case \"button\":\n return \"button\";\n case \"body1\":\n case \"body2\":\n case \"body3\":\n case \"body4\":\n default:\n return \"body1\";\n }\n};\n\nconst mapComponent = (\n component?: ElementType,\n variant?: TextVariant\n): ElementType | undefined => {\n if (component) return component;\n\n switch (variant) {\n case \"body1\":\n case \"body2\":\n case \"body3\":\n case \"body4\":\n return \"span\";\n\n default:\n return undefined;\n }\n};\n\nexport const Literal = ({\n color,\n fontWeight,\n variant,\n component,\n sx,\n children,\n ...typographyProps\n}: PropsWithChildren) => {\n const theme = useTheme();\n const mappedVariant = mapVariant(variant);\n const mappedColor = mapColor(color);\n const mappedComponent = mapComponent(component, variant);\n\n // We need to create literal props as an object literal to spread, otherwise TS complains if `component` is undefined\n const { fontSize, fontWeight: defaultFontWeight } =\n theme.typography[variant ?? \"body1\"];\n\n const props = {\n ...typographyProps,\n component: mappedComponent,\n variant: mappedVariant,\n color: mappedColor,\n sx: {\n fontSize,\n fontWeight: fontWeight ?? defaultFontWeight,\n ...(sx || {})\n }\n };\n\n return {children};\n};\n","import { Literal } from \"components/Literal\";\nimport { PropsWithChildren } from \"react\";\n\nimport {\n Box,\n CircularProgress,\n LinearProgress,\n Modal,\n useTheme\n} from \"@mui/material\";\nimport { SxProps } from \"@mui/system\";\n\ninterface SpinnerSxProps {\n sx?: SxProps;\n circularSize?: number;\n}\n\nexport interface SpinnerProps extends SpinnerSxProps {\n variant?: \"normal\" | \"inline\" | \"fullscreen\" | \"modal\";\n}\n\nconst FullScreenSpinner = ({\n sx,\n children\n}: PropsWithChildren) => {\n return (\n <>\n \n \n {children}\n \n \n );\n};\n\nconst InlineSpinner = ({ sx, children }: PropsWithChildren) => {\n return (\n \n \n {children}\n \n );\n};\n\nconst BoxSpinner = ({\n sx,\n children,\n circularSize\n}: PropsWithChildren) => {\n return (\n \n \n {children}\n \n );\n};\n\nconst ModalSpinner = ({ sx, ...rest }: PropsWithChildren) => {\n const theme = useTheme();\n\n return (\n \n \n \n \n \n );\n};\n\nexport const Spinner = ({\n variant,\n ...spinnerProps\n}: PropsWithChildren) => {\n switch (variant) {\n case \"fullscreen\":\n return ;\n case \"modal\":\n return ;\n case \"inline\":\n return ;\n\n case \"normal\":\n default:\n return ;\n }\n};\n","export enum BookingStep {\n Unknown = 0,\n SelectPatientType = 1,\n SelectAppointmentType = 2,\n AppointmentTypeInformation = 3,\n SelectAppointmentSlot = 4,\n CompleteProfile = 5,\n SelectPatient = 6,\n AddDependant = 7,\n AddPatientNotes = 8,\n ConfirmBooking = 9,\n BookingSuccess = 10,\n NotAcceptingBookings = 11,\n NotAcceptingNewPatients = 12,\n PracticeOutage = 13\n // to be defined for new step\n}\nexport enum Country {\n Australia = \"AU\",\n NewZealand = \"NZ\"\n}\n","// Keys used for entries in local storage\nexport const StorageKey = {\n BHB_RETURN_PARAMS: \"@bp:bhb\",\n BHB_WIZARD_MODEL: \"@bp:booking\",\n CORRELATION_ID: \"@bp:correlation-id\"\n};\n","const compare = (left?: string, right?: string, caseSensitive = false) => {\n // Purposely using type-coercion here to see if the values are nullish\n const hasLeft = left != null;\n const hasRight = right != null;\n\n if (hasLeft && hasRight) {\n const options: Intl.CollatorOptions = {\n sensitivity: caseSensitive ? \"variant\" : \"accent\"\n };\n\n return left.localeCompare(right, [], options);\n }\n\n if (hasLeft) return 1;\n if (hasRight) return -1;\n return 0;\n};\n\nconst areEqual = (left?: string, right?: string, caseSensitive = false) =>\n compare(left, right, caseSensitive) === 0;\n\nexport const strings = {\n compare,\n areEqual\n};\n\nexport const capitalizeFirstLetter = (value: string) => {\n return value.charAt(0).toUpperCase() + value.toLowerCase().slice(1);\n};\n","import {\n BookingState,\n ConfirmedAppointment,\n ConfirmedReservation,\n UnconfirmedReservation\n} from \"core/domain/booking/BookingState\";\nimport { StorageKey } from \"core/store/Storage\";\nimport { strings } from \"core/strings\";\nimport { guid } from \"core/types\";\nimport { DateTime } from \"luxon\";\n\ntype StoredReservation = Omit<\n ConfirmedReservation,\n \"startTime\" | \"endTime\" | \"timeZone\"\n> & {\n startTime: string;\n endTime: string;\n timeZone: string;\n};\n\ntype StoredAppointment = Omit<\n ConfirmedAppointment,\n \"startTime\" | \"timeZone\"\n> & {\n startTime: string;\n timeZone: string;\n};\n\ntype StoredUnconfirmedReservation = Omit<\n UnconfirmedReservation,\n \"startTime\" | \"endTime\"\n> & {\n startTime: string;\n endTime: string;\n};\n\ntype StoredWizardState = Omit<\n BookingState,\n | \"appointmentStartTime\"\n | \"reservation\"\n | \"appointment\"\n | \"unconfirmedReservation\"\n> & {\n timeSlot?: string;\n reservation?: StoredReservation;\n appointment?: StoredAppointment;\n unconfirmedReservation?: StoredUnconfirmedReservation;\n lastUpdatedMillis: number;\n};\n\nexport const bookingTimeoutMills = 15 * 60 * 1000;\n\nconst clearStateFromLocalStorage = () => {\n localStorage.removeItem(StorageKey.BHB_WIZARD_MODEL);\n return undefined;\n};\n\nconst storeStateInLocalStorage = (state?: BookingState) => {\n if (state) {\n // The DateTime.toJSON() method is called when serializing to JSON, which actually calls toISO() and creates a string.\n // Note that some information is lost in the process (the locale, the zone (but not its offset) are for instance not serialized).\n // This code below stores the reservation timeZone, so we can persist this information post page refresh.\n state &&\n state.reservation &&\n (state.reservation.timeZone = state.reservation.startTime.zoneName);\n state &&\n state.unconfirmedReservation &&\n (state.unconfirmedReservation.timeZone =\n state.unconfirmedReservation.startTime.zoneName);\n state &&\n state.appointment &&\n (state.appointment.timeZone = state.appointment.startTime.zoneName);\n\n localStorage.setItem(\n StorageKey.BHB_WIZARD_MODEL,\n JSON.stringify({\n ...state,\n lastUpdatedMillis: new Date().valueOf()\n })\n );\n } else {\n clearStateFromLocalStorage();\n }\n};\n\nconst restoreStateFromLocalStorage = (\n currentPracticeId: guid\n): BookingState | undefined => {\n // Rehydrate the return parameters from local storage when the store is constructed\n const json = localStorage.getItem(StorageKey.BHB_WIZARD_MODEL);\n if (!json) return undefined;\n\n const {\n practiceId,\n lastUpdatedMillis,\n timeSlot: timeSlotIso,\n reservation,\n unconfirmedReservation,\n appointment,\n ...modelRest\n } = JSON.parse(json) as StoredWizardState;\n\n // If the practiceId stored in the state is different to the current practice, then throw out the state.\n if (!strings.areEqual(currentPracticeId, practiceId)) {\n return clearStateFromLocalStorage();\n }\n\n // If the booking is stale, then throw out the state.\n const now = DateTime.now();\n if (\n lastUpdatedMillis &&\n lastUpdatedMillis <= now.valueOf() - bookingTimeoutMills\n ) {\n return clearStateFromLocalStorage();\n }\n\n // If the time slot has expired, then throw out the state.\n const timeSlot = timeSlotIso ? DateTime.fromISO(timeSlotIso) : undefined;\n if (timeSlot && timeSlot <= now) {\n return clearStateFromLocalStorage();\n }\n\n const model: BookingState = { ...modelRest, practiceId };\n\n if (reservation) {\n const { startTime, endTime, timeZone, ...reservationRest } = reservation;\n\n model.reservation = {\n ...reservationRest,\n startTime: DateTime.fromISO(startTime, { zone: timeZone }), // Restore timeZone property for display purposes\n endTime: DateTime.fromISO(endTime, { zone: timeZone }) // Restore timeZone property for display purposes\n };\n }\n\n if (unconfirmedReservation) {\n const { startTime, endTime, timeZone, ...rest } = unconfirmedReservation;\n\n model.unconfirmedReservation = {\n ...rest,\n startTime: DateTime.fromISO(startTime, { zone: timeZone }), // Restore timeZone property for display purposes\n endTime: DateTime.fromISO(endTime, { zone: timeZone }) // Restore timeZone property for display purposes\n };\n }\n\n if (appointment) {\n const { startTime, timeZone } = appointment;\n\n model.appointment = {\n ...appointment,\n startTime: DateTime.fromISO(startTime, { zone: timeZone })\n };\n }\n\n return model;\n};\n\nexport const BookingStorageService = {\n storeState: storeStateInLocalStorage,\n restoreState: restoreStateFromLocalStorage\n};\n","import type { ProviderTimeSlot } from \"core/domain/booking\";\nimport { DateTime } from \"luxon\";\n\n/**\n * All the times that are available for a single day\n */\nexport interface DailyAvailableTimes {\n day: DateTime;\n startTimes: DateTime[];\n pageIndex: number;\n}\n\nexport type ProviderTimeSlotEventHandler = (\n providerTimeSlot: ProviderTimeSlot\n) => void | Promise;\n\nexport const ProviderOnlineStatusCodes = {\n yes: \"YES\",\n no: \"NO\",\n call: \"CALL\"\n};\n","import { Route, RouteKey } from \"./routes.types\";\n\n/**\n * This object describes BHB routes\n */\nexport const routes: Record = {\n profile: {\n path: \"profile/*\",\n fullPath: \"/profile\",\n title: \"My profile | Best Health\",\n subRoutes: {\n profileDetails: {\n path: \"details\",\n fullPath: \"profile/details\",\n title: \"My profile | Details | Best Health\",\n subRoutes: {\n profileDetailEdit: {\n path: \"edit\",\n fullPath: \"details/edit\",\n title: \"My profile | Edit Details | Best Health\",\n subRoutes: {}\n }\n }\n },\n profileSecurity: {\n path: \"security\",\n fullPath: \"profile/security\",\n title: \"My profile | Security | Best Health\",\n subRoutes: {}\n },\n profileManagement: {\n path: \"management\",\n fullPath: \"profile/management\",\n title: \"My profile | Account Management | Best Health\",\n subRoutes: {}\n },\n profileIncomplete: {\n path: \"incomplete\",\n fullPath: \"profile/incomplete\",\n title: \"My profile | Complete | Best Health\",\n subRoutes: {}\n }\n }\n },\n appointments: {\n path: \"/appointments/*\",\n fullPath: \"/appointments\",\n title: \"My appointments | Best Health\",\n subRoutes: {}\n },\n family: {\n path: \"/family/*\",\n fullPath: \"/family\",\n title: \"Family members | Best Health\",\n subRoutes: {\n addDependant: {\n path: \"add\",\n fullPath: \"family/add\",\n title: \"Family members | Add new | Best Health\",\n subRoutes: {}\n },\n editDependant: {\n path: \"edit\",\n fullPath: \"family/edit\",\n title: \"Family members | Edit | Best Health\",\n subRoutes: {}\n }\n }\n },\n dashboard: {\n path: \"/dashboard/*\",\n fullPath: \"/dashboard\",\n title: \"Dashboard | Best Health\",\n subRoutes: {\n dashboardProvider: {\n path: \"/provider/*\",\n fullPath: \"dashboard/provider\",\n title: \"Provider | Best Health\",\n subRoutes: {}\n },\n dashboardPractice: {\n path: \"/practice/*\",\n fullPath: \"dashboard/practice\",\n title: \"Practice | Best Health\",\n subRoutes: {}\n }\n }\n },\n bha: {\n path: \"/bha/*\",\n fullPath: \"/bha\",\n title: \"BHA | Best Health\",\n subRoutes: {\n profile: {\n path: \"profile/*\",\n fullPath: \"bha/profile\",\n title: \"BHA | Profile | Best Health\",\n subRoutes: {\n view: {\n path: \"details\",\n fullPath: \"bha/profile/details\",\n title: \"BHA | Profile | Details | Best Health\",\n subRoutes: {}\n },\n edit: {\n path: \"details/edit\",\n fullPath: \"bha/profile/details/edit\",\n title: \"BHA | Profile | Edit details | Best Health\",\n subRoutes: {}\n }\n }\n },\n family: {\n path: \"family/*\",\n fullPath: \"bha/family\",\n title: \"BHA | Family | Best Health\",\n subRoutes: {}\n }\n }\n },\n setup: {\n path: \"setup/*\",\n fullPath: \"/setup\",\n title: \"Setup | Best Health\",\n subRoutes: {\n confirm: {\n path: \"confirm/*\",\n fullPath: \"setup/confirm\",\n title: \"Setup | Confirm | Best Health\",\n subRoutes: {}\n },\n commit: {\n path: \"commit/*\",\n fullPath: \"setup/commit\",\n title: \"Setup | Commit | Best Health\",\n subRoutes: {}\n },\n cancel: {\n path: \"cancel/*\",\n fullPath: \"setup/cancel\",\n title: \"Setup | Cancel | Best Health\",\n subRoutes: {}\n },\n complete: {\n path: \"complete/*\",\n fullPath: \"setup/complete\",\n title: \"Setup | Complete | Best Health\",\n subRoutes: {}\n }\n }\n },\n booking: {\n path: \"booking/*\",\n fullPath: \"/booking\",\n title: \"Booking | Best Health\",\n subRoutes: {\n error: {\n path: \"error\",\n fullPath: \"booking/error\",\n title: \"Booking | Error | Best Health\",\n subRoutes: {}\n },\n patientType: {\n path: \"patient-type\",\n fullPath: \"booking/patient-type\",\n title: \"Booking | Patient type | Best Health\",\n subRoutes: {}\n },\n appointmentType: {\n path: \"appointment-type\",\n fullPath: \"booking/appointment-type\",\n title: \"Booking | Appointment Type | Best Health\",\n subRoutes: {}\n },\n appointmentTypeInformation: {\n path: \"appointment-type-information\",\n fullPath: \"booking/appointment-type-information\",\n title: \"Booking | Appointment Type Information | Best Health\",\n subRoutes: {}\n },\n appointmentSlot: {\n path: \"appointment-slot\",\n fullPath: \"booking/appointment-slot\",\n title: \"Booking | Appointment Time | Best Health\",\n subRoutes: {}\n },\n patient: {\n path: \"patient\",\n fullPath: \"booking/patient\",\n title: \"Booking | Patient | Best Health\",\n subRoutes: {}\n },\n addDependant: {\n path: \"add-dependant\",\n fullPath: \"booking/add-dependant\",\n title: \"Booking | Add Dependant | Best Health\",\n subRoutes: {}\n },\n notes: {\n path: \"add-patient-notes\",\n fullPath: \"booking/add-patient-notes\",\n title: \"Booking | Add Patient Notes | Best Health\",\n subRoutes: {}\n },\n confirm: {\n path: \"confirm\",\n fullPath: \"booking/confirm\",\n title: \"Booking | Confirm | Best Health\",\n subRoutes: {}\n },\n complete: {\n path: \"complete\",\n fullPath: \"booking/complete\",\n title: \"Booking | Confirmed | Best Health\",\n subRoutes: {}\n },\n unavailable: {\n path: \"unavailable\",\n fullPath: \"booking/unavailable\",\n title: \"Booking | Unavailable | Best Health\",\n subRoutes: {}\n },\n unaccepted: {\n path: \"unaccepted\",\n fullPath: \"booking/unaccepted\",\n title: \"Booking | Unaccepted | Best Health\",\n subRoutes: {}\n },\n practiceOutage: {\n path: \"practice-outage\",\n fullPath: \"booking/practice-outage\",\n title: \"Booking | Practice Outage | Best Health\",\n subRoutes: {}\n },\n completeProfile: {\n path: \"complete-profile\",\n fullPath: \"booking/complete-profile\",\n title: \"Booking | Complete profile | Best Health\",\n subRoutes: {}\n },\n policy: {\n path: \"policy/*\",\n fullPath: \"booking/policy\",\n title: \"Booking | Policy| Best Health\",\n subRoutes: {}\n },\n cancel: {\n path: \"cancellation/*\",\n fullPath: \"booking/cancellation\",\n title: \"Booking | Cancellation| Best Health\",\n subRoutes: {}\n },\n reschedule: {\n path: \"reschedule/*\",\n fullPath: \"booking/reschedule\",\n title: \"Booking | Reschedule| Best Health\",\n subRoutes: {}\n }\n }\n }\n};\n","import { BookingStep } from \"core/domain/booking/Enums\";\nimport { guid } from \"core/types\";\nimport qs, { StringifiableRecord } from \"query-string\";\nimport urlJoin from \"url-join\";\n\nimport { routes } from \"../../core/routes/routes\";\n\nexport const BHB_ROOT_ROUTE = \"/booking\";\n\nexport const RouteMap = {\n cancelBooking: \"cancellation/\",\n policy: \"policy/\",\n rescheduleBooking: \"reschedule/\",\n\n queries: {\n appointmentId: \"appointmentId\",\n locationId: \"locationId\"\n },\n\n bookingSteps: {\n [BookingStep.Unknown]: routes.booking.subRoutes.error.path,\n [BookingStep.SelectPatientType]: routes.booking.subRoutes.patientType.path,\n [BookingStep.SelectAppointmentType]:\n routes.booking.subRoutes.appointmentType.path,\n [BookingStep.AppointmentTypeInformation]:\n routes.booking.subRoutes.appointmentTypeInformation.path,\n [BookingStep.SelectAppointmentSlot]:\n routes.booking.subRoutes.appointmentSlot.path,\n [BookingStep.CompleteProfile]:\n routes.booking.subRoutes.completeProfile.path,\n [BookingStep.SelectPatient]: routes.booking.subRoutes.patient.path,\n [BookingStep.AddDependant]: routes.booking.subRoutes.addDependant.path,\n [BookingStep.AddPatientNotes]: routes.booking.subRoutes.notes.path,\n [BookingStep.ConfirmBooking]: routes.booking.subRoutes.confirm.path,\n [BookingStep.BookingSuccess]: routes.booking.subRoutes.complete.path,\n [BookingStep.NotAcceptingBookings]:\n routes.booking.subRoutes.unavailable.path,\n [BookingStep.NotAcceptingNewPatients]:\n routes.booking.subRoutes.unaccepted.path,\n [BookingStep.PracticeOutage]: routes.booking.subRoutes.practiceOutage.path\n },\n\n getBookingPath: (\n path: string,\n query: StringifiableRecord,\n absolute: boolean = false\n ) => {\n const url = absolute ? urlJoin(BHB_ROOT_ROUTE, path) : path;\n return qs.stringifyUrl({\n url,\n query\n });\n },\n\n getBookingStepPath: (\n stepOrRoute: BookingStep | string,\n practiceId: guid,\n absolute: boolean = false\n ) => {\n const route =\n typeof stepOrRoute === \"string\"\n ? stepOrRoute\n : RouteMap.bookingSteps[stepOrRoute];\n\n const url = absolute ? urlJoin(BHB_ROOT_ROUTE, route) : route;\n\n return qs.stringifyUrl({\n url,\n query: { locationId: practiceId }\n });\n },\n\n getBookingWizardAbsoluteUrl: () => {\n const { locationId } = qs.parse(window.location.search);\n\n return qs.stringifyUrl({\n url: urlJoin(\n window.location.origin,\n window.location.pathname,\n BHB_ROOT_ROUTE\n ),\n query: { locationId }\n });\n }\n};\n","import {\n AppointmentsFilters,\n BookingState,\n ConfirmedAppointment,\n ConfirmedReservation,\n Filters,\n SaveForLaterFavorite,\n UnconfirmedReservation\n} from \"core/domain/booking/BookingState\";\nimport { BookingStep } from \"core/domain/booking/Enums\";\nimport { Practice } from \"core/domain/booking/Practice\";\nimport { BookingStorageService } from \"core/services/booking/BookingStorageService\";\nimport { guid } from \"core/types\";\nimport { DateTime } from \"luxon\";\nimport {\n action,\n computed,\n makeObservable,\n observable,\n reaction,\n runInAction,\n toJS\n} from \"mobx\";\nimport { ProviderOnlineStatusCodes } from \"modules/bhb/pages/select-appointment-slot/types\";\nimport { RouteMap } from \"modules/bhb/RouteMap\";\nimport { NavigateOptions, To } from \"react-router-dom\";\nimport { ReCaptchaInstance } from \"recaptcha-v3\";\n\nimport { AppointmentTypeDto, ProviderDto } from \"../services/booking\";\nimport { StorageKey } from \"./Storage\";\n\nexport class BookingStore implements BookingState {\n private _suspendSaveToLocalStorage = false;\n\n private _practice?: Practice;\n private _isUserProfileComplete?: boolean;\n\n private _step: BookingStep = BookingStep.SelectPatientType;\n private _isNewPatient?: boolean;\n private _filters: Filters = {};\n private _appointmentFilters: AppointmentsFilters = {};\n private _reservation?: ConfirmedReservation;\n private _unconfirmedReservation?: UnconfirmedReservation;\n private _isAppointmentForUser?: boolean;\n private _dependantId?: string;\n private _appointment?: ConfirmedAppointment;\n private _rescheduleAppointmentId?: string;\n private _patientNotes?: string;\n\n private _availabilityFromDate: DateTime = DateTime.now().startOf(\"day\");\n\n private _reCaptchaInstance?: ReCaptchaInstance;\n private _reCaptchaToken: string | null = null;\n\n private _providerDetailsId: string | undefined;\n\n private _appointmentTypes?: AppointmentTypeDto[];\n private _providers?: ProviderDto[];\n private _saveForLaterFavorite?: SaveForLaterFavorite;\n private _hasSeenPracticeNotice: boolean = false;\n\n public constructor() {\n makeObservable<\n BookingStore,\n | \"_practice\"\n | \"_isUserProfileComplete\"\n | \"_step\"\n | \"_isNewPatient\"\n | \"_filters\"\n | \"_reservation\"\n | \"_unconfirmedReservation\"\n | \"_isAppointmentForUser\"\n | \"_dependantId\"\n | \"_appointment\"\n | \"_rescheduleAppointmentId\"\n | \"_patientNotes\"\n | \"_availabilityFromDate\"\n | \"_reCaptchaInstance\"\n | \"_reCaptchaToken\"\n | \"nextStep\"\n | \"previousStep\"\n | \"_providerDetailsId\"\n | \"_appointmentTypes\"\n | \"_providers\"\n | \"_saveForLaterFavorite\"\n | \"postLogoutRedirectUri\"\n | \"_appointmentFilters\"\n | \"_hasSeenPracticeNotice\"\n >(this, {\n _practice: observable,\n _isUserProfileComplete: observable,\n\n _step: observable,\n _isNewPatient: observable,\n _filters: observable,\n _appointmentFilters: observable,\n _reservation: observable,\n _unconfirmedReservation: observable,\n _isAppointmentForUser: observable,\n _dependantId: observable,\n _appointment: observable,\n _rescheduleAppointmentId: observable,\n _patientNotes: observable,\n\n _availabilityFromDate: observable,\n _reCaptchaInstance: observable,\n _reCaptchaToken: observable,\n\n // See: https://stackoverflow.com/a/68067250/127497\n availabilityFromDate: computed,\n reCaptchaInstance: computed,\n reCaptchaToken: computed,\n canSelectAppointmentType: computed,\n isUserProfileComplete: computed,\n\n practiceId: computed,\n practice: computed,\n previousStep: computed,\n nextStep: computed,\n\n postLogoutRedirectUri: computed,\n\n updateBookingState: action.bound,\n tryRestoreCurrentBooking: action.bound,\n resetWizardState: action.bound,\n\n _providerDetailsId: observable,\n _appointmentTypes: observable,\n _providers: observable,\n _saveForLaterFavorite: observable,\n _hasSeenPracticeNotice: observable\n });\n\n reaction(\n () => ({\n step: this.step,\n practiceId: this.practiceId,\n isNewPatient: this.isNewPatient,\n filters: toJS(this.filters),\n appointmentFilters: toJS(this.appointmentFilters),\n reservation: this.reservation,\n patientNotes: this.patientNotes,\n isAppointmentForUser: this.isAppointmentForUser,\n dependantId: this.dependantId,\n appointment: this.appointment,\n unconfirmedReservation: this.unconfirmedReservation,\n rescheduleAppointmentId: this.rescheduleAppointmentId,\n saveForLaterFavorite: this.saveForLaterFavorite\n }),\n state => {\n if (this._suspendSaveToLocalStorage) {\n this._suspendSaveToLocalStorage = false;\n } else {\n BookingStorageService.storeState(state);\n }\n }\n );\n }\n\n public get practiceId(): guid | undefined {\n if (this._practice?.id) return this._practice?.id;\n\n const bookingStorage = localStorage.getItem(StorageKey.BHB_WIZARD_MODEL);\n if (bookingStorage) {\n return JSON.parse(bookingStorage).practiceId;\n }\n return undefined;\n }\n\n public get practice(): Practice {\n return this._practice!;\n }\n\n public get isUserProfileComplete(): boolean | undefined {\n return this._isUserProfileComplete;\n }\n\n public set isUserProfileComplete(next: boolean | undefined) {\n this._isUserProfileComplete = next;\n }\n\n public get step() {\n return this._step;\n }\n\n public get isNewPatient() {\n return this._isNewPatient;\n }\n\n public get hasSeenPracticeNotice() {\n return this._hasSeenPracticeNotice;\n }\n\n public set hasSeenPracticeNotice(value: boolean) {\n this._hasSeenPracticeNotice = value;\n }\n\n public get filters() {\n return this._filters;\n }\n\n public get appointmentFilters() {\n return this._appointmentFilters;\n }\n\n public get unconfirmedReservation() {\n return this._unconfirmedReservation;\n }\n\n public get reservation() {\n return this._reservation;\n }\n\n public get isAppointmentForUser() {\n return this._isAppointmentForUser;\n }\n\n public get dependantId() {\n return this._dependantId;\n }\n\n public get patientNotes() {\n return this._patientNotes;\n }\n\n public get appointment() {\n return this._appointment;\n }\n\n public get rescheduleAppointmentId() {\n return this._rescheduleAppointmentId;\n }\n\n public get availabilityFromDate() {\n return this._availabilityFromDate;\n }\n\n public set availabilityFromDate(next: DateTime) {\n this._availabilityFromDate = next;\n }\n\n public get reCaptchaInstance() {\n return this._reCaptchaInstance;\n }\n\n public set reCaptchaInstance(next: ReCaptchaInstance | undefined) {\n this._reCaptchaInstance = next;\n }\n\n public get reCaptchaToken() {\n return this._reCaptchaToken;\n }\n\n public set reCaptchaToken(next: string | null) {\n this._reCaptchaToken = next;\n }\n\n public get providerDetailsId() {\n return this._providerDetailsId;\n }\n\n public get saveForLaterFavorite() {\n return this._saveForLaterFavorite;\n }\n\n public set saveForLaterFavorite(\n saveForLaterFavorite: SaveForLaterFavorite | undefined\n ) {\n runInAction(() => {\n this._saveForLaterFavorite = saveForLaterFavorite;\n });\n }\n\n public set providerDetailsId(id: string | undefined) {\n runInAction(() => {\n this._providerDetailsId = id;\n });\n }\n\n public get canSelectAppointmentType() {\n return (\n this.isNewPatient === false ||\n !this.practice?.bookingSettings?.allowNewPatients\n );\n }\n\n public get appointmentTypes() {\n return this._appointmentTypes ?? [];\n }\n\n public get providers() {\n return this._providers ?? [];\n }\n\n private get hasAppointmentTypeInformation() {\n const appointmentType = this.appointmentTypes.find(\n at => at.id === this.filters.appointmentTypeId\n );\n return appointmentType?.appointmentInformationEnabled ?? false;\n }\n\n public updateBookingState(delta: Partial) {\n if (!delta) return;\n\n Object.keys(delta).forEach(key => {\n if (this[key] !== delta[key]) {\n this[`_${key}`] = delta[key];\n }\n });\n }\n\n public updateFilterState = (delta: Partial) => {\n runInAction(() => {\n if (!delta) return;\n\n Object.keys(delta).forEach(key => {\n if (this._filters[key] !== delta[key]) {\n this._filters[key] = delta[key];\n }\n });\n });\n };\n\n public updateAppointmentsFilterState = (\n delta: Partial\n ) => {\n runInAction(() => {\n if (!delta) return;\n\n Object.keys(delta).forEach(key => {\n if (this._appointmentFilters[key] !== delta[key]) {\n this._appointmentFilters[key] = delta[key];\n }\n });\n });\n };\n\n public resetFilterState = () => {\n runInAction(() => {\n this._filters = {\n appointmentTypeId: this.filters.appointmentTypeId,\n appointmentTypeCategoryId: this.filters.appointmentTypeCategoryId\n };\n });\n };\n\n public resetAppointmentsFilterState = () => {\n runInAction(() => {\n this._appointmentFilters = {};\n });\n };\n\n public tryRestoreCurrentBooking(\n practice: Practice,\n appointmentTypes?: AppointmentTypeDto[],\n providers?: ProviderDto[]\n ): boolean {\n this._practice = practice;\n this._appointmentTypes = appointmentTypes;\n this._providers = providers;\n\n const restored = BookingStorageService.restoreState(practice.id);\n if (!restored) return true;\n\n this._suspendSaveToLocalStorage = true;\n this.updateBookingState(restored);\n return true;\n }\n\n public resetWizardState() {\n this._isNewPatient = undefined;\n this._filters = {};\n this._reservation = undefined;\n this._unconfirmedReservation = undefined;\n this._isAppointmentForUser = undefined;\n this._dependantId = undefined;\n }\n\n public get postLogoutRedirectUri() {\n return this.practiceId\n ? RouteMap.getBookingStepPath(this.step, this.practiceId, true)\n : \"/\";\n }\n\n public isPatientNotesEnabled = (appointmentTypeId: string) => {\n return (\n this.appointmentTypes.find(x => x.id === appointmentTypeId)\n ?.allowPatientNotes === true\n );\n };\n\n /**\n * Get the logical \"current\" step based on what information has been filled out in the booking wizard.\n */\n public calculateLogicalStep(requestedStep: BookingStep): BookingStep {\n const {\n practice,\n isNewPatient,\n isAppointmentForUser,\n dependantId,\n reservation,\n appointment\n } = this;\n\n // Check for Practice Outage\n if (practice.bookingSettings.practiceOutage) {\n return BookingStep.PracticeOutage;\n }\n\n // immediately check if only booking are enabled and practice has at least one assign appointment type\n // Ensure not all providers are set to Call Clinic\n if (\n !practice?.bookingSettings.isEnabled ||\n !this.appointmentTypes?.length ||\n this.appointmentTypes?.every(at => at.callClinicEnabled) ||\n !this.providers?.length ||\n this.providers.every(\n x => x.providerOnlineStatus === ProviderOnlineStatusCodes.call\n )\n )\n return BookingStep.NotAcceptingBookings;\n\n if (\n requestedStep === BookingStep.SelectAppointmentSlot &&\n this.rescheduleAppointmentId\n ) {\n return BookingStep.SelectAppointmentSlot;\n }\n\n if (requestedStep === BookingStep.NotAcceptingNewPatients) {\n return BookingStep.NotAcceptingNewPatients;\n }\n\n if (\n requestedStep === BookingStep.NotAcceptingBookings &&\n practice.bookingSettings.isEnabled\n ) {\n return BookingStep.NotAcceptingBookings;\n }\n\n const hasPatient = !!(isAppointmentForUser || dependantId);\n\n if (\n requestedStep > BookingStep.SelectPatientType &&\n isNewPatient === false && // Using strict equality as this will be undefined on the BookingSuccess page after it calls resetWizardState\n this.appointmentTypes.filter(x => x.isAvailableExistingPatients === true)\n .length === 0\n ) {\n return BookingStep.NotAcceptingBookings;\n }\n\n if (\n requestedStep > BookingStep.SelectPatientType &&\n isNewPatient &&\n this.appointmentTypes.filter(x => x.isAvailableNewPatients === true)\n .length === 0\n ) {\n return BookingStep.NotAcceptingNewPatients;\n }\n\n if (this._isUserProfileComplete) {\n if (requestedStep === BookingStep.BookingSuccess && appointment)\n return BookingStep.BookingSuccess;\n if (requestedStep >= BookingStep.ConfirmBooking && hasPatient)\n return BookingStep.ConfirmBooking;\n if (requestedStep === BookingStep.AddDependant && !!reservation)\n return BookingStep.AddDependant;\n if (\n requestedStep === BookingStep.AddPatientNotes &&\n !!reservation &&\n this.isPatientNotesEnabled(reservation.appointmentTypeId)\n )\n return BookingStep.AddPatientNotes;\n if (requestedStep >= BookingStep.SelectPatient && !!reservation)\n return BookingStep.SelectPatient;\n }\n\n if (requestedStep >= BookingStep.CompleteProfile) {\n if (this._isUserProfileComplete) return BookingStep.SelectPatient;\n if (this._isUserProfileComplete === false)\n return BookingStep.CompleteProfile;\n\n // The user is not logged in, continue to select patient to prompt for login\n return BookingStep.SelectPatient;\n }\n\n if (requestedStep >= BookingStep.SelectPatient && !!reservation) {\n // User has logged in but not completed their profile\n return this._isUserProfileComplete !== false\n ? BookingStep.SelectPatient\n : BookingStep.CompleteProfile;\n }\n\n if (requestedStep === BookingStep.SelectAppointmentType) {\n return BookingStep.SelectAppointmentType;\n }\n\n if (requestedStep === BookingStep.AppointmentTypeInformation) {\n return BookingStep.AppointmentTypeInformation;\n }\n\n if (requestedStep === BookingStep.SelectAppointmentSlot) {\n return BookingStep.SelectAppointmentSlot;\n }\n\n return BookingStep.SelectPatientType;\n }\n\n private get previousStep(): BookingStep {\n // Don't let them go back after confirming. In theory this will never be called because we don't show a\n // \"back\" button on this page.\n if (this._step === BookingStep.ConfirmBooking)\n return this.isPatientNotesEnabled(this.reservation!.appointmentTypeId)\n ? BookingStep.AddPatientNotes\n : BookingStep.SelectPatient;\n if (this._step === BookingStep.AddPatientNotes)\n return BookingStep.SelectPatient;\n if (this._step === BookingStep.AddDependant)\n return BookingStep.SelectPatient;\n if (this._step === BookingStep.SelectPatient)\n return BookingStep.SelectAppointmentSlot;\n if (this._step === BookingStep.AppointmentTypeInformation)\n return BookingStep.SelectAppointmentType;\n if (this._step === BookingStep.SelectAppointmentSlot) {\n return this.hasAppointmentTypeInformation\n ? BookingStep.AppointmentTypeInformation\n : BookingStep.SelectAppointmentType;\n }\n\n return BookingStep.SelectPatientType;\n }\n\n private get nextStep(): BookingStep {\n if (this._isUserProfileComplete) {\n if (this._step === BookingStep.ConfirmBooking)\n return BookingStep.BookingSuccess;\n if (\n this._step === BookingStep.AddDependant &&\n this.reservation &&\n this.dependantId\n )\n return this.isPatientNotesEnabled(this.reservation.appointmentTypeId)\n ? BookingStep.AddPatientNotes\n : BookingStep.ConfirmBooking;\n\n if (this._step === BookingStep.AddPatientNotes && this.reservation) {\n return BookingStep.ConfirmBooking;\n }\n if (this._step === BookingStep.SelectPatient && this.reservation) {\n // Next screen could be confirm booking or add patient notes\n const nextScreen = this.isPatientNotesEnabled(\n this.reservation!.appointmentTypeId\n )\n ? BookingStep.AddPatientNotes\n : BookingStep.ConfirmBooking;\n\n return this.isAppointmentForUser || this.dependantId\n ? nextScreen\n : BookingStep.AddDependant;\n }\n\n if (\n this._step === BookingStep.SelectAppointmentSlot &&\n this.reservation?.id\n ) {\n return this._isUserProfileComplete\n ? BookingStep.SelectPatient\n : BookingStep.CompleteProfile;\n }\n }\n\n if (this._step === BookingStep.CompleteProfile) {\n return this.calculateLogicalStep(BookingStep.ConfirmBooking);\n }\n\n if (\n this._step >= BookingStep.SelectAppointmentSlot &&\n !this._isUserProfileComplete\n )\n return BookingStep.CompleteProfile;\n\n if (this._step === BookingStep.SelectAppointmentType) {\n return this.hasAppointmentTypeInformation\n ? BookingStep.AppointmentTypeInformation\n : BookingStep.SelectAppointmentSlot;\n }\n\n if (this._step === BookingStep.AppointmentTypeInformation) {\n return BookingStep.SelectAppointmentSlot;\n }\n\n if (this._step === BookingStep.SelectPatientType) {\n return BookingStep.SelectAppointmentType;\n }\n\n return BookingStep.SelectPatientType;\n }\n\n public getNavigationArgs = (\n step: BookingStep,\n forceReplace = false\n ): [To, NavigateOptions] => {\n if (!this.practiceId) throw Error(\"locationId is required.\");\n\n const replace = forceReplace || BookingStore.shouldReplaceHistory(step);\n\n const args = [\n RouteMap.getBookingStepPath(step, this.practiceId, true),\n { replace }\n ];\n\n return args as [To, NavigateOptions];\n };\n\n public getPreviousStepNavigationArgs = () =>\n this.getNavigationArgs(this.previousStep);\n public getNextStepNavigationArgs = () =>\n this.getNavigationArgs(this.nextStep);\n\n private static shouldReplaceHistory(step: BookingStep) {\n // When the user goes submits the \"Add someone new\" form, we need to remove this page from the browser stack.\n // That way, if they click the browser back button, they'll be returned to the \"Who is this appointment for\" page\n // where their new dependant will now be on the list.\n return step === BookingStep.AddDependant;\n }\n}\n","import { action, computed, makeObservable, observable } from \"mobx\";\n\nconst DEFAULT_NOTIFICATION_TIMEOUT_MILLIS = 6000;\n\nexport type NotificationType = \"info\" | \"warning\" | \"success\" | \"error\";\n\nexport interface Notification {\n id: number;\n type: NotificationType;\n title: string | null;\n message: string;\n count: number;\n expiresAtMillis: number | null;\n}\n\ntype MessageOrError = string | Error | unknown | null | undefined;\nexport type NotificationFactory = (\n title: string,\n details?: MessageOrError,\n timeoutMillis?: number | null\n) => number;\n\nexport class NotificationStore {\n private static _id = 0;\n private notifications: Notification[] = [];\n\n public constructor() {\n // We have to pass 'notifications' as an argument here because TypeScript.\n // See point 8 at: https://mobx.js.org/observable-state.html#limitations\n makeObservable(this, {\n notifications: observable,\n notifyInfo: action,\n notifySuccess: action,\n notifyWarning: action,\n notifyError: action,\n dismiss: action,\n current: computed\n });\n }\n\n public notifyInfo: NotificationFactory = (\n titleOrMessage,\n details,\n timeoutMillis\n ) => this.add(\"info\", titleOrMessage, { details, timeoutMillis });\n public notifySuccess: NotificationFactory = (\n titleOrMessage,\n details,\n timeoutMillis\n ) => this.add(\"success\", titleOrMessage, { details, timeoutMillis });\n public notifyWarning: NotificationFactory = (\n titleOrMessage,\n details,\n timeoutMillis\n ) => this.add(\"warning\", titleOrMessage, { details, timeoutMillis });\n public notifyError: NotificationFactory = (\n titleOrMessage,\n details,\n timeoutMillis\n ) => this.add(\"error\", titleOrMessage, { details, timeoutMillis });\n\n private add = (\n type: NotificationType,\n\n titleOrMessage: string,\n options: {\n details: MessageOrError;\n timeoutMillis: number | null | undefined;\n }\n ): number => {\n const { details, timeoutMillis = null } = options;\n const expiresAtMillis =\n timeoutMillis !== Infinity\n ? new Date().valueOf() +\n (timeoutMillis || DEFAULT_NOTIFICATION_TIMEOUT_MILLIS)\n : null;\n\n const message = this.extractMessage(details);\n const existing = this.notifications.find(\n n =>\n n.type === type && n.title === titleOrMessage && n.message === message\n );\n\n if (existing) {\n existing.count++;\n existing.expiresAtMillis = expiresAtMillis;\n\n return existing.id;\n }\n\n // If we don't have both a title and a message, then we omit the title due to the way that notifications\n // get formatted.\n const hasTitleAndMessage = !!(titleOrMessage && message);\n\n const notification: Notification = {\n id: ++NotificationStore._id,\n type,\n title: hasTitleAndMessage ? titleOrMessage : null,\n message: message || titleOrMessage,\n count: 1,\n expiresAtMillis\n };\n\n this.notifications.push(notification);\n return notification.id;\n };\n\n private extractMessage = (details: MessageOrError): string | null => {\n if (details == null) return null;\n if (typeof details === \"string\") return details;\n if (details instanceof Error) return details.message;\n\n return (details as Object).toString() || null;\n };\n\n public dismiss = (notification: number | Notification) => {\n this.notifications = this.notifications.filter(\n n => n !== notification && n.id !== notification\n );\n };\n\n public dismissAll = action(() => {\n if (this.count > 0) {\n this.notifications = [];\n }\n });\n\n public get count() {\n return this.notifications.length;\n }\n\n public get current() {\n const now = new Date().valueOf();\n\n // Dismiss any notifications that have already expired. This is to cater for notifications that are raised while\n // the browser tab is not in focus. The `Snackbar` component (which is responsible for displaying notifications)\n // won't show these until the browser tab comes back in focus which means we could have a lot of notifications\n // that really aren't relevant anymore.\n for (const notification of this.notifications) {\n if (!notification.expiresAtMillis || notification.expiresAtMillis > now) {\n return notification;\n }\n\n this.dismiss(notification);\n }\n\n return null;\n }\n}\n","import { Settings } from \"luxon\";\n\nconst deepMerge = (...objects: Partial[]) => {\n return objects.reduce((src, dest) => {\n if (!dest) return src;\n\n Object.keys(src).forEach(key => {\n const destValue = dest[key];\n const srcValue = src[key];\n\n dest[key] =\n typeof srcValue === \"object\"\n ? deepMerge(srcValue, destValue)\n : destValue ?? srcValue;\n });\n\n return dest;\n });\n};\n\n/**\n * Default configuration values extracted from .env files. undefined values will be overwritten by whatever gets loaded from\n * the /public/config.json file. See ConfigLoader for details.\n */\nconst envConfig = {\n msal: {\n clientId: import.meta.env.VITE_MSAL_CLIENT_ID || undefined,\n authority: import.meta.env.VITE_MSAL_AUTHORITY || undefined\n },\n\n locale: \"en-AU\",\n dateFormatPattern: \"dd/mm/yyyy\",\n gaMeasurementId: import.meta.env.VITE_GA_MEASUREMENT_ID || undefined,\n appInsightsInstrumentationKey: import.meta.env.VITE_APP_INSIGHTS || undefined,\n hotjarSiteId: import.meta.env.VITE_HOTJAR_SITEID || undefined,\n\n bhacApiUrl: import.meta.env.VITE_BHAC_API_URL || undefined,\n bhbApiUrl: import.meta.env.VITE_BHB_API_URL || undefined,\n bhbUrl: import.meta.env.VITE_BHB_URL || undefined,\n bhwUrl: import.meta.env.VITE_BHW_URL || undefined,\n isLocal: import.meta.env.VITE_IS_LOCAL || undefined,\n\n query: {\n staleTimeMillis: import.meta.env.VITE_QUERY_STALE_TIME_MILLIS\n ? parseInt(import.meta.env.VITE_QUERY_STALE_TIME_MILLIS, 10)\n : undefined\n }\n} as Partial;\n\nexport const config = deepMerge(\n {},\n window.appConfig,\n envConfig\n) as RuntimeConfig;\n\n// eslint-disable-next-line no-console\nconsole.log(`Setting locale for date/times to: ${config.locale}`);\nSettings.defaultLocale = config.locale;\n","import { ProviderDto, ProviderWithTimeSlotsDto } from \"core/services/booking\";\nimport { DateTime } from \"luxon\";\n\nconst providerOnlineStatusOrder: { [key: string]: number } = {\n YES: 0,\n CALL: 1,\n NO: 2\n};\n\nconst providerSortOnProviderOnlineStatus = (a: ProviderDto, b: ProviderDto) => {\n if (!a.providerOnlineStatus || !b.providerOnlineStatus) return -1;\n return (\n providerOnlineStatusOrder[a.providerOnlineStatus] -\n providerOnlineStatusOrder[b.providerOnlineStatus]\n );\n};\n\n// Sort providers for the TimeSlotSelector\nexport function sortProvidersForTimeSlotSelector(\n providers: Array\n) {\n if (providers === undefined || null) {\n return null;\n }\n\n return (\n providers\n // Sort by first name then last name\n .sort((a, b) => (a.firstName ?? \"\").localeCompare(b.firstName ?? \"\"))\n .sort((a, b) => (a.lastName ?? \"\").localeCompare(b.lastName ?? \"\"))\n\n // Sort by earliest timeslot\n .sort((a, b) =>\n a.timeSlots?.length > 0 &&\n b.timeSlots?.length > 0 &&\n a.timeSlots[0].startTime.valueOf() -\n b.timeSlots[0].startTime.valueOf() <\n 0\n ? -1\n : 0\n )\n\n // Sort favourites to the top\n .sort((a, b) => Number(b.isFavorite) - Number(a.isFavorite))\n\n // Sort online bookable providers before call clinic providers\n .sort(\n (a, b) =>\n providerOnlineStatusOrder[a.providerOnlineStatus!] -\n providerOnlineStatusOrder[b.providerOnlineStatus!]\n )\n );\n}\n\n// Sort providers for the Practice Team page\nexport function sortProvidersForPracticeTeam(providers: Array) {\n if (providers === undefined || null) {\n return null;\n }\n\n return Array.from(providers)\n .sort((a, b) => (a.firstName ?? \"\").localeCompare(b.firstName ?? \"\"))\n .sort((a, b) => (a.lastName ?? \"\").localeCompare(b.lastName ?? \"\"))\n .sort((a, b) => providerSortOnProviderOnlineStatus(a, b));\n}\n\nexport function getCountry() {\n const timezones = {\n \"Australia/ACT\": \"AU\",\n \"Australia/Adelaide\": \"AU\",\n \"Australia/Brisbane\": \"AU\",\n \"Australia/Broken_Hill\": \"AU\",\n \"Australia/Canberra\": \"AU\",\n \"Australia/Currie\": \"AU\",\n \"Australia/Darwin\": \"AU\",\n \"Australia/Eucla\": \"AU\",\n \"Australia/Hobart\": \"AU\",\n \"Australia/LHI\": \"AU\",\n \"Australia/Lindeman\": \"AU\",\n \"Australia/Lord_Howe\": \"AU\",\n \"Australia/Melbourne\": \"AU\",\n \"Australia/NSW\": \"AU\",\n \"Australia/North\": \"AU\",\n \"Australia/Perth\": \"AU\",\n \"Australia/Queensland\": \"AU\",\n \"Australia/South\": \"AU\",\n \"Australia/Sydney\": \"AU\",\n \"Australia/Tasmania\": \"AU\",\n \"Australia/Victoria\": \"AU\",\n \"Australia/West\": \"AU\",\n \"Australia/Yancowinna\": \"AU\",\n NZ: \"NZ\",\n \"NZ-CHAT\": \"NZ\",\n \"Pacific/Chatham\": \"NZ\",\n \"Pacific/Auckland\": \"NZ\"\n };\n\n const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n\n if (timezone === \"\" || !timezone) {\n return null;\n }\n\n return timezones[timezone];\n}\nexport function getSortedDates(dates: string[]) {\n return dates\n .map(as => DateTime.fromISO(as))\n .sort((left, right) => left.valueOf() - right.valueOf());\n}\n\nexport function isObjectEmpty(obj: object) {\n return !Object.values(obj).some(o => !!o);\n}\n","import { getCountry } from \"pages/common/utils\";\nimport * as yup from \"yup\";\n\nimport { Country } from \"./booking\";\n\nexport interface Address {\n street1: string;\n city: string;\n postCode: string;\n suburb?: string;\n addressState?: string;\n country: string;\n}\n\n/**\n * Creates a basic schema for validating an address. Schemas are immutable so consumers can modify the returned\n * schema without changing the original.\n *\n * @see https://github.com/jquense/yup/blob/master/docs/extending.md#extending-schema\n */\nexport const createAddressValidationSchema = (isRequired: boolean) =>\n yup.object().shape({\n street1: yup\n .string()\n .max(40, \"The street address must be 40 characters or less\")\n .matches(\n /^[\\w/\\-,'.\\s]+$/,\n \"The street address contains invalid characters\"\n )\n .test({\n name: \"address-street-required\",\n test: value => !!value || !isRequired,\n message: \"Please enter a valid street address\"\n }),\n city: yup.string().when(\"country\", {\n is: Country.NewZealand,\n then: yup\n .string()\n .max(40, \"The suburb name must be 40 characters or less\")\n .matches(\n /^[a-z'\\-\\s]+$/i,\n \"The suburb name contains invalid characters\"\n )\n .test({\n name: \"address-city-required\",\n test: value => !!value || !isRequired,\n message: \"Please enter a valid city\"\n })\n }),\n addressState: yup.string().test({\n name: \"address-empty-country-state-required\",\n test: (value, con) => {\n const country = con.parent[\"country\"];\n if (!country || country === Country.Australia)\n return !!value || !isRequired;\n return true;\n },\n message: \"Please select a valid state\"\n }),\n suburb: yup.string().test({\n name: \"address-suburb-required\",\n test: (value, con) => {\n const country = con.parent[\"country\"];\n if (!country || country === Country.Australia) {\n return !!value || !isRequired;\n }\n return true;\n },\n message: \"Please enter a valid suburb\"\n }),\n postCode: yup\n .string()\n .matches(/\\d{4}/, \"The postcode must be four digits\")\n .typeError(\"Please specify a valid postcode\")\n .test({\n name: \"address-postcode-required\",\n test: value => !!value || !isRequired,\n message: \"Please enter a valid postcode\"\n }),\n country: yup.string().test({\n name: \"address-country-required\",\n test: value => !!value || !isRequired,\n message: \"Please select a country\"\n })\n });\n\n/**\n * An address match found by google Autocomplete\n */\nexport interface AddressMatch {\n id: string;\n description: string;\n}\n\nexport class AddressRestrictions {\n // Minimum number of characters entered before an autocomplete search is done\n public static MinFullTextSearchLength: number = 3;\n\n // Minimum number of characters entered before manual address entry displays even when there are matches\n public static MinSearchLengthForManualEntry: number = 15;\n}\n\nexport const LocalCountry = getCountry() || Country.NewZealand;\nexport const getDefaultAddress = (country?: string): Address => {\n return {\n street1: \"\",\n city: \"\",\n postCode: \"\",\n suburb: \"\",\n addressState: \"\",\n country: country ?? LocalCountry\n };\n};\n","import { DateTime } from \"luxon\";\nimport { BaseSchema } from \"yup\";\nimport { date as defaults } from \"yup/lib/locale\";\nimport Reference from \"yup/lib/Reference\";\n\n/**\n * Defines a schema that can be used for validating Luxon DateTime instances.\n *\n * @remarks\n * Unfortunately the default `DateSchema` from yup does not allow inheritance with types that aren't\n * a `Date` - so we have to effectively re-implement the `DateSchema`.\n *\n * See: https://github.com/jquense/yup/blob/master/src/date.ts\n */\nclass DateTimeSchema extends BaseSchema {\n static create() {\n return new DateTimeSchema();\n }\n\n constructor() {\n super();\n\n this.withMutation(() => {\n this.transform(function (value, originalValue) {\n if (this.isType(value)) return value;\n\n try {\n const dateTime = DateTime.fromObject(originalValue);\n if (dateTime.isValid) return dateTime;\n } catch (err) {}\n\n // *shrug* This doesn't look like anything we can convert to a DateTime\n return undefined;\n });\n });\n }\n\n private prepareParam(\n ref: DateTime | Reference | unknown,\n name: string\n ): DateTime | Reference {\n if (Reference.isRef(ref)) {\n return ref as Reference;\n }\n\n if (typeof ref === \"function\") {\n const exprValue = ref() as DateTime;\n if (this._typeCheck(exprValue)) {\n return exprValue;\n }\n }\n\n const castValue = this.cast(ref);\n if (this._typeCheck(castValue)) {\n return castValue;\n }\n\n throw new TypeError(\n `'${name}' must be a DateTime, or an expression which produces a DateTime (received ${ref} which is of type '${typeof ref}')`\n );\n }\n\n min(min: unknown | Reference, message = defaults.min) {\n const limit = this.prepareParam(min, \"min\");\n\n return this.test({\n message,\n name: \"min\",\n exclusive: true,\n params: { min },\n test(value) {\n return value == null || value >= this.resolve(limit);\n }\n });\n }\n\n max(max: unknown | Reference, message = defaults.max) {\n const limit = this.prepareParam(max, \"max\");\n\n return this.test({\n message,\n name: \"max\",\n exclusive: true,\n params: { max },\n test(value) {\n const resolvedMax = this.resolve(limit);\n return value == null || value <= resolvedMax;\n }\n });\n }\n\n // @ts-ignore\n protected override _typeCheck(value): value is DateTime {\n return value instanceof DateTime && (value as DateTime).isValid;\n }\n}\n\nexport const yupExtensions = {\n dateTime: () => new DateTimeSchema()\n};\n","import { strings } from \"core/strings\";\nimport { guid } from \"core/types/Guid\";\nimport { yupExtensions } from \"core/validation/yupExtensions\";\nimport { DateTime } from \"luxon\";\nimport * as yup from \"yup\";\n\nimport { Address } from \"./Address\";\n\nexport interface Person {\n id: guid | null;\n firstName: string;\n lastName: string;\n dateOfBirth?: DateTime;\n mobile: string;\n address: Address;\n}\n\nexport const PersonMeta = {\n getDisplayName: (person: Person) =>\n `${person.firstName || \"\"} ${person.lastName || \"\"}`.trim(),\n getInitials: (person: Person) =>\n `${person.firstName[0] || \"\"}${person.lastName[0] || \"\"}`.trim(),\n\n // The oldest person ever to have lived was 122\n getMinDateOfBirth: () => DateTime.now().minus({ years: 125 }).startOf(\"day\"),\n\n // Users must be at least 14 years old.\n getMaxDateOfBirthForUserProfile: () =>\n DateTime.now().minus({ years: 14 }).startOf(\"day\"),\n\n sort: (left: Person, right: Person) => {\n const lastNameResult = strings.compare(left.lastName, right.lastName);\n return lastNameResult === 0\n ? strings.compare(left.firstName, right.firstName)\n : lastNameResult;\n }\n};\n\n/**\n * Validation schema for the required fields for a person - firstName, lastName and dateOfBirth.\n */\n\nexport const PersonValidationSchema = yup.object().shape({\n firstName: yup\n .string()\n .required(\"Please enter a first name\")\n .min(1, \"The first name you have entered is too short\"),\n lastName: yup\n .string()\n .required(\"Please enter a last name\")\n .min(1, \"The last name you have entered is too short\")\n});\n\nexport const DateOfBirthSchema = yupExtensions\n .dateTime()\n .nullable()\n .min(\n PersonMeta.getMinDateOfBirth(),\n () =>\n \"The date of birth is before the minimum allowed value \" +\n `(${PersonMeta.getMinDateOfBirth().toLocaleString(DateTime.DATE_SHORT)})`\n );\n\n/**\n * Validation schema for an Australian or NZ mobile phone number\n */\nexport const MobileNumberValidationSchema = yup\n .string()\n .nullable()\n .required(\"Please enter a mobile number\")\n .matches(\n /^0[245]\\d{8}$/,\n \"Your mobile must start with '02', '04' or '05' and be 10 digits long\"\n );\n","import { createAddressValidationSchema } from \"core/domain/Address\";\nimport { DateTime } from \"luxon\";\nimport * as yup from \"yup\";\n\nimport {\n DateOfBirthSchema,\n MobileNumberValidationSchema,\n Person,\n PersonValidationSchema\n} from \"./Person\";\n\nexport interface Dependant extends Omit {\n useAccountInfo: boolean;\n dateOfBirth: DateTime;\n}\n\nexport const DependantValidationSchema = PersonValidationSchema.shape({\n useAccountInfo: yup.boolean(),\n mobile: yup.string().when(\"useAccountInfo\", {\n is: false,\n then: MobileNumberValidationSchema\n }),\n\n dateOfBirth: DateOfBirthSchema.required(\n \"Please enter a valid date of birth\"\n ).max(\n () => DateTime.now().startOf(\"day\"),\n \"The date of birth cannot be after today.\"\n ),\n\n address: yup.object().when(\"useAccountInfo\", {\n is: false,\n then: createAddressValidationSchema(true)\n })\n});\n","export enum Environment {\n Dev = \"deva\",\n Uat = \"uata\",\n Prod = \"proda\"\n}\n","import { config } from \"config\";\nimport { Environment } from \"core/domain\";\nimport { action, computed, makeObservable, observable } from \"mobx\";\n\nimport { useAccount } from \"@azure/msal-react\";\n\nexport class UserPreferencesStore {\n // Features are visible by default in the dev environment\n private _areToggledFeaturesVisible = config.environment === Environment.Dev;\n private _isProductionEnvironment = config.environment === Environment.Prod;\n\n public constructor() {\n makeObservable<\n UserPreferencesStore,\n \"_areToggledFeaturesVisible\" | \"_isProductionEnvironment\"\n >(this, {\n _isProductionEnvironment: observable,\n _areToggledFeaturesVisible: observable,\n toggleFeatureToggle: action,\n areToggledFeaturesVisible: computed\n });\n }\n\n public toggleFeatureToggle = () => {\n // For production the features aren't able to be toggled\n if (!this._isProductionEnvironment) {\n this._areToggledFeaturesVisible = !this._areToggledFeaturesVisible;\n }\n };\n\n public get areToggledFeaturesVisible(): boolean {\n if (!this._isProductionEnvironment) return this._areToggledFeaturesVisible;\n\n // Ensure that toggled features aren't displayed in production\n return false;\n }\n\n public get isProductionEnvironment(): boolean {\n return this._isProductionEnvironment;\n }\n\n isUserLoggedIn = () => {\n const account = useAccount();\n return !!account;\n };\n}\n","import { BookingStore } from \"core/store/BookingStore\";\nimport { NotificationStore } from \"core/store/NotificationStore\";\nimport { UserPreferencesStore } from \"core/store/UserPreferencesStore\";\nimport { createContext, PropsWithChildren, useContext } from \"react\";\n\nconst notificationStore = new NotificationStore();\nconst userPreferencesStore = new UserPreferencesStore();\nconst bookingStore = new BookingStore();\n\nexport const RootStore = {\n notificationStore,\n userPreferencesStore,\n bookingStore\n};\n\nconst StoreContext = createContext(RootStore);\n\nexport const StoreContextProvider = ({\n children\n}: PropsWithChildren) => {\n return (\n {children}\n );\n};\n\nexport const useRootStore = () => useContext(StoreContext);\nexport const useBookingStore = () => useRootStore().bookingStore;\nexport const useNotificationStore = () => useRootStore().notificationStore;\nexport const useUserPreferencesStore = () =>\n useRootStore().userPreferencesStore;\n","import { Literal } from \"components/Literal\";\nimport { Notification } from \"core/store/NotificationStore\";\nimport { useNotificationStore } from \"core/store/RootStore\";\nimport { observer } from \"mobx-react-lite\";\nimport { SyntheticEvent, useCallback } from \"react\";\n\nimport { Alert, Slide, SlideProps, Snackbar } from \"@mui/material\";\n\ninterface NotificationCountProps {\n count: number;\n hide?: boolean;\n}\n\nconst NotificationTally = ({ count, hide }: NotificationCountProps) => {\n if (hide || count <= 1) return null;\n return ({count});\n};\n\nconst SlideRight = (props: SlideProps) => (\n \n);\n\ninterface ToastProps {\n notification: Notification;\n onDismiss: (notification: Notification) => void;\n}\n\nconst Toast = observer(({ notification, onDismiss }: ToastProps) => {\n const autoHideDuration = notification.expiresAtMillis\n ? notification.expiresAtMillis - new Date().valueOf()\n : null;\n\n const handleDismiss = () => onDismiss(notification);\n const handleClose = (event: SyntheticEvent, reason: string) =>\n reason !== \"clickaway\" && handleDismiss();\n\n const hasTitle = !!notification.title;\n const messageVariant = hasTitle ? \"body1\" : \"title2\";\n\n return (\n \n \n <>\n {hasTitle && (\n \n {notification.title}{\" \"}\n \n \n )}\n \n {notification.message}\n \n \n \n \n \n );\n});\n\nconst Notifications = observer(() => {\n const store = useNotificationStore();\n const handleDismiss = useCallback(\n (notification: Notification) => store.dismiss(notification.id),\n [store]\n );\n\n // Only show one notification at a time (in line with Material UI guidelines - https://material.io/components/snackbars#usage)\n const notification = store.current;\n if (!notification) return null;\n\n return (\n <>\n \n \n );\n});\n\n// eslint-disable-next-line import/no-default-export\nexport default Notifications;\n","import { useEffect } from \"react\";\nimport { useLocation } from \"react-router-dom\";\n\nimport { useAppInsightsContext } from \"@microsoft/applicationinsights-react-js\";\n\nimport { config } from \"../../../config\";\nimport { Environment } from \"../../domain\";\n\nexport const useAppInsightsPageViewTracker = () => {\n const appInsightPlugin = useAppInsightsContext();\n const location = useLocation();\n useEffect(() => {\n if (config.environment !== Environment.Dev) {\n appInsightPlugin.trackPageView &&\n appInsightPlugin.trackPageView({ name: document.title });\n }\n }, [location, appInsightPlugin.trackPageView, appInsightPlugin]);\n};\n","export type Route = {\n path: string;\n title: string;\n fullPath: string;\n subRoutes: Record;\n};\n\nexport type RouteTitle = { fullPath: string; title: string };\n\nexport type RouteKey =\n | \"profile\"\n | \"appointments\"\n | \"family\"\n | \"dashboard\"\n | \"bha\"\n | \"setup\"\n | \"booking\";\n\nexport const DEFAULT_PAGE_TITLE = \"Best Health\";\n","import { Route, RouteTitle } from \"./routes.types\";\n\n/**\n * Returns RouteTitle object from Route\n * @param route\n */\nconst getRouteTitle = (route: Route): RouteTitle => {\n return { fullPath: route.fullPath, title: route.title };\n};\n\n/**\n * Returns routes nesting number\n * @param route\n */\nconst getRouteNesting = (route: RouteTitle) => {\n return route.fullPath\n .split(\"/\")\n .reduce((acc: string[], item: string) => [...acc, ...item.split(\"-\")], [])\n .filter(i => i.length > 0).length;\n};\n\n/**\n * Recursively return Array from Array\n * @param routes\n */\nexport const getRoutesTitles = (routes: Route[]): RouteTitle[] => {\n return routes\n .reduce((acc: RouteTitle[], item: Route) => {\n const hasSubRoutes = !!Object.values(item.subRoutes).length;\n if (hasSubRoutes) {\n return [\n ...acc,\n ...getRoutesTitles(Object.values(item.subRoutes)),\n getRouteTitle(item)\n ];\n }\n return [...acc, getRouteTitle(item)];\n }, [] as RouteTitle[])\n .sort((a, b) => {\n // sort routes by route nesting\n const aNesting = getRouteNesting(a);\n const bNesting = getRouteNesting(b);\n return bNesting - aNesting;\n });\n};\n","import { useEffect } from \"react\";\nimport { useLocation } from \"react-router-dom\";\n\nimport { routes } from \"../routes/routes\";\nimport { DEFAULT_PAGE_TITLE } from \"../routes/routes.types\";\nimport { getRoutesTitles } from \"../routes/routes.utils\";\n\nconst routesTitles = getRoutesTitles(Object.values(routes));\nexport const usePageTitle = (overridePageTitle?: string) => {\n const location = useLocation();\n useEffect(() => {\n const match = routesTitles.find(rt =>\n location.pathname.includes(rt.fullPath)\n );\n document.title = match?.title ?? overridePageTitle ?? DEFAULT_PAGE_TITLE;\n }, [overridePageTitle, location]);\n};\n","import { Spinner } from \"components/Spinner\";\nimport Notifications from \"layout/Notifications\";\nimport { ComponentType, ExoticComponent, lazy, Suspense } from \"react\";\nimport { Route, Routes } from \"react-router-dom\";\n\nimport { Authenticated } from \"@bps/msal\";\n\nimport { useAppInsightsPageViewTracker } from \"./core/analytics/app-insights/app-insights.hooks\";\nimport { usePageTitle } from \"./core/hooks/usePageTitle\";\nimport { routes } from \"./core/routes/routes\";\n\ninterface BhwModuleRoute {\n path: string;\n allowAnonymous?: boolean;\n resolveComponent: () => Promise<{ default: ComponentType }>;\n}\n\nconst Layout = lazy(() => import(\"layout/Layout\"));\n\nconst modules: BhwModuleRoute[] = [\n {\n path: \"/profile/incomplete\",\n resolveComponent: () => import(\"modules/booking\")\n },\n {\n path: routes.bha.path,\n resolveComponent: () => import(\"modules/bha\")\n },\n {\n path: routes.setup.path,\n allowAnonymous: true,\n resolveComponent: () => import(\"modules/setup\")\n },\n {\n path: routes.booking.path,\n allowAnonymous: true,\n resolveComponent: () => import(\"modules/bhb\")\n }\n];\n\ninterface BhwModuleProps {\n allowAnonymous?: boolean;\n component: ExoticComponent;\n}\n\nconst AppModule = ({\n allowAnonymous,\n component: Component\n}: BhwModuleProps) => {\n if (allowAnonymous) {\n return ;\n }\n\n return (\n (\n {spinnerMessage}\n )}\n >\n \n \n );\n};\n\nexport const AppRoutes = () => {\n usePageTitle();\n useAppInsightsPageViewTracker();\n return (\n <>\n Loading, please wait...\n }\n >\n \n {modules.map(({ path, allowAnonymous, resolveComponent }) => (\n \n }\n />\n ))}\n\n } />\n \n \n\n \n \n );\n};\n","import { Literal } from \"components/Literal\";\n\nimport Alert from \"@mui/material/Alert\";\n\ninterface Props {\n title?: string;\n error?: Error | unknown;\n}\n\nconst hasMessage = (error?: unknown): error is { message: string } => {\n if (!error) return false;\n if ((error as { message: unknown }) === undefined) return false;\n\n const errorWithMessage = error as { message: unknown };\n return typeof errorWithMessage.message === \"string\";\n};\n\nexport const ErrorBox = ({ title, error }: Props) => {\n const errorMessage = hasMessage(error)\n ? error.message\n : (error as object)?.toString() ?? null;\n\n const text = title ?? errorMessage ?? \"An error has occurred.\";\n const details = (title && errorMessage) ?? null;\n\n return (\n \n {text}\n {details && {details}}\n \n );\n};\n","import { FunctionComponent } from \"react\";\nimport { FallbackProps } from \"react-error-boundary\";\n\nimport { ErrorBox } from \"./ErrorBox\";\n\nexport const ErrorBoundaryFallback: FunctionComponent = ({\n error,\n children\n}) => {\n if (error) {\n return ;\n }\n return <>{children};\n};\n","import { config } from \"config\";\nimport { PropsWithChildren } from \"react\";\nimport { QueryClient, QueryClientProvider } from \"react-query\";\n\nexport const queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n refetchOnWindowFocus: false,\n retry: false,\n staleTime: config.query.staleTimeMillis\n }\n }\n});\n\nconst ReactQueryProvider = ({ children }: PropsWithChildren) => {\n return (\n {children}\n );\n};\n\n// eslint-disable-next-line import/no-default-export\nexport default ReactQueryProvider;\n","import { useUserAgent } from \"@oieduardorabelo/use-user-agent\";\n\nexport const useIsMobileView = () => {\n const details = useUserAgent();\n\n // determines if this is a mobile embedded webview i.e. a webview from IOS or Android from BHA\n return (\n (details &&\n details.browser &&\n (details.browser.name === \"WebKit\" ||\n details.browser.name === \"Chrome WebView\")) ||\n (details && details.device && details.device.type === \"mobile\")\n );\n};\n","/**\n * This hook dynamically set main-height css custom property.\n * --main-height is used to calculate correct viewport for mobile-devices.\n */\nimport { useEffect } from \"react\";\n\nimport { useIsMobileView } from \"./useIsMobileView\";\n\n// we multiply the viewport height by 1% to get a value for a vh unit\nconst VHRATIO = 0.01;\n\nexport const useWindowHeightResize = () => {\n const isMobile = useIsMobileView();\n const documentHeight = () => {\n if (!isMobile) return;\n\n const doc = document.documentElement;\n\n // set custom-property to use in index.css\n doc.style.setProperty(\"--main-height\", `${window.innerHeight * VHRATIO}px`);\n };\n\n useEffect(() => {\n documentHeight();\n return () => {\n window.removeEventListener(\"resize\", documentHeight);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isMobile]);\n};\n","import { ReactPlugin as AppInsightsReactPlugin } from \"@microsoft/applicationinsights-react-js\";\nimport {\n ApplicationInsights,\n IConfiguration\n} from \"@microsoft/applicationinsights-web\";\n\nimport { config } from \"../../../config\";\n\nexport const initAppInsights = () => {\n const appInsightConfig: IConfiguration = {\n instrumentationKey: config.appInsightsInstrumentationKey\n };\n\n const appInsightPlugin = new AppInsightsReactPlugin();\n\n const appInsights = new ApplicationInsights({\n config: {\n enableAutoRouteTracking: false,\n disableFetchTracking: false,\n extensions: [appInsightPlugin as any],\n ...appInsightConfig\n }\n });\n appInsights.loadAppInsights();\n return appInsightPlugin;\n};\n","import { DependencyList, useEffect } from \"react\";\nimport ReactGA from \"react-ga4\";\n\nimport { config } from \"../../../config\";\nimport { AnalyticsEffectCallback } from \"./google-analytics.types\";\n\nexport const useAnalyticsInit = () => {\n const { gaMeasurementId } = config;\n\n useEffect(() => {\n if (!gaMeasurementId || ReactGA.isInitialized) return;\n ReactGA.initialize(gaMeasurementId, {\n gaOptions: {\n // See: https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#create\n }\n });\n }, [gaMeasurementId]);\n};\n\nexport const useAnalyticsEffect = (\n effect?: AnalyticsEffectCallback,\n deps: DependencyList = []\n) => {\n const { gaMeasurementId } = config;\n\n if (!ReactGA.isInitialized && gaMeasurementId) {\n ReactGA.initialize(gaMeasurementId, {\n gaOptions: {\n // See: https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#create\n }\n });\n }\n\n useEffect(() => {\n if (!gaMeasurementId) return;\n effect && effect(ReactGA);\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [gaMeasurementId, ...deps]);\n\n return ReactGA;\n};\n","import Hotjar from \"@hotjar/browser\";\n\nimport { config } from \"../../../config\";\n\nconst HOTJAR_VERSION = 6;\n\nexport const initHotJar = () => {\n if (!window.appConfig.isLocal) {\n const siteId = Number(config.hotjarSiteId);\n Hotjar.init(siteId, HOTJAR_VERSION);\n }\n};\n","import { AppRoutes } from \"AppRoutes\";\n\nimport { ErrorBoundaryFallback } from \"components/ErrorBoundaryFallback\";\nimport { theme } from \"components/theme\";\nimport { config } from \"config\";\nimport { Environment } from \"core/domain\";\nimport ReactQueryProvider from \"core/services/ReactQueryProvider\";\nimport { StoreContextProvider } from \"core/store/RootStore\";\nimport { ErrorBoundary } from \"react-error-boundary\";\nimport { ReactQueryDevtools } from \"react-query/devtools\";\nimport { BrowserRouter as Router } from \"react-router-dom\";\n\nimport { MsalProvider } from \"@azure/msal-react\";\nimport { configure, getAppInstance } from \"@bps/msal\";\nimport { AppInsightsContext } from \"@microsoft/applicationinsights-react-js\";\nimport AdapterLuxon from \"@mui/lab/AdapterLuxon\";\nimport LocalizationProvider from \"@mui/lab/LocalizationProvider\";\nimport CssBaseline from \"@mui/material/CssBaseline\";\nimport ThemeProvider from \"@mui/material/styles/ThemeProvider\";\n\nimport { useWindowHeightResize } from \"./components/hooks/useWindowHeightResize\";\nimport { initAppInsights } from \"./core/analytics/app-insights/app-insights.utils\";\nimport { useAnalyticsInit } from \"./core/analytics/google-analytics/google-analytics.hooks\";\nimport { initHotJar } from \"./core/analytics/hotjar/hot-jar.utils\";\n\nconfigure(config.msal);\nconst appInsightPlugin = initAppInsights();\ninitHotJar();\n\nfunction App() {\n useWindowHeightResize();\n useAnalyticsInit();\n\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n\n {config.environment === Environment.Dev &&\n process.env.NODE_ENV === \"development\" && (\n \n )}\n \n \n \n \n \n );\n}\n\n// eslint-disable-next-line import/no-default-export\nexport default App;\n","import { ReportHandler } from \"web-vitals\";\n\nconst reportWebVitals = (onPerfEntry?: ReportHandler) => {\n if (onPerfEntry && onPerfEntry instanceof Function) {\n import(\"web-vitals\").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n getCLS(onPerfEntry);\n getFID(onPerfEntry);\n getFCP(onPerfEntry);\n getLCP(onPerfEntry);\n getTTFB(onPerfEntry);\n });\n }\n};\n\n// eslint-disable-next-line import/no-default-export\nexport default reportWebVitals;\n","import { StrictMode } from \"react\";\nimport ReactDOM from \"react-dom\";\n\nimport App from \"./App\";\nimport \"./index.css\";\nimport \"./normalize.css\";\nimport reportWebVitals from \"./reportWebVitals\";\n\nReactDOM.render(\n \n \n ,\n document.getElementById(\"root\")\n);\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals();\n"],"file":"assets/index-DdAfURns.js"}