{"version":3,"file":"chunk.e2428584e8f43ff5c6f9.js","mappings":"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","sources":["webpack:///../.env.js","webpack:///./scripts/components/AuthenticationContext.tsx","webpack:///./scripts/components/CatastrophicErrorScreen.tsx","webpack:///./scripts/components/SnackbarProvider.tsx","webpack:///./scripts/components/StandardProvider.tsx","webpack:///./scripts/components/UserProfileProvider/index.tsx","webpack:///./scripts/components/UserProfileProvider/queries.ts","webpack:///./scripts/constants/env.ts","webpack:///./scripts/http/AuthApiProvider.tsx","webpack:///./scripts/http/exceptions.ts","webpack:///./scripts/http/httpClient.ts","webpack:///./scripts/http/httpClients-no-auth.ts","webpack:///./scripts/http/requests-no-auth.ts","webpack:///../../../packages/pg-ui/src/base/Material/memberTheme.ts","webpack:///./scripts/shared/Material/theme.tsx","webpack:///./scripts/shared/utils/atomic-updates.ts","webpack:///./scripts/utils/ServiceBrand.ts","webpack:///./scripts/utils/logger.ts","webpack:///../../../packages/domain/src/data/users/GlobalUser.ts","webpack:///../../../packages/domain/src/data/users/UserAuth.ts","webpack:///../../../packages/domain/src/data/users/birthdate.ts","webpack:///../../../packages/http-clients-js/src/ApiClient.ts","webpack:///../../../packages/http-clients-js/src/exceptions.ts","webpack:///../../../packages/http-clients-js/src/types.ts","webpack:///../../../packages/next-utils/src/useIsNextJs.ts","webpack:///../../../packages/pg-ui/src/base/Material/components/Button.tsx","webpack:///../../../packages/pg-ui/src/base/Material/theme.tsx","webpack:///../../../packages/pg-ui/src/base/Material/utils/colors.ts","webpack:///../../../packages/pg-ui/src/base/Material/utils/sx-helpers.tsx","webpack:///../../../packages/pg-ui/src/components/CatastrophicErrorBoundary.tsx","webpack:///../../../packages/pg-ui/src/components/Deferred.tsx","webpack:///../../../packages/pg-ui/src/components/FetchFailureMessage.tsx","webpack:///../../../packages/pg-ui/src/components/ResponsiveTypography.tsx","webpack:///../../../packages/pg-ui/src/utils/MobileApp.ts","webpack:///../../../packages/pg-ui/src/utils/environment.ts","webpack:///../../../packages/pg-util/src/DateUtils.ts","webpack:///../../../packages/pg-util/src/DomUtils.ts","webpack:///../../../packages/pg-util/src/FunctionUtils.ts","webpack:///../../../packages/pg-util/src/ObjectUtils.ts","webpack:///../../../packages/pg-util/src/TypescriptUtils.ts"],"sourcesContent":["module.exports = {\n PG_CORE_URL: 'https://api-core.patientrewardshub.com',\n PG_COMM_URL: 'https://api-communications.patientrewardshub.com',\n MY_DOT_URL: {\n PRH: 'https://my.patientrewardshub.com',\n HUBBUX: 'https://my.hubbux.com',\n CULTURELLO: 'https://my.culturello.com',\n },\n SANITY_URL: 'https://practicegenius.sanity.studio',\n FILES_URL: 'https://files.patientrewardshub.com',\n BASE_URL: '',\n ASSETS_URL: 'https://sites-assets.patientrewardshub.com/assets',\n\n GOOGLE_MAPS_KEY: 'AIzaSyBjzPiPMIBYLCJ9_bcT_4l2wkUjDcJrdFY',\n PUSHER_KEY: '6a1480dff8c57c27367c',\n PUSHER_CLUSTER: 'us3',\n\n GOOGLE_RECAPTCHA_SITE_KEY: {\n PRH: '6LercfkcAAAAAAei2x1f6i9j0hstVrvm7zKUaGb1',\n HUBBUX: '6LcuGPYcAAAAAM5MFgZEboRxQ4mgXxJtf5GaXvwc',\n CULTURELLO: '6LcFWdoqAAAAAKwc5be95Zc6vLAer4rxZchtYtGW',\n },\n\n GIPHY_API_KEY: '1tHZt4wUmq2DsaSgkYXXzTa5TCpAZ3fu',\n};\n\n","import React from 'react';\n\ntype AuthenticationContextValue = {\n isAuthenticated: boolean;\n};\nconst AuthenticationContext = React.createContext({\n isAuthenticated: false,\n});\n\nexport const useIsAuthenticated = () => {\n return React.useContext(AuthenticationContext).isAuthenticated;\n};\n\n/** This informs the provided tree that the session should be considered authenticated\n * This only works because we only use this provider in contexts we know to be authenticated.\n * When we have more React on the unauthorized side, we'll need to touch this up and allow this to\n * directly infer authentication status from the application context.\n */\nexport const AuthenticationContextProvider: React.FCC = ({children}) => {\n return (\n \n {children}\n \n );\n};\n","import {styled} from '@mui/material';\nimport {Typography} from '@practicegenius/pg-ui/src/components/ResponsiveTypography';\nimport React from 'react';\n\nconst Wrapper = styled('div')(({theme}) => ({\n margin: theme.spacing(5, 2, 2, 2),\n display: 'flex',\n alignItems: 'center',\n flexDirection: 'column',\n}));\n\nexport const CatastrophicErrorScreen: React.FC = () => (\n \n \n Oops! There is a problem.\n \n \n);\n","import {SnackbarProvider as NotistackSnackbarProvider} from 'notistack';\nimport React from 'react';\n\nconst SNACKBAR_ROOT_ID = 'snackbar-root';\n\nexport const SnackbarProvider: React.FCC = ({children}) => {\n const [rootEl, setRootEl] = React.useState();\n\n React.useEffect(() => {\n // Look for previously-created snackbar root\n let root = document.querySelector(`#${SNACKBAR_ROOT_ID}`);\n\n if (!root) {\n root = document.createElement('div');\n root.setAttribute('id', SNACKBAR_ROOT_ID);\n document.body.append(root);\n }\n\n setRootEl(root);\n }, []);\n\n return (\n \n {children}\n \n );\n};\n","import React from 'react';\nimport {QueryClient, QueryClientProvider} from '@tanstack/react-query';\nimport {ReactQueryDevtools} from '@tanstack/react-query-devtools';\nimport {Breakpoint} from '@mui/material';\nimport {CatastrophicErrorBoundary} from '@practicegenius/pg-ui/src/components/CatastrophicErrorBoundary';\nimport {AuthApiProvider} from '../http/AuthApiProvider';\nimport {UserProfileProvider} from './UserProfileProvider';\nimport logger from '../utils/logger';\nimport {\n AuthenticatedThemeProvider,\n UnauthenticatedThemeProvider,\n} from '../shared/Material/theme';\nimport {CatastrophicErrorScreen} from './CatastrophicErrorScreen';\nimport {AuthenticationContextProvider} from './AuthenticationContext';\nimport {SnackbarProvider} from './SnackbarProvider';\n\n/**\n * The sharedQueryClient is used between all instances of StandardProvider components\n * so the single ReactQueryDevtools instance can display all queries on the page between\n * different mount points\n */\nconst sharedQueryClient = new QueryClient();\n\nlet renderedDevTools = false;\n/** Who needs multiple instances of query devtools? Ew */\nconst SingletonReactQueryDevtools = React.memo(() => {\n if (renderedDevTools) return null;\n\n renderedDevTools = true;\n\n return ;\n});\n\ntype StandardProviderProps = {\n breakpoint?: Breakpoint;\n /** Provide a name for the app using this provider. This is currently only used in the Catastrophic Error boundary.\n * Default: 'sites-dot'\n */\n appName?: string;\n showErrorMessage?: boolean;\n};\n\nconst StandardCatastrophicErrorBoundary: React.FCC<{\n appName?: string;\n showError: boolean;\n}> = ({children, appName = 'sites-dot', showError}) => (\n : null}\n >\n {children}\n \n);\n\nconst SharedProvider: React.FCC> = ({\n children,\n appName,\n showErrorMessage = false,\n}) => (\n \n \n \n \n {children}\n \n \n \n);\n\n/** Provides Thene, Snackbars, Standard Error Boundary, and React Query Client */\nexport const UnauthenticatedStandardProvider: React.FCC =\n ({breakpoint, appName, children, showErrorMessage = false}) => {\n return (\n \n \n {children}\n \n \n );\n };\n\nexport const withUnauthenticatedStandardProvider =\n (providerProps: StandardProviderProps = {}) =>\n (Inner: React.ComponentType) =>\n (props: any) =>\n (\n \n \n \n );\n\n/** Provides everything from the unauth provider + authenticated API and logged-in user data */\nexport const StandardProvider: React.FCC = ({\n breakpoint,\n appName,\n children,\n showErrorMessage = false,\n}) => (\n // We only use this provider in authenticated contexts, so we can unconditionally provide this context\n \n \n \n \n \n {children}\n \n \n \n \n \n);\n\nexport const withStandardProvider =\n (providerProps: StandardProviderProps = {}) =>\n (Inner: React.ComponentType) =>\n (props: any) =>\n (\n \n \n \n );\n","import React from 'react';\nimport {styled, CircularProgress} from '@mui/material';\nimport {Deferred} from '@practicegenius/pg-ui/src/components/Deferred';\nimport {FetchFailureMessage} from '@practicegenius/pg-ui/src/components/FetchFailureMessage';\nimport {useUserProfileQuery} from './queries';\nimport {UserProfile} from './data';\n\nconst Context = React.createContext(undefined);\n\nconst SpinnerRoot = styled('div')({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n});\n\nexport const useUserProfile = () => {\n const ctx = React.useContext(Context);\n\n if (!ctx) {\n throw new Error(\n 'useUserProfile must be used within a UserProfileProvider!'\n );\n }\n\n return ctx;\n};\n\nexport const UserProfileProvider: React.FCC<{\n /** Show error message if fetch fails */\n showErrorMessage?: boolean;\n /** Redirect to this URL if fetch fails */\n redirectOnError?: string;\n}> = ({children, redirectOnError, showErrorMessage = false}) => {\n const profileQuery = useUserProfileQuery();\n\n switch (profileQuery.status) {\n case 'success':\n return (\n \n {children}\n \n );\n case 'error':\n if (redirectOnError) {\n window.location.href = redirectOnError;\n\n return null;\n }\n\n return showErrorMessage ? (\n \n ) : null;\n default:\n return (\n \n \n \n \n \n );\n }\n};\n","import * as R from 'ramda';\nimport {useMutation, useQuery, useQueryClient} from '@tanstack/react-query';\nimport {useSnackbar} from 'notistack';\nimport {ReceiveUserProfileSitesToAppMessage} from '@practicegenius/domain/src/sites-mobile-app/messages';\nimport {fetchGlobalUserProfile} from '@practicegenius/domain/src/data/users/GlobalUser';\nimport {postMessageToMobileApp} from '@practicegenius/pg-ui/src/utils/MobileApp';\nimport {useApi, useGlobalUserApi} from '../../http/AuthApiProvider';\nimport {UserProfile} from './data';\nimport {atomicUpdate} from '../../shared/utils/atomic-updates';\n\nconst userProfileQueryKey = ['global_user_profile'];\n\nexport const useUserProfileQuery = () => {\n const globalUserCoreAuth = useGlobalUserApi();\n\n return useQuery({\n queryKey: userProfileQueryKey,\n queryFn: () =>\n fetchGlobalUserProfile(globalUserCoreAuth)\n /**\n * Perform side-effects for mobile app and legacy UI\n * These are done here (instead of queryOptions.onSuccess) to ensure they only run once per user profile fetch and not once per query instance.\n */\n .then(profile => {\n const practiceRecord = profile.practiceRecords[0];\n if (!practiceRecord) {\n return profile;\n }\n\n // Send user profile to mobile app every time it updates.\n postMessageToMobileApp({\n type: 'receive_user_profile',\n payload: {\n ...profile,\n // TODO this is a temporary fix to get the notification counts to the mobile app\n // This won't work in the long run because a global user can be associated to multiple practice users\n // It works today because we don't yet have any multi-practice users\n // The long-term fix is to either\n // - Update the logic here to reliably get the practice record for the _current_ practice user\n // - Update the mobile app to pull the notification counts from the practice user on its own.\n notificationCounts: practiceRecord.notificationCounts,\n // Send along the cookie so the mobile app can make requests on behalf of this user\n cookie: document.cookie,\n },\n } as ReceiveUserProfileSitesToAppMessage);\n\n // Update user points for legacy UI\n atomicUpdate(\n 'user_points',\n new Intl.NumberFormat().format(practiceRecord.points ?? 0)\n );\n return profile;\n }),\n staleTime: 3 * 60 * 1000, // 3 minutes\n });\n};\n\nexport const useInvalidateUserProfileQuery = () => {\n const queryClient = useQueryClient();\n\n return () =>\n queryClient.invalidateQueries({\n queryKey: userProfileQueryKey,\n });\n};\n\ntype PrivacyPreferenceKey =\n | 'hide_birthday_from_feed'\n | 'hide_anniversary_from_feed';\n\nexport type PrivacyPreferenceData = {\n key: PrivacyPreferenceKey;\n value: Boolean;\n};\n\nconst useUpdateUserProfileQueryData = () => {\n const queryClient = useQueryClient();\n return (updater: Parameters[1]) =>\n queryClient.setQueryData(userProfileQueryKey, updater);\n};\n\nexport const useUpdatePrivacyPreferences = () => {\n const {globalUserCoreAuth} = useApi();\n const queryClient = useQueryClient();\n const updateUserProfile = useUpdateUserProfileQueryData();\n const {enqueueSnackbar} = useSnackbar();\n\n return useMutation<\n unknown,\n unknown,\n PrivacyPreferenceData,\n {previousUserProfile: UserProfile}\n >({\n mutationFn: (preferenceData: PrivacyPreferenceData) =>\n globalUserCoreAuth._unsafe.post(\n `/global_users/hub_settings`,\n preferenceData\n ),\n onMutate: async ({key, value}) => {\n await queryClient.cancelQueries({queryKey: userProfileQueryKey});\n const previousUserProfile = queryClient.getQueryData(\n userProfileQueryKey\n ) as UserProfile;\n queryClient.setQueryData(\n userProfileQueryKey,\n R.assocPath(['hubSettings', key], value)\n );\n return {previousUserProfile};\n },\n onSuccess: (_, {key, value}) => {\n updateUserProfile(R.assocPath(['hubSettings', key], value));\n },\n onError: (_, __, context) => {\n if (context) {\n queryClient.setQueryData(\n userProfileQueryKey,\n context.previousUserProfile\n );\n }\n enqueueSnackbar('Error updating setting.', {\n autoHideDuration: 3000,\n variant: 'error',\n });\n },\n });\n};\n","import {isNotUndefined} from '@practicegenius/pg-util/src/TypescriptUtils';\nimport {isClient} from '@practicegenius/pg-ui/src/utils/environment';\nimport envJS from '../../../.env.js';\n\nconst {\n PG_CORE_URL,\n PG_COMM_URL,\n MY_DOT_URL,\n SANITY_URL,\n FILES_URL,\n ASSETS_URL,\n BASE_URL,\n GOOGLE_MAPS_KEY,\n GOOGLE_RECAPTCHA_SITE_KEY,\n PUSHER_KEY,\n PUSHER_CLUSTER,\n PUSHER_HOST,\n GIPHY_API_KEY,\n} = envJS;\n\nconst __DEV__ = process.env.NODE_ENV === 'development';\nconst __TEST__ = process.env.NODE_ENV === 'test';\nconst __PROD__ = process.env.NODE_ENV === 'production';\n\nexport {\n PG_CORE_URL,\n PG_COMM_URL,\n MY_DOT_URL,\n SANITY_URL,\n FILES_URL,\n ASSETS_URL,\n BASE_URL,\n GOOGLE_MAPS_KEY,\n GOOGLE_RECAPTCHA_SITE_KEY,\n PUSHER_KEY,\n PUSHER_CLUSTER,\n PUSHER_HOST,\n GIPHY_API_KEY,\n __DEV__,\n __TEST__,\n __PROD__,\n};\n\n/**\n * Detect the storybook context\n */\nexport const isStorybook: boolean =\n isClient &&\n isNotUndefined(\n // @ts-ignore this is set by storybook\n window.STORYBOOK_ENV\n );\n","import React from 'react';\nimport {InvariantError} from 'ts-invariant';\nimport {stringify} from 'qs';\nimport {useQuery} from '@tanstack/react-query';\nimport {\n UserAuth,\n tokenToAuth,\n decodeJwt,\n} from '@practicegenius/domain/src/data/users/UserAuth';\nimport {\n makeNoAuthApiClient,\n makeAuthApiClient,\n} from '@practicegenius/http-clients-js/src/ApiClient';\nimport {ApiClient} from '@practicegenius/http-clients-js/src/types';\nimport {useIsNextJs} from '@practicegenius/next-utils/src/useIsNextJs';\nimport {requestGlobalJwt, requestJwt} from './requests-no-auth';\nimport {PG_CORE_URL} from '../constants/env';\n\ntype ApiContextValue = {\n /** Core API authenticated as business user */\n coreAuth: ApiClient;\n /** Decoded version of the practice-user core jwt */\n decodedToken: UserAuth;\n /** Core API authenticated as global user */\n globalUserCoreAuth: ApiClient;\n};\n\n/** @deprecated not meant to be used outside of existing legacy scenarios */\n// eslint-disable-next-line import/no-mutable-exports\nexport let __HACKY_GLOBAL_USER_JWT = '';\n\nconst NextApiContext = React.createContext | null>(null);\n\ntype NextGlobalUserAuthApiContextValue = {\n globalUserCoreAuth: ApiClient;\n};\nconst NextGlobalUserAuthApiContext =\n React.createContext(null);\n\n/** HTTP Client for requests to sites-dot's backend (Kohana at the moment)\n * These requests are implicitly authenticated through cookies\n * so the client does not need extra setup\n */\nexport const sitesHttpClient = makeNoAuthApiClient({\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n 'X-Requested-With': 'xmlhttprequest',\n },\n transformRequest: [data => stringify(data)],\n});\n\n/** The actual useQuery that hydrates the API client context. Not intended to be used externally */\nconst useApiClients = () => {\n return useQuery({\n queryKey: ['apiContext'],\n queryFn: () =>\n Promise.all([requestJwt(), requestGlobalJwt()]).then(\n ([coreJwt, globalUserJwt]) => {\n __HACKY_GLOBAL_USER_JWT = globalUserJwt.token;\n return {\n coreAuth: makeAuthApiClient({\n baseURL: PG_CORE_URL,\n authToken: coreJwt.token,\n }),\n globalUserCoreAuth: makeAuthApiClient({\n baseURL: PG_CORE_URL,\n authToken: globalUserJwt.token,\n }),\n decodedToken:\n process.env.NODE_ENV === 'test' // The JWT in tests is not decodable\n ? {\n userId: 0,\n userType: 'admin' as const,\n practiceId: 0,\n timezone: '',\n }\n : tokenToAuth(decodeJwt(coreJwt.token)),\n };\n }\n ),\n // 3 minutes\n staleTime: 1000 * 60 * 3,\n });\n};\n\n/** Use only the global user api client */\nexport const useGlobalUserApi = () => {\n // This value will never change at runtime, so it should not trigger rules-of-hooks errors\n // by conditionally calling hooks below\n const isNextJs = useIsNextJs();\n\n if (isNextJs) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const nextGlobalUserApiCtx = React.useContext(NextGlobalUserAuthApiContext);\n if (!nextGlobalUserApiCtx) {\n throw new InvariantError(\n 'useGlobalUserApi must be used within a NextGlobalUserAuthApiProvider!'\n );\n }\n return nextGlobalUserApiCtx.globalUserCoreAuth;\n }\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const {data} = useApiClients();\n if (!data)\n throw new InvariantError(\n \"useGlobalUserApi must be called inside ApiProvider's context\"\n );\n\n return data.globalUserCoreAuth;\n};\n\n/** Use the collection of api clients needed to make authenticated requests to api-core */\nexport const useApi = (): ApiContextValue => {\n // This value will never change at runtime, so it should not trigger rules-of-hooks errors\n // by conditionally calling hooks below\n const isNextJs = useIsNextJs();\n\n if (isNextJs) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const globalUserCoreAuth = useGlobalUserApi();\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const nextApiCtx = React.useContext(NextApiContext);\n if (!nextApiCtx) {\n throw new InvariantError(\n 'useApi must be used within a ApiProvider or NextApiProvider!'\n );\n }\n return {\n globalUserCoreAuth,\n ...nextApiCtx,\n };\n }\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const {data} = useApiClients();\n if (!data)\n throw new InvariantError(\n \"useApi must be called inside ApiProvider's context\"\n );\n\n return data;\n};\n\nexport const AuthApiProvider: React.FCC = ({children}) => {\n const apiClientQuery = useApiClients();\n\n switch (apiClientQuery.status) {\n case 'error':\n // Just rendering children when the token request(s) fail\n // just defers the error down to the components, as the first time they try to use the\n // ApiClient, we'll get an error because the default client's token is invalid\n // TODO We need an error component here like we have in my-dot\n return <>{children};\n\n case 'success':\n return <>{children};\n\n // Not showing anything here gives this parity with the old http clients 😅\n default:\n return null;\n }\n};\n\nexport const NextAuthApiProvider: React.FCC<{\n practiceUserJwt: string;\n}> = ({practiceUserJwt, children}) => {\n return (\n \n {children}\n \n );\n};\n\nexport const NextGlobalUserAuthApiProvider: React.FCC<{\n globalUserCoreJwt: string;\n}> = ({children, globalUserCoreJwt}) => {\n __HACKY_GLOBAL_USER_JWT = globalUserCoreJwt;\n const globalUserCoreAuth = makeAuthApiClient({\n baseURL: PG_CORE_URL,\n authToken: globalUserCoreJwt,\n });\n\n return (\n \n {children}\n \n );\n};\n","import {\n AlreadyRegisteredHint,\n AlreadySocialRegisteredHint,\n} from '@practicegenius/register-account/src/data/types';\nimport {AxiosInstance} from 'axios';\n\nexport class UnauthenticatedError extends Error {\n name = 'UnauthenticatedError';\n response: Response;\n constructor(response: Response) {\n super(`Response failed as unauthenticated (${response.status})`);\n this.response = response;\n }\n}\n\nexport class NotFoundError extends Error {\n name = 'NotFoundError';\n response: Response;\n constructor(response: Response) {\n super();\n this.response = response;\n }\n}\n\nexport class ValidationError extends Error {\n name = 'ValidationError';\n errors: any;\n\n constructor(errors: any) {\n super();\n this.errors = errors;\n }\n}\n\nexport class AccountRegisteredError extends Error {\n name = 'AccountRegisteredError';\n message: string;\n // This eventually gets passed back to the login form as username.\n // It can be a card number, email address, or username\n hint: AlreadyRegisteredHint;\n\n constructor(message: string, hint: AlreadyRegisteredHint) {\n super();\n this.message = message;\n this.hint = hint;\n }\n}\n\nexport class SocialAccountRegisteredError extends Error {\n name = 'SocialAccountRegisteredError';\n message: string;\n // The backend responds with a list of platforms the user is registered with\n hint: AlreadySocialRegisteredHint;\n\n constructor(message: string, hint: AlreadySocialRegisteredHint) {\n super();\n this.message = message;\n this.hint = hint;\n }\n}\n\n/**\n * Produce a Promise catch handler that transforms and rethrows validation errors\n */\nexport function rethrowValidationErrors(\n transformErrors: (a: any) => any\n): (a: any) => void {\n return error => {\n if (error instanceof ValidationError) {\n throw new ValidationError(transformErrors(error.errors));\n }\n\n throw error;\n };\n}\n\nexport class InternalServerError extends Error {\n name = 'InternalServerError';\n response: Response;\n constructor(response: Response) {\n super();\n this.response = response;\n }\n}\n\nexport class BadResponseError extends Error {\n name = 'BadResponseError';\n response: Response;\n constructor(response: Response) {\n super();\n this.response = response;\n }\n}\n\nexport class ReauthenticationError extends Error {\n name = 'ReauthenticationError';\n payload: any;\n\n constructor(payload: any) {\n super();\n this.payload = payload;\n }\n}\n\nexport class TimeoutError extends Error {}\n\nexport class RateLimitError extends Error {\n response: Response;\n constructor(response: Response) {\n super();\n this.response = response;\n }\n}\n\nexport function isNetworkError(error: Error): boolean {\n return (\n error instanceof TimeoutError ||\n (error instanceof TypeError &&\n /network request failed/i.test(error.message))\n );\n}\n\nexport const handleHTTPErrors = (client: AxiosInstance) => {\n client.interceptors.response.use(undefined, err => {\n const {response, code} = err;\n if (code === 'ECONNABORTED') {\n throw new TimeoutError();\n }\n\n switch (response.status) {\n case 401:\n case 403:\n throw new UnauthenticatedError(response);\n case 404:\n throw new NotFoundError(response);\n case 408:\n throw new TimeoutError();\n case 422: {\n switch (response.data.code) {\n case 'account_registered':\n throw new AccountRegisteredError(\n response.data.message,\n response.data.hint\n );\n\n case 'social_registered':\n throw new SocialAccountRegisteredError(\n response.data.message,\n response.data.hint || {}\n );\n\n default:\n throw new ValidationError(response.data.errors);\n }\n }\n case 429:\n throw new RateLimitError(response);\n case 500:\n throw new InternalServerError(response);\n default:\n throw new BadResponseError(response);\n }\n });\n\n return client;\n};\n","import axios, {AxiosRequestConfig} from 'axios';\nimport {handleHTTPErrors} from './exceptions';\n\nconst REQUEST_TIMEOUT_LENGTH = 10000;\n\nexport function httpClient({baseURL, ...config}: AxiosRequestConfig) {\n const client = axios.create({\n baseURL,\n timeout: REQUEST_TIMEOUT_LENGTH,\n ...config,\n });\n\n return handleHTTPErrors(client);\n}\n","import {stringify} from 'qs';\nimport {httpClient} from './httpClient';\nimport {PG_CORE_URL, BASE_URL} from '../constants/env';\n\n/** @deprecated use coreApiClient */\nexport const pgCoreNoAuth = httpClient({\n baseURL: PG_CORE_URL,\n});\n\n/** @deprecated use sitesHttpClient */\nexport const sitesDot = httpClient({\n // Reminder: if baseURL is undefined then axios makes the requests from `window.origin`. This is exactly what we want for sites-dot\n baseURL: process.env.NODE_ENV === 'test' ? BASE_URL : undefined,\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n 'X-Requested-With': 'xmlhttprequest',\n },\n transformRequest: [data => stringify(data)],\n});\n","import {AxiosResponse} from 'axios';\nimport {JWT$Server} from '@practicegenius/http-clients-js/src/types';\nimport {pgCoreNoAuth, sitesDot} from './httpClients-no-auth';\n\nconst handleJwtError = (err: any) => {\n const response = err.response as AxiosResponse | undefined;\n if (response && [401, 403].includes(response.status))\n window.location.href = '/login';\n throw err;\n};\n\nexport function requestJwt() {\n return sitesDot\n .post('/api/token')\n .then(({data: token}) => token as JWT$Server)\n .catch(handleJwtError);\n}\n\nexport function requestGlobalJwt() {\n return sitesDot\n .post('/api/global_token')\n .then(({data: token}) => token as JWT$Server)\n .catch(handleJwtError);\n}\n\nexport function refreshJwt(refreshToken: string) {\n const payload = {\n refresh_token: refreshToken,\n };\n return pgCoreNoAuth\n .post('authentication/refresh', payload)\n .then(({data: token}) => token as JWT$Server);\n}\n\nexport function refreshSession() {\n return sitesDot.post('/api/session_refresh');\n}\n\nexport const registerDeviceNotificationToken = ({\n deviceType,\n token,\n previousTokens = [],\n}: {\n deviceType: string;\n token: string;\n previousTokens?: string[];\n}): Promise =>\n sitesDot.post('/api/user/appnotificationsetup', {\n token,\n type: deviceType,\n previous_tokens: previousTokens,\n });\n\nexport const unregisterDeviceNotificationToken = ({\n deviceType,\n token,\n}: {\n deviceType: string;\n token: string | null;\n}): Promise =>\n sitesDot.post('/api/user/appnotificationdestruction', {\n token,\n type: deviceType,\n });\n\nexport const markContentShared = ({\n shareCode,\n}: {\n shareCode: string;\n}): Promise => sitesDot.post(`/api/share/create`, {code: shareCode});\n","import {darken, lighten, ThemeOptions} from '@mui/material/styles';\n\nexport const FALLBACK_UNAUTH_COLOR = {\n primary: '#1F98D9',\n secondary: 'rgba(0,0,0,0.6)',\n};\n\nconst breakpoints = {\n unit: 'em',\n values: {\n xs: 0,\n sm: 30,\n md: 48,\n lg: 78,\n xl: 120,\n },\n};\n\nexport const baseMembersThemeOptions: ThemeOptions = {\n breakpoints,\n typography: {\n fontFamily: ['Source Sans Pro', 'sans-serif'].join(','),\n fontSize: 14,\n },\n palette: {\n primary: {\n main: '#34C5EE',\n contrastText: '#fff',\n },\n secondary: {\n main: '#DCDCDC',\n contrastText: '#fff',\n },\n error: {\n main: '#FF3638',\n },\n warning: {\n main: '#FACC0F',\n },\n action: {\n hoverOpacity: 0.08,\n focusOpacity: 0.24,\n },\n },\n components: {\n MuiFormControl: {\n defaultProps: {\n variant: 'outlined',\n margin: 'dense',\n fullWidth: true,\n size: 'small',\n },\n },\n MuiInputBase: {\n styleOverrides: {\n root: {\n '&:not(.Mui-disabled)': {\n color: 'text.primary',\n },\n '& fieldset': {\n borderRadius: `2px`,\n },\n '&.Mui-disabled fieldset': {\n opacity: 0.5,\n },\n },\n },\n },\n MuiTextField: {\n defaultProps: {\n variant: 'outlined',\n size: 'small',\n },\n },\n MuiFormLabel: {\n styleOverrides: {\n root: {\n textTransform: 'none',\n },\n },\n },\n MuiButton: {\n styleOverrides: {\n root: {\n borderRadius: '100px',\n },\n },\n },\n MuiIconButton: {\n styleOverrides: {\n root: {\n borderRadius: '100px',\n },\n },\n },\n MuiLink: {\n styleOverrides: {\n root: {\n textDecoration: 'none',\n },\n },\n },\n },\n};\n\nconst themePalette = {\n blue: '#006fa6',\n orange: '#d03e00',\n green: '#00790d',\n red: '#b80014',\n purple: '#af3290',\n grey: '#494949',\n};\n\n/**\n * @see apps/sites.patientrewardshub.com/application/assets/stylesheets/private/themes/template.colors.scss\n */\nconst themeColorMapping: Record = {\n 1: 'blue',\n 2: 'orange',\n 3: 'orange',\n 4: 'blue',\n 5: 'red',\n 6: 'green',\n 7: 'red',\n 8: 'red',\n 9: 'blue',\n 10: 'green',\n 11: 'purple',\n 12: 'green',\n 13: 'grey',\n 14: 'orange',\n};\n\nexport const getColorsForMemberThemeId = (themeId: number) => ({\n primary: themePalette[themeColorMapping[themeId]],\n secondary: FALLBACK_UNAUTH_COLOR.secondary,\n});\n\nexport const getExpandedPaletteForColor = (color: string) => ({\n main: color,\n dark: darken(color, 0.2),\n light: lighten(color, 0.2),\n});\n","import React from 'react';\nimport * as R from 'ramda';\nimport {\n // eslint-disable-next-line no-restricted-imports\n createTheme,\n Palette as MuiPalette,\n Breakpoint,\n Theme,\n ThemeOptions,\n} from '@mui/material';\nimport {\n ThemeProvider,\n defaultThemeOptions,\n defaultThemeOptionsAtBreakpoint,\n} from '@practicegenius/pg-ui/src/base/Material/theme';\nimport {\n DeepPartial,\n isUndefined,\n} from '@practicegenius/pg-util/src/TypescriptUtils';\nimport {Practice} from '@practicegenius/domain/src/data/practice';\nimport {\n baseMembersThemeOptions,\n FALLBACK_UNAUTH_COLOR,\n getColorsForMemberThemeId,\n getExpandedPaletteForColor,\n} from '@practicegenius/pg-ui/src/base/Material/memberTheme';\nimport {inMobileApp} from '@practicegenius/pg-ui/src/utils/MobileApp';\nimport {useUserProfile} from '../../components/UserProfileProvider';\nimport ServiceBrand from '../../utils/ServiceBrand';\n\nconst sitesDotThemeOptions: Theme = createTheme(baseMembersThemeOptions);\n\ntype ThemeCustomizationOptions = {\n atBreakpoint?: Breakpoint;\n /** User-selected theme id. Undefined for unauthenticated */\n themeId?: number;\n palette?: DeepPartial;\n};\n\n/**\n * While we've deprecated all our custom themes here in favor\n * of `pg-ui`, `sites.` has a special need to control its own\n * breakpoints (thanks a bunch Foundation). This little\n * helper will do all the heavy lifting for ya! 😄\n */\nexport const createSitesTheme = ({\n atBreakpoint,\n themeId,\n palette: paletteOverride = {},\n}: ThemeCustomizationOptions = {}): Theme => {\n const baseThemeOptions = isUndefined(atBreakpoint)\n ? defaultThemeOptions\n : defaultThemeOptionsAtBreakpoint(atBreakpoint);\n\n const memberThemeColors = (() => {\n if (!themeId) return {};\n const colors = getColorsForMemberThemeId(themeId);\n return {\n palette: {\n primary: getExpandedPaletteForColor(colors.primary),\n secondary: getExpandedPaletteForColor(colors.secondary),\n },\n };\n })();\n\n const sitesDotTheme = createTheme(\n R.reduce(\n R.mergeDeepRight,\n // @ts-ignore\n {},\n [\n R.evolve(\n {\n // We need to avoid using the 50-900 values from the pg-ui theme here, as they leak into hover states and will lead to weird UX\n palette: {\n primary: R.pick(['main']),\n secondary: R.pick(['main']),\n },\n },\n // @ts-expect-error\n R.omit(['overrides'], baseThemeOptions)\n ),\n sitesDotThemeOptions,\n // Override palette with member theme colors if defined\n memberThemeColors,\n ]\n ) as ThemeOptions\n );\n\n // I expect that one day we will align the mobile app and standard web experiences.\n // Until then, we need to show the old color so we don't clash with the legacy CSS.\n /** Get MUI theme colors for the unauthenticated app experience */\n const unauthThemeColors = (() => {\n const bodyEl = document.querySelector('body');\n\n const makeResult = (primaryColor: string, secondaryColor: string) => ({\n primary: getExpandedPaletteForColor(primaryColor),\n secondary: getExpandedPaletteForColor(secondaryColor),\n });\n\n if (!bodyEl)\n return makeResult(\n FALLBACK_UNAUTH_COLOR.primary,\n FALLBACK_UNAUTH_COLOR.secondary\n );\n\n // Get legacy theme colors by parsing the CSS variables\n let primaryColor = getComputedStyle(bodyEl)\n .getPropertyValue('--template-color-1')\n .trim();\n let secondaryColor = getComputedStyle(bodyEl)\n .getPropertyValue('--template-color-8')\n .trim();\n if (primaryColor === '') primaryColor = FALLBACK_UNAUTH_COLOR.primary;\n if (secondaryColor === '') secondaryColor = FALLBACK_UNAUTH_COLOR.secondary;\n\n // Special case: override theme colors in mobile app to make them consistent across all practices\n if (inMobileApp)\n primaryColor = ServiceBrand.select({\n prh: '#00A2B8',\n hubbux: '#E02020',\n culturello: '#0ebbc5',\n });\n\n return makeResult(primaryColor, secondaryColor);\n })();\n\n // theme palette primary and secondary for unauthenticated views\n const unauthThemeOverrides = {\n primary: {\n ...unauthThemeColors.primary,\n contrastText: '#fff',\n },\n secondary: {\n ...unauthThemeColors.secondary,\n contrastText: '#fff',\n },\n action: {\n hoverOpacity: 0.08,\n focusOpacity: 0.24,\n },\n };\n\n const authThemeOverrides = {};\n\n const overrides = R.mergeDeepRight(\n sitesDotTheme.palette ?? {},\n themeId !== undefined ? authThemeOverrides : unauthThemeOverrides\n );\n\n return {\n ...sitesDotTheme,\n ...{\n // TODO this might need a touchup for the members-app\n /**\n * Currently, when unauthenticated and in the mobile app we override the primary and secondary colors\n * to a global color scheme. When this is used in Next.js the practice colors are provided via the\n * paletteOverride prop. This means that in the members app the practice color scheme will take priority\n * over the global color scheme when unauthenticated. We'll just need to see what the product team thinks\n * of the updated experience\n */\n palette: [sitesDotTheme.palette, overrides, paletteOverride].reduce(\n R.mergeDeepRight,\n {}\n ) as MuiPalette,\n },\n };\n};\n\ntype ThemeProviderProps = {breakpoint?: Breakpoint};\n\nexport const UnauthenticatedThemeProvider: React.FCC<{\n breakpoint?: Breakpoint;\n practiceColors?: Practice['colors'];\n}> = ({children, breakpoint, practiceColors}) => {\n const palette = !practiceColors\n ? undefined\n : {\n primary: {main: practiceColors.color1},\n secondary: {main: practiceColors.color8},\n };\n return (\n \n {children}\n \n );\n};\n\n/** Override the Standard Unauthenticated theme with user-defined overrides from their selected theme */\nexport const AuthenticatedThemeProvider: React.FCC = ({\n children,\n breakpoint,\n}) => {\n const user = useUserProfile();\n return (\n \n {children}\n \n );\n};\n","function getAtomicElements(key: string): HTMLElement[] {\n return Array.from(document.querySelectorAll(`[data-atomic-update=\"${key}\"]`));\n}\n\ntype Key =\n | 'user.fullname'\n | 'messages_count'\n | 'appointments_count'\n | 'user_points';\n\n/**\n * atomicUpdate updates dynamic sections of legacy DOM\n * @param key\n * @param value\n */\nexport function atomicUpdate(key: Key, value: string) {\n getAtomicElements(key).forEach(el => {\n el.innerText = value;\n });\n}\n\ntype ImageKey = 'user.image';\n\nexport function atomicUpdateImg(key: ImageKey, src: string) {\n getAtomicElements(key).forEach(el => {\n if (el instanceof HTMLImageElement) {\n el.src = src;\n }\n });\n}\n","import {GOOGLE_RECAPTCHA_SITE_KEY, MY_DOT_URL} from '../constants/env';\nimport {\n ServiceBrandType,\n ServiceBrandInterface,\n} from '../@practicegenius/utils/ServiceBrand';\n\nconst ServiceBrand: ServiceBrandInterface = {\n PRH: 'prh',\n HUBBUX: 'hubbux',\n CULTURELLO: 'culturello',\n\n get current(): ServiceBrandType {\n const host = window.location.host.replace(/.*?\\.(.*?)\\..*/, '$1') as\n | 'patientrewardshub'\n | 'hubbux'\n | 'culturello';\n const hostToBrand = {\n patientrewardshub: this.PRH,\n hubbux: this.HUBBUX,\n culturello: this.CULTURELLO,\n };\n\n return hostToBrand[host] || this.PRH;\n },\n\n get lang() {\n return {\n practiceNoun: this.select({\n prh: 'practice',\n hubbux: 'business',\n culturello: 'business',\n }),\n hubProduct: this.select({\n prh: 'Patient Rewards Hub',\n hubbux: 'Hubbux',\n culturello: 'Culturello',\n }),\n appUrlAndroid: this.select({\n prh: 'https://play.google.com/store/apps/details?id=com.practicegenius.hubapp1',\n hubbux:\n 'https://play.google.com/store/apps/details?id=com.practicegenius.hubbux',\n culturello:\n 'https://play.google.com/store/apps/details?id=com.culturello.Culturello',\n }),\n appUrlIos: this.select({\n prh: 'https://itunes.apple.com/us/app/patient-rewards-hub/id962626763?ls=1&mt=8',\n hubbux: 'https://itunes.apple.com/us/app/hubbux-rewards/id1164729911',\n culturello: 'https://itunes.apple.com/us/app/culturello/id6738893094',\n }),\n };\n },\n\n get data() {\n return {\n myDotUrl: this.select({\n prh: MY_DOT_URL.PRH,\n hubbux: MY_DOT_URL.HUBBUX,\n culturello: MY_DOT_URL.CULTURELLO,\n }),\n googleRecaptchaSiteKey: this.select({\n prh: GOOGLE_RECAPTCHA_SITE_KEY.PRH,\n hubbux: GOOGLE_RECAPTCHA_SITE_KEY.HUBBUX,\n culturello: GOOGLE_RECAPTCHA_SITE_KEY.CULTURELLO,\n }),\n };\n },\n\n select(criteria: {prh: P; hubbux: H; culturello: C}): P | H | C {\n return criteria[this.current];\n },\n};\n\nexport default ServiceBrand;\n","/* eslint-disable no-console */\nimport {Logger} from '@practicegenius/domain/src/common/logger';\nimport {isClient} from '@practicegenius/pg-ui/src/utils/environment';\n\nconst level = Object.freeze({\n debug: 'debug',\n info: 'info',\n warning: 'warning',\n error: 'error',\n critical: 'critical',\n});\n\ntype Level = typeof level[keyof typeof level];\n\n// TODO FLOW-TO-TS Perhaps a rollbar type can be imported from somewhere?\ninterface RollbarWindow extends Window {\n Rollbar?: Record void>;\n}\n\nconst _window = isClient ? (window as RollbarWindow) : ({} as RollbarWindow);\n\nconst logger = (level: Level, message: string, data?: unknown) => {\n // only send error logs to rollbar\n if (_window.Rollbar && (level === 'error' || level === 'critical')) {\n _window.Rollbar[level](message, data);\n }\n\n if (process.env.NODE_ENV === 'development') {\n console.log(`[${level}]`, message, data);\n }\n};\n\nconst log: Logger = {\n debug(message: string, data?: unknown) {\n logger(level.debug, message, data);\n },\n\n info(message: string, data?: unknown) {\n logger(level.info, message, data);\n },\n\n warning(message: string, data?: unknown) {\n logger(level.warning, message, data);\n },\n\n error(message: string, data?: unknown) {\n logger(level.error, message, data);\n },\n\n critical(message: string, data?: unknown) {\n logger(level.critical, message, data);\n },\n};\n\nexport default log;\n","import * as R from 'ramda';\nimport {InvariantError} from 'ts-invariant';\nimport {pipe} from '@practicegenius/pg-util/src/FunctionUtils';\nimport {\n ApiClient,\n UnknownServerData,\n} from '@practicegenius/http-clients-js/src/types';\nimport {\n dropNilOrEmptyValues,\n objectKeysToCamelCaseDeep,\n renameKey,\n} from '@practicegenius/pg-util/src/ObjectUtils';\nimport {parseNullableDate} from '@practicegenius/pg-util/src/DateUtils';\nimport {Address, AddressType} from '../address';\nimport {SocialAuthIntegration} from '../integrations';\nimport {BaseUser, ContactStatus, UserType} from './BaseUser';\nimport {Practice} from '../practice';\nimport {isChild} from './birthdate';\n\nconst transformCommonTimestamps = R.evolve({\n createdAt: parseNullableDate,\n updatedAt: parseNullableDate,\n});\n\ntype GlobalUserInfo = {\n id: number;\n firstname: string;\n middlename: string;\n lastname: string;\n username: string;\n avatarUrl: string;\n hasPassword: boolean;\n responsibleFirstname: string | null;\n responsibleLastname: string | null;\n birthdate: Date;\n createdAt: Date;\n lastLoginAt: Date;\n registrationCompletedAt: Date;\n};\n\nconst transformIncomingGlobalUserProfile: (\n data: UnknownServerData\n) => GlobalUserInfo = pipe(\n objectKeysToCamelCaseDeep,\n transformCommonTimestamps,\n R.evolve({\n birthdate: parseNullableDate,\n lastLoginAt: parseNullableDate,\n registrationCompletedAt: parseNullableDate,\n })\n);\n\ntype GlobalUserAddress = Address & {\n id: number;\n globalUserId: number;\n notes: string | null;\n type: AddressType;\n createdAt: Date;\n updatedAt: Date;\n};\n\nconst transformGlobalUserAddresses = pipe(\n objectKeysToCamelCaseDeep,\n transformCommonTimestamps\n);\n\ntype GlobalUserContactType =\n | {\n type: 'email';\n subType: 'primary' | 'responsible';\n }\n | {\n type: 'phone';\n subType: 'home' | 'cell';\n };\n\ntype GlobalUserContact = {\n id: number;\n globalUserId: number;\n contact: string;\n createdAt: Date;\n verificationIdentifier: string;\n verified: boolean;\n} & GlobalUserContactType;\n\nconst transformGlobalUserContact = pipe(\n objectKeysToCamelCaseDeep,\n transformCommonTimestamps\n);\n\nexport type GlobalUserPracticeRecord = BaseUser & {\n type: UserType;\n status: 'active' | 'deleted' | 'new' | 'lockedout' | 'unqualified';\n cardNumber: string | null;\n points: number;\n isSynced: boolean;\n joinedAt: Date;\n startedAt: Date | null;\n registrationCompletedAt: Date | null;\n responsibleCellphone: string | null;\n responsibleCellphoneStatus: ContactStatus;\n responsibleEmail: string | null;\n responsibleEmailStatus: ContactStatus;\n responsibleFirstname: string | null;\n responsibleLastname: string | null;\n responsibleHomephone: string | null;\n notificationCounts: {\n messages: number;\n appointments: number;\n };\n};\n\nconst transformGlobalUserPractice = pipe(\n objectKeysToCamelCaseDeep,\n renameKey('address1', 'addressLine1'),\n renameKey('address2', 'addressLine2')\n);\n\nconst transformGlobalUserPracticeRecord = (\n rawPracticeRecord: UnknownServerData,\n rawPracticeNotificationCountsRecord: UnknownServerData\n) => {\n return pipe(\n R.assoc('notificationCounts', rawPracticeNotificationCountsRecord),\n objectKeysToCamelCaseDeep,\n renameKey('address1', 'addressLine1'),\n renameKey('address2', 'addressLine2'),\n R.evolve({\n joinedAt: parseNullableDate,\n startedAt: parseNullableDate,\n registrationCompletedAt: parseNullableDate,\n })\n )(rawPracticeRecord);\n};\n\ntype GlobalUserSocialAccount = {\n provider: SocialAuthIntegration;\n providerUserId: string;\n createdAt: Date;\n};\n\nconst transformGlobalUserSocialAccount = pipe(\n objectKeysToCamelCaseDeep,\n transformCommonTimestamps\n);\n\ntype GlobalUserHubSettings = {\n theme_id?: number;\n hide_birthday_from_feed?: boolean;\n hide_anniversary_from_feed?: boolean;\n};\n\nconst transformGlobalUserHubSettings = (\n data: UnknownServerData[]\n): Partial => {\n if (R.isEmpty(data)) return {};\n return R.reduce(\n (acc: {}, setting: UnknownServerData) => {\n if (setting.key === 'theme_id') return {...acc, theme_id: setting.value};\n return {...acc, [setting.key]: !!Number(setting.value)};\n },\n {},\n data\n );\n};\n\n/** A Global User's contacts will always contain either or both of primary and responsible emails,\n * but not neither */\ntype GlobalUserEmails =\n | {\n primary?: string;\n responsible: string;\n }\n | {\n primary: string;\n responsible?: string;\n }\n | {\n primary: string;\n responsible: string;\n };\n\nconst getGlobalUserEmails = (\n contacts: GlobalUserContact[]\n): GlobalUserEmails => {\n const primaryEmail = contacts.find(\n c => c.type === 'email' && c.subType === 'primary'\n );\n const responsibleEmail = contacts.find(\n c => c.type === 'email' && c.subType === 'responsible'\n );\n\n if (!primaryEmail && !responsibleEmail)\n throw new InvariantError(\n 'Global user contacts must contain at least one or both of primary and responsible emails'\n );\n\n return dropNilOrEmptyValues({\n primary: primaryEmail?.contact,\n responsible: responsibleEmail?.contact,\n }) as GlobalUserEmails;\n};\n\nexport type GlobalUserProfile = {\n user: GlobalUserInfo;\n practices: Practice[];\n contacts: GlobalUserContact[];\n practiceRecords: GlobalUserPracticeRecord[];\n parents: GlobalUserInfo[];\n children: GlobalUserInfo[];\n siblings: GlobalUserInfo[];\n parentContacts: GlobalUserContact[];\n childContacts: GlobalUserContact[];\n siblingContacts: GlobalUserContact[];\n addresses: GlobalUserAddress[];\n socialAccounts: GlobalUserSocialAccount[];\n hubSettings: GlobalUserHubSettings;\n themeId: number; // TODO get this from Hub settings?\n};\n\n/** A map of include names to transform functions */\nconst userProfileIncludeTransformSpec = {\n contacts: pipe(\n R.path(['included', 'contacts']),\n R.map(transformGlobalUserContact)\n ),\n practices: pipe(\n R.path(['included', 'practices']),\n R.map(transformGlobalUserPractice)\n ),\n practiceRecords: (data: UnknownServerData) => {\n const practiceRecords = R.path(\n ['included', 'practice_records'],\n data\n ) as UnknownServerData[];\n const notificationCounts = R.path(\n ['included', 'practice_records.notification_counts'],\n data\n );\n const indexedNotificationCounts = R.indexBy(\n R.prop('user_id'),\n notificationCounts as Array<{user_id: number}>\n ) as Record;\n return practiceRecords.map(practiceRecord => {\n return transformGlobalUserPracticeRecord(\n practiceRecord,\n R.pick(\n ['messages', 'appointments'],\n indexedNotificationCounts[practiceRecord.id]\n )\n );\n });\n },\n parents: pipe(\n R.path(['included', 'parents']),\n R.map(transformIncomingGlobalUserProfile)\n ),\n children: pipe(\n R.path(['included', 'children']),\n R.map(transformIncomingGlobalUserProfile)\n ),\n siblings: pipe(\n R.path(['included', 'siblings']),\n R.map(transformIncomingGlobalUserProfile)\n ),\n parentContacts: pipe(\n R.path(['included', 'parents.contacts']),\n R.map(transformGlobalUserContact)\n ),\n childContacts: pipe(\n R.path(['included', 'children.contacts']),\n R.map(transformGlobalUserContact)\n ),\n siblingContacts: pipe(\n R.path(['included', 'siblings.contacts']),\n R.map(transformGlobalUserContact)\n ),\n addresses: pipe(\n R.path(['included', 'addresses']),\n transformGlobalUserAddresses\n ),\n socialAccounts: pipe(\n R.path(['included', 'social_accounts']),\n R.map(transformGlobalUserSocialAccount)\n ),\n hubSettings: pipe>(\n R.path(['included', 'hub_settings']),\n transformGlobalUserHubSettings\n ),\n themeId: pipe(\n R.path(['included', 'hub_settings']),\n R.find(R.propEq('theme_id', 'key')),\n R.propOr('1', 'value'),\n Number\n ),\n};\n\nexport const makeGlobalUserProfileTransfomer = <\n TFields extends Array\n>(\n includes: TFields\n) => {\n const transformSpec = R.pick(includes, userProfileIncludeTransformSpec);\n return pipe>(\n R.prop('data'),\n R.applySpec({\n user: pipe(R.prop('item'), transformIncomingGlobalUserProfile),\n ...transformSpec,\n })\n );\n};\n\nconst transformFullUserProfile = makeGlobalUserProfileTransfomer(\n // @ts-expect-error This is an intentional behavior of TS\n Object.keys(userProfileIncludeTransformSpec)\n);\n\nconst profileIncludes = [\n 'contacts',\n 'practices',\n 'practice_records',\n 'practice_record.notification_counts',\n 'parents',\n 'children',\n 'siblings',\n 'parents.contacts',\n 'children.contacts',\n 'siblings.contacts',\n 'addresses',\n 'social_accounts',\n 'hub_settings',\n];\n\n/** Given an ApiClient authorized to api-core as a GlobalUser, fetch the GlobalUserProfile */\nexport const fetchGlobalUserProfile = (authorizedApiClient: ApiClient) =>\n authorizedApiClient._unsafe\n .get('/global_users/profile', {\n params: {\n include: profileIncludes.join(','),\n },\n })\n .then(transformFullUserProfile);\n\n/** Get the correct email to display for the user given their age */\nexport const getUserDisplayEmail = (profile: GlobalUserProfile) => {\n const emails = getGlobalUserEmails(profile.contacts);\n\n return isChild(profile.user.birthdate)\n ? ((emails.responsible ?? emails.primary) as string)\n : (emails.primary as string);\n};\n","import {DecodedJWT} from '@practicegenius/http-clients-js/src/types';\nimport * as R from 'ramda';\nimport {UserType} from './BaseUser';\n\nexport type UserAuth = {\n userId: number;\n userType: UserType;\n practiceId: number;\n timezone: string;\n};\n\nconst decodeIncomingJwt = (encoded: string) => atob(encoded);\n\n/**\n * Given a JWT, return the decoded payload.\n */\nexport function decodeJwt(jwt: string): DecodedJWT {\n const segments = jwt.split('.');\n\n if (segments.length !== 3)\n throw new Error(\n \"JWT is malformed. It must be of the form 'header.payload.signature'\"\n );\n\n try {\n const payload = segments[1];\n return JSON.parse(decodeIncomingJwt(payload));\n } catch (err) {\n throw new Error(\n `JWT payload could not be parsed - ${(err as Error).message}`\n );\n }\n}\n\n/**\n * Given a decoded JWT payload, return a usable auth object.\n * @param token\n * @return {{userId: int, userRole: string, practiceId: int, timezone: string}}\n */\nexport function tokenToAuth(token: DecodedJWT): UserAuth {\n return {\n userId: token.sub,\n userType: token.subtype as UserAuth['userType'],\n practiceId: token.pid,\n timezone: token.zoneinfo,\n };\n}\n\n/**\n * Convert a JWT to UserAuth in one step\n */\nexport const jwtToAuth: (jwt: string) => UserAuth = R.pipe(\n decodeJwt,\n tokenToAuth\n);\n","import {differenceInYears, isFuture, isValid} from 'date-fns';\n\n// TODO what about lang?\nexport const validateBirthDate = (birthdate?: Date | number | null) => {\n if (!birthdate) return 'Please enter your birthday.';\n\n if (!isValid(birthdate))\n return 'This date is not recognized. Please use the format mm/dd/yyyy.';\n if (isFuture(birthdate))\n return 'This date is in the future. Please use the format mm/dd/yyyy.';\n if (differenceInYears(new Date(), birthdate) > 125)\n return 'This date is too far in the past. Please use the format mm/dd/yyyy.';\n};\n\nexport const isChild = (birthdate: Date, now: Date = new Date()) =>\n differenceInYears(now, birthdate) < 13;\n\nexport const isAdult = (birthdate: Date, now: Date = new Date()) =>\n differenceInYears(now, birthdate) >= 18;\n\nexport const isTeen = (birthdate: Date, now: Date = new Date()) =>\n !isChild(birthdate, now) && !isAdult(birthdate, now);\n","import axios, {\n AxiosError,\n AxiosInstance,\n AxiosRequestConfig,\n AxiosResponse,\n} from 'axios';\nimport * as R from 'ramda';\nimport {Evolver} from 'ramda';\nimport {Err, err, Ok, ok} from 'neverthrow';\nimport {\n BadResponseException,\n InternalServerException,\n NotFoundException,\n RateLimitException,\n TimeoutException,\n UnauthenticatedException,\n ValidationException,\n} from './exceptions';\nimport {\n ApiClient,\n ApiError,\n ApiErrorKind,\n ApiResponse,\n ApiResult,\n} from './types';\n\nexport const HEADER_KEY_ASSUME_PRACTICE_ID = 'X-PG-PID';\n\n/**\n * Adds error interceptors that throw domain-specific exceptions\n */\nconst handleHTTPErrorsUnsafely = (client: AxiosInstance): AxiosInstance => {\n client.interceptors.response.use(undefined, ({code, response}) => {\n if (code === 'ECONNABORTED') {\n throw new TimeoutException();\n }\n\n switch (response.status) {\n case 401:\n case 403:\n throw new UnauthenticatedException(response);\n case 404:\n throw new NotFoundException(response);\n case 408:\n throw new TimeoutException();\n case 422:\n throw new ValidationException(response.data);\n case 429:\n throw new RateLimitException(response);\n case 500:\n throw new InternalServerException(response);\n default:\n throw new BadResponseException(response);\n }\n });\n\n return client;\n};\n\nconst getResponseError = (response: AxiosResponse | AxiosError): ApiError => {\n if ((response as AxiosError).code === 'ECONNABORTED') {\n return {kind: ApiErrorKind.TimeoutError};\n }\n const error = {response: response as AxiosResponse};\n\n switch ((response as AxiosResponse).status) {\n case 401:\n case 403:\n return {...error, kind: ApiErrorKind.UnauthenticatedError};\n case 404:\n return {...error, kind: ApiErrorKind.NotFoundError};\n case 408:\n return {...error, kind: ApiErrorKind.TimeoutError};\n case 422:\n return {\n ...error,\n kind: ApiErrorKind.ValidationError,\n errors: (response as AxiosResponse).data.errors,\n };\n case 429:\n return {...error, kind: ApiErrorKind.RateLimitError};\n case 500:\n return {...error, kind: ApiErrorKind.InternalServerError};\n default:\n return {...error, kind: ApiErrorKind.BadResponseError};\n }\n};\n\nconst makeErrResult = (respError: ApiError): ApiResult => {\n const errResult = err(respError) as ApiResult;\n\n errResult.mapData = (): Err => err(respError);\n return errResult;\n};\n\nconst makeOkResult = (response: AxiosResponse): ApiResult => {\n const okResult = ok(response) as ApiResult;\n okResult.mapData = (mapper: (data: D) => X): Ok =>\n ok(mapper(response.data));\n return okResult;\n};\n\nconst resultifyResponse = (\n responseOrErrorOrException: AxiosResponse | AxiosError | Error\n): ApiResult => {\n const exception = responseOrErrorOrException as Error;\n const error = responseOrErrorOrException as AxiosError;\n const response = responseOrErrorOrException as AxiosResponse;\n\n if (exception instanceof Error) {\n return makeErrResult({kind: ApiErrorKind.TimeoutError});\n }\n\n if (response.status > 399 || error.code) {\n return makeErrResult(getResponseError(response));\n }\n\n return makeOkResult(response);\n};\n\nconst addDefaultResponseTransformer = (\n cfg?: AxiosRequestConfig\n): AxiosRequestConfig | undefined => {\n if (cfg)\n return R.evolve(\n {\n transformResponse: R.flip(R.append)([JSON.parse]),\n },\n cfg\n );\n};\n\nconst resultifyClientInstance = (\n safeInstance: AxiosInstance\n): Omit => {\n function get(url: string, config?: AxiosRequestConfig): ApiResponse {\n return safeInstance\n .get(url, addDefaultResponseTransformer(config))\n .then(resultifyResponse)\n .catch(err => resultifyResponse(err));\n }\n\n function _delete(\n url: string,\n config?: AxiosRequestConfig\n ): ApiResponse {\n return safeInstance\n .delete(url, addDefaultResponseTransformer(config))\n .then(resultifyResponse)\n .catch(err => resultifyResponse(err));\n }\n\n function head(url: string, config?: AxiosRequestConfig): ApiResponse {\n return safeInstance\n .head(url, addDefaultResponseTransformer(config))\n .then(resultifyResponse)\n .catch(err => resultifyResponse(err));\n }\n\n function options(\n url: string,\n config?: AxiosRequestConfig\n ): ApiResponse {\n return safeInstance\n .options(url, addDefaultResponseTransformer(config))\n .then(resultifyResponse)\n .catch(err => resultifyResponse(err));\n }\n\n function post(\n url: string,\n data?: In,\n config?: AxiosRequestConfig\n ): ApiResponse {\n return safeInstance\n .post(url, data, addDefaultResponseTransformer(config))\n .then(resultifyResponse)\n .catch(err => resultifyResponse(err));\n }\n\n function put(\n url: string,\n data?: In,\n config?: AxiosRequestConfig\n ): ApiResponse {\n return safeInstance\n .put(url, data, addDefaultResponseTransformer(config))\n .then(resultifyResponse)\n .catch(err => resultifyResponse(err));\n }\n\n function patch(\n url: string,\n data?: In,\n config?: AxiosRequestConfig\n ): ApiResponse {\n return safeInstance\n .patch(url, data, addDefaultResponseTransformer(config))\n .then(resultifyResponse)\n .catch(err => resultifyResponse(err));\n }\n\n return {get, delete: _delete, head, options, post, put, patch};\n};\n\ntype NoAuthApiClientFactory = (\n config: AxiosRequestConfig & {\n baseURL?: string;\n }\n) => ApiClient;\n/**\n * Generates an ApiClient instance for making requests that don't require authentication\n */\nexport const makeNoAuthApiClient: NoAuthApiClientFactory = config => {\n const unsafeInstance = (\n R.pipe(axios.create, handleHTTPErrorsUnsafely) as (\n c: typeof config\n ) => AxiosInstance\n )({\n ...config,\n });\n\n const safeInstance = axios.create({\n ...config,\n validateStatus: R.T,\n });\n\n return {\n _unsafe: unsafeInstance,\n ...resultifyClientInstance(safeInstance),\n };\n};\n\nexport const makeInterserviceApiClient = (\n clientConfig: Omit & {\n baseURL: string;\n interserviceToken: string;\n practiceId?: number;\n }\n) => {\n const {interserviceToken, practiceId, ...config} = clientConfig;\n\n const headers: Record = {\n Authorization: `Basic ${interserviceToken}`,\n };\n\n if (practiceId) headers[HEADER_KEY_ASSUME_PRACTICE_ID] = practiceId;\n\n const axiosConfig = {\n ...config,\n headers: {\n ...clientConfig.headers,\n ...headers,\n },\n };\n\n const unsafeInstance = (\n R.pipe(axios.create, handleHTTPErrorsUnsafely) as (\n c: typeof axiosConfig\n ) => AxiosInstance\n )({\n ...axiosConfig,\n });\n\n const safeInstance = axios.create({\n ...axiosConfig,\n validateStatus: R.T,\n });\n\n return {\n _unsafe: unsafeInstance,\n ...resultifyClientInstance(safeInstance),\n };\n};\n\ntype AuthApiClientFactory = (\n clientConfig: Omit & {\n baseURL?: string;\n authToken: string;\n }\n) => ApiClient;\n/**\n * Generates an ApiClient instance for making requests that require authentication\n */\nexport const makeAuthApiClient: AuthApiClientFactory = clientConfig => {\n const _auth = clientConfig.authToken;\n\n const makeAxiosConfig = (): AxiosRequestConfig => ({\n baseURL: clientConfig.baseURL,\n headers: {\n Authorization: `Bearer ${_auth}`,\n },\n });\n\n /**\n * If certain environment conditions are met,\n * configures an interceptor that logs request/responses in our RequestSpec format\n */\n const bindRequestSpecLogger = (instance: AxiosInstance): AxiosInstance => {\n const logForConfig = (\n config: AxiosRequestConfig,\n response?: any,\n status?: number\n ) => {\n if (config.method) {\n const reqData = config.data;\n const requestSpec: Record = {\n [config.method]: reqData\n ? [`/${config.url}`, JSON.parse(reqData)]\n : [`/${config.url}`],\n };\n\n if (config.params) requestSpec.query = config.params;\n\n requestSpec.reply = [status, response || 'no response'];\n\n // eslint-disable-next-line no-console\n console.log('requestSpec\\n', JSON.stringify(requestSpec, null, 2));\n }\n };\n\n if (\n typeof window !== 'undefined' &&\n typeof process !== 'undefined' &&\n (process.env.LOG_REQUEST_SPEC ||\n localStorage?.getItem?.('LOG_REQUEST_SPEC'))\n ) {\n instance.interceptors.response.use(\n response => {\n logForConfig(response.config, response.data, response.status);\n\n return response;\n },\n error => {\n // Unfortunately it seems that there's no way to get the response body here\n logForConfig(error.config, error.message);\n throw error;\n }\n );\n }\n\n return instance;\n };\n\n const createSafeInstance = (): Omit =>\n (\n R.pipe(axios.create, bindRequestSpecLogger, resultifyClientInstance) as (\n config: AxiosRequestConfig\n ) => ReturnType\n )({\n ...makeAxiosConfig(),\n validateStatus: R.T,\n });\n\n async function get(\n url: string,\n config: AxiosRequestConfig\n ): ApiResponse {\n const instance = createSafeInstance();\n return instance.get(url, config);\n }\n async function _delete(\n url: string,\n config?: AxiosRequestConfig\n ): Promise> {\n const instance = createSafeInstance();\n return instance.delete(url, config);\n }\n async function head(\n url: string,\n config?: AxiosRequestConfig\n ): Promise> {\n const instance = createSafeInstance();\n return instance.head(url, config);\n }\n async function options(\n url: string,\n config?: AxiosRequestConfig\n ): Promise> {\n const instance = createSafeInstance();\n return instance.options(url, config);\n }\n async function patch(\n url: string,\n data?: In,\n config?: AxiosRequestConfig\n ): Promise> {\n const instance = createSafeInstance();\n return instance.patch(url, data, config);\n }\n async function post(\n url: string,\n data?: In,\n config?: AxiosRequestConfig\n ): Promise> {\n const instance = createSafeInstance();\n return instance.post(url, data, config);\n }\n async function put(\n url: string,\n data?: In,\n config?: AxiosRequestConfig\n ): Promise> {\n const instance = createSafeInstance();\n return instance.put(url, data, config);\n }\n\n return {\n get _unsafe(): AxiosInstance {\n return R.pipe(\n makeAxiosConfig,\n axios.create,\n bindRequestSpecLogger,\n handleHTTPErrorsUnsafely\n )();\n },\n get,\n delete: _delete,\n head,\n options,\n patch,\n post,\n put,\n };\n};\n\n/**\n * Utility for creating ApiResults from unknown data (for testing)\n */\nexport const makeApiResult = (\n response: unknown,\n isErr = false\n): ApiResult =>\n isErr\n ? makeErrResult(response as ApiError)\n : makeOkResult(response as AxiosResponse);\n\n/**\n * Utility for creating ApiError instances from a partial ApiError object\n */\nexport const makeApiError = (err: {\n kind: ApiErrorKind;\n response?: AxiosResponse;\n errors?: Record;\n}): ApiError => err as ApiError;\n\n/**\n * The methods on a NilApiClient instance don't do anything but return an error, but it's useful when you want to\n * instantiate something that requires an ApiClient instance before you can make a real one,\n * and you don't want to handle null checks everywhere.\n */\nexport const makeNilApiClient = (): ApiClient => {\n const error = makeApiError({kind: ApiErrorKind.InternalServerError});\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const handler = R.always(Promise.resolve(makeErrResult(error)));\n\n return {\n _unsafe: axios.create(),\n get: handler,\n delete: handler,\n head: handler,\n options: handler,\n post: handler,\n put: handler,\n patch: handler,\n };\n};\n","export class UnauthenticatedException extends Error {\n name = 'UnauthenticatedError';\n response: Response;\n constructor(response: Response) {\n super(`Response failed as unauthenticated (${response.status})`);\n this.response = response;\n }\n}\n\nexport class NotFoundException extends Error {\n name = 'NotFoundError';\n response: Response;\n constructor(response: Response) {\n super();\n this.response = response;\n }\n}\n\nexport class ValidationException extends Error {\n name = 'ValidationError';\n /** All of the data from the response */\n data: Record;\n /** Errors from the response data (convenience accessor) */\n errors: Record;\n\n constructor(data: Record) {\n super();\n this.errors = (data.errors ?? {}) as Record;\n this.data = data;\n }\n}\n\nexport class InternalServerException extends Error {\n name = 'InternalServerError';\n response: Response;\n constructor(response: Response) {\n super();\n this.response = response;\n }\n}\n\nexport class BadResponseException extends Error {\n name = 'BadResponseError';\n response: Response;\n constructor(response: Response) {\n super();\n this.response = response;\n }\n}\n\nexport class TimeoutException extends Error {}\n\nexport class RateLimitException extends Error {\n response: Response;\n constructor(response: Response) {\n super();\n this.response = response;\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {Result} from 'neverthrow';\nimport {AxiosInstance, AxiosRequestConfig, AxiosResponse} from 'axios';\n\nexport enum ApiErrorKind {\n UnauthenticatedError,\n NotFoundError,\n ValidationError,\n InternalServerError,\n BadResponseError,\n TimeoutError,\n RateLimitError,\n InvalidInstance,\n}\n\ninterface BadApiResponse {\n kind: ApiErrorKind;\n response: AxiosResponse;\n}\n\nexport interface InvalidInstanceError {\n kind: ApiErrorKind.InvalidInstance;\n}\n\n// This does not extend BadApiResponse because a timeout might not have a response to send back\nexport interface TimeoutError {\n kind: ApiErrorKind.TimeoutError;\n response?: AxiosResponse;\n}\n\nexport interface InternalServerError extends BadApiResponse {\n kind: ApiErrorKind.InternalServerError;\n}\n\nexport interface UnauthenticatedError extends BadApiResponse {\n kind: ApiErrorKind.UnauthenticatedError;\n}\n\nexport interface NotFoundError extends BadApiResponse {\n kind: ApiErrorKind.NotFoundError;\n}\n\nexport interface ValidationError extends BadApiResponse {\n kind: ApiErrorKind.ValidationError;\n errors: Record;\n}\n\nexport interface BadResponseError extends BadApiResponse {\n kind: ApiErrorKind.BadResponseError;\n}\n\nexport interface RateLimitError extends BadApiResponse {\n kind: ApiErrorKind.RateLimitError;\n}\n\nexport type ApiError =\n | TimeoutError\n | InternalServerError\n | UnauthenticatedError\n | NotFoundError\n | ValidationError\n | BadResponseError\n | RateLimitError\n | InvalidInstanceError;\n\nexport type ApiResult = Result, ApiError> & {\n mapData(mapper: (d: Data) => X): Result;\n};\n\nexport type ApiResponse = Promise>;\n\nexport type UnknownServerData = Record;\n\nexport interface ApiClient {\n _unsafe: AxiosInstance;\n get(\n url: string,\n config?: AxiosRequestConfig\n ): ApiResponse;\n delete(\n url: string,\n config?: AxiosRequestConfig\n ): ApiResponse;\n head(\n url: string,\n config?: AxiosRequestConfig\n ): ApiResponse;\n options(\n url: string,\n config?: AxiosRequestConfig\n ): ApiResponse;\n post(\n url: string,\n data?: In,\n config?: AxiosRequestConfig\n ): ApiResponse;\n put(\n url: string,\n data?: In,\n config?: AxiosRequestConfig\n ): ApiResponse;\n patch(\n url: string,\n data?: In,\n config?: AxiosRequestConfig\n ): ApiResponse;\n}\n\nexport type JWT$Server = {\n token: string;\n refresh_token: string;\n expires_in: number;\n};\n\nexport type JWT = {\n token: string;\n refreshToken: string;\n expiresIn: number;\n};\n\nexport type DecodedJWT = {\n /** user id */\n sub: number;\n /** issued at */\n iat: number;\n /** expires at */\n exp: number;\n /** practice id */\n pid: number;\n /** timezone identifier */\n zoneinfo: string;\n /** user type */\n subtype: string;\n /** issuer */\n iss: string;\n};\n","/** Detects if rendering in a Next.js environment */\nexport const useIsNextJs = () => {\n try {\n // Requiring useRouter this way prevents a bundle-level issue in the router from crashing the app\n // eslint-disable-next-line @typescript-eslint/no-var-requires,global-require\n const {useRouter} = require('next/router');\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useRouter();\n return true;\n } catch (e) {\n return false;\n }\n};\n","import * as React from 'react';\nimport {alpha, styled} from '@mui/material/styles';\nimport MuiButton, {ButtonProps as MuiButtonProps} from '@mui/material/Button';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport Box from '@mui/material/Box';\nimport {overlayColor} from '../utils/colors';\nimport {makeSxStyles} from '../utils/sx-helpers';\n\nexport enum ButtonHeight {\n SHORT = 'short',\n NORMAL = 'normal',\n MEDIUM = 'medium',\n TALL = 'tall',\n}\n\nexport enum ButtonWidth {\n NARROW = 'narrow',\n MEDIUM = 'medium',\n WIDE = 'wide',\n ELASTIC = 'elastic',\n FULL_WIDTH = 'fullWidth',\n}\ntype ButtonSize = 'small' | 'medium' | 'large';\nconst heightMap: Record = {\n [ButtonHeight.SHORT]: 'small',\n [ButtonHeight.NORMAL]: 'medium',\n [ButtonHeight.MEDIUM]: 'medium',\n [ButtonHeight.TALL]: 'large',\n};\n\nconst widthMap: Record = {\n [ButtonWidth.NARROW]: '64px',\n [ButtonWidth.MEDIUM]: '104px',\n [ButtonWidth.WIDE]: '152px',\n [ButtonWidth.FULL_WIDTH]: '100%',\n [ButtonWidth.ELASTIC]: 'auto',\n};\n\nexport enum ButtonVariant {\n text = 'text',\n outlined = 'outlined',\n contained = 'contained',\n}\n\nconst muiColors = ['primary', 'secondary'] as const;\ntype MuiColor = typeof muiColors[number];\nconst nonMuiColors = ['error', 'success', 'warning'] as const;\ntype NonMuiColor = typeof nonMuiColors[number];\n\ntype ButtonColor =\n | undefined\n | 'inherit'\n | 'primary'\n | 'secondary'\n | NonMuiColor;\n\nconst parseMuiColor = (color: ButtonColor): MuiColor | undefined => {\n return muiColors.includes(color as MuiColor)\n ? (color as MuiColor)\n : undefined;\n};\n\nconst getBackgroundForBlank = alpha;\nconst getBackgroundForFilled = (\n base: string,\n overlay: string,\n opacity: number\n): string => overlayColor(base, alpha(overlay, opacity));\n\nconst bgFunctions = {\n text: getBackgroundForBlank,\n outlined: getBackgroundForBlank,\n contained: getBackgroundForFilled,\n};\n\nconst focusOpacity = 0.24;\n\ntype ButtonProps = Omit & {\n height?: ButtonHeight;\n width?: ButtonWidth;\n variant?: ButtonVariant;\n color?: ButtonColor;\n loading?: boolean;\n uppercase?: boolean;\n /** When not specified, spinner color matches button color */\n loadingIndicatorColor?: React.ComponentProps<\n typeof CircularProgress\n >['color'];\n};\n\nconst StyledButton = styled(MuiButton)(({width}) => ({\n transition: 'all 0.75s ease',\n width: widthMap[width as keyof typeof widthMap],\n}));\n\nconst makeUseStyles = ({color, variant}: ButtonProps) => {\n return makeSxStyles(theme => {\n const hasThemeColor = color && color !== 'inherit';\n const colorArgs = {\n text: hasThemeColor\n ? [theme.palette[color].main]\n : [theme.palette.text.primary],\n outlined: hasThemeColor\n ? [theme.palette[color].main]\n : [theme.palette.text.primary],\n contained: hasThemeColor\n ? [theme.palette[color].main, theme.palette[color].contrastText]\n : [\n theme.palette.grey[300],\n theme.palette.getContrastText(theme.palette.grey[300]),\n ],\n };\n\n const styleColors = colorArgs[variant || 'contained'];\n const hoverBgArgs = [...styleColors, theme.palette.action.hoverOpacity];\n const focusBgArgs = [...styleColors, focusOpacity];\n\n const bgFn = bgFunctions[variant || 'contained'];\n // @ts-ignore\n const hoverBg = (() => bgFn(...hoverBgArgs))();\n // @ts-ignore\n const focusBg = (() => bgFn(...focusBgArgs))();\n\n return {\n text: {\n color: hasThemeColor\n ? theme.palette[color].main\n : theme.palette.text.primary,\n '&:hover': {backgroundColor: hoverBg},\n '@media (hover: none)': {\n ':not(#\\\\20)&:hover': {backgroundColor: hoverBg},\n },\n '&:focus': {backgroundColor: focusBg},\n },\n outlined: {\n borderColor: hasThemeColor\n ? theme.palette[color].main\n : alpha(theme.palette.common.black, 0.2),\n color: hasThemeColor\n ? theme.palette[color].main\n : theme.palette.text.primary,\n '&:hover': {backgroundColor: hoverBg},\n '@media (hover: none)': {\n ':not(#\\\\20)&:hover': {backgroundColor: hoverBg},\n },\n '&:focus': {backgroundColor: focusBg},\n },\n contained: {\n backgroundColor: hasThemeColor ? theme.palette[color].main : 'inherit',\n color: hasThemeColor ? theme.palette[color].contrastText : 'inherit',\n '&:hover': {backgroundColor: hoverBg},\n '@media (hover: none)': {\n ':not(#\\\\20)&:hover': {backgroundColor: hoverBg},\n },\n '&:focus': {backgroundColor: focusBg},\n },\n noTransform: {textTransform: 'none'},\n spinnerContainer: {\n position: 'absolute',\n left: 0,\n top: 0,\n width: '100%',\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n },\n };\n });\n};\n\nconst HideButtonText = styled('span')({visibility: 'hidden'});\n\nconst Spinner: React.FC<{\n color?: 'inherit' | 'primary' | 'secondary';\n}> = props => ;\n\nexport const Button: React.FC = React.forwardRef(\n (\n {\n height = ButtonHeight.NORMAL,\n width = ButtonWidth.ELASTIC,\n variant = ButtonVariant.contained,\n loading,\n loadingIndicatorColor,\n disabled,\n children,\n color,\n uppercase = true,\n ...otherProps\n },\n ref\n ) => {\n const colorAsMui = parseMuiColor(color);\n\n const [styles, sn] = makeUseStyles({\n color,\n variant,\n })();\n\n const ButtonTextWrapper = loading ? HideButtonText : React.Fragment;\n\n return (\n \n {children}\n {loading && (\n \n \n \n )}\n \n );\n }\n);\n","import * as React from 'react';\nimport * as R from 'ramda';\nimport {\n createTheme,\n darken,\n lighten,\n getLuminance,\n alpha,\n PaletteOptions,\n Breakpoint,\n ThemeOptions,\n} from '@mui/material/styles';\nimport {CssBaseline, ThemeProvider as MuiThemeProvider} from '@mui/material';\nimport {CacheProvider} from '@emotion/react';\nimport createCache, {EmotionCache} from '@emotion/cache';\nimport {isClient} from '../../utils/environment';\nimport '@mui/x-data-grid/themeAugmentation';\n\nfunction createExtraScopePlugin(...extra: any[]) {\n const scopes = extra.map(scope => `${scope.trim()} `);\n\n return (element: any) => {\n if (element.type !== 'rule') {\n return;\n }\n\n if (element.root?.type === '@keyframes') {\n return;\n }\n\n element.props = element.props\n .map((prop: string) => scopes.map(scope => scope + prop))\n .reduce(\n (scopesArray: string[], scope: string[]) => scopesArray.concat(scope),\n []\n );\n };\n}\n\nconst typography = {\n fontFamily: ['Source Sans Pro', 'sans-serif'].join(','),\n fontSize: 15.22,\n};\n\nconst buttonStateAdjustmentCoefficients = {\n hover: 0.08,\n focus: 0.12,\n active: 0.12,\n};\n\nconst spacingScalingFactor = 8;\n\nexport const palette = {\n primary: {\n main: '#137194',\n 50: '#E1F4F6',\n 100: '#B3E2EA',\n 200: '#85CFDD',\n 300: '#5DBCD1',\n 400: '#42AECB',\n 500: '#2AA1C5',\n 600: '#2194B8',\n 700: '#1482A7',\n 800: '#137194',\n 900: '#075273',\n },\n secondary: {\n main: '#E19516',\n 50: '#FCFAE5',\n 100: '#F8F2BF',\n 200: '#F3E994',\n 300: '#EEE06B',\n 400: '#EBDB4B',\n 500: '#E8D52B',\n 600: '#E6C325',\n 700: '#E4AC1E',\n 800: '#E19516',\n 900: '#DB6D06',\n },\n error: {\n main: '#B00020',\n },\n warning: {\n main: '#FACC0F',\n },\n success: {\n main: '#087F23',\n },\n text: {\n secondary: 'rgba(0,0,0,0.60)',\n },\n action: {\n hoverOpacity: buttonStateAdjustmentCoefficients.hover,\n focusOpacity: buttonStateAdjustmentCoefficients.focus,\n },\n};\n\nconst autofillShadow = '0 0 0px 1000px hsl(0, 0%, 96%) inset';\nexport const defaultFocusStyle = {\n outline: '-webkit-focus-ring-color auto 1px',\n};\nconst theme = createTheme();\n\nexport const commonPopoverPositioning = {\n bottomLeft: {\n anchorOrigin: {\n vertical: 'bottom' as const,\n horizontal: 'left' as const,\n },\n transformOrigin: {\n vertical: 'top' as const,\n horizontal: 'left' as const,\n },\n },\n};\n\nexport const defaultThemeOptions: ThemeOptions = {\n spacing: spacingScalingFactor,\n palette: palette as PaletteOptions,\n typography,\n components: {\n MuiOutlinedInput: {\n styleOverrides: {\n root: {\n borderRadius: '1px',\n '& .MuiIconButton-root:not([class*=MuiAutocomplete])': {\n padding: 4,\n },\n },\n input: {\n // make the autofilled input field background unchanged\n '&:-webkit-autofill': {\n WebkitBoxShadow: autofillShadow,\n boxShadow: autofillShadow,\n },\n },\n adornedStart: {\n '& .MuiInputAdornment-positionStart > button': {\n marginLeft: '-11px',\n },\n },\n adornedEnd: {\n '& .MuiInputAdornment-positionEnd > button': {\n marginRight: '-11px',\n },\n },\n },\n },\n MuiAutocomplete: {\n styleOverrides: {\n listbox: {\n maxHeight: '232px',\n },\n },\n },\n MuiModal: {\n styleOverrides: {\n root: {\n '& .MuiBackdrop-root': {\n backdropFilter: 'blur(2px)',\n },\n },\n },\n },\n MuiTableHead: {\n styleOverrides: {\n root: {\n fontWeight: 600,\n padding: `${spacingScalingFactor}px ${2 * spacingScalingFactor}px`,\n },\n },\n },\n MuiDialog: {\n styleOverrides: {\n root: {\n root: {\n '& .MuiBackdrop-root': {\n backdropFilter: 'blur(2px)',\n },\n },\n },\n paperFullScreen: {\n paddingTop: 'env(safe-area-inset-top)',\n paddingBottom: 'env(safe-area-inset-bottom)',\n '& .MuiAppBar-root': {\n position: 'relative',\n height: 'unset',\n borderBottom: 'initial',\n },\n },\n },\n },\n MuiFab: {\n styleOverrides: {\n root: {\n marginBottom: 'env(safe-area-inset-bottom)',\n },\n },\n },\n MuiButton: {\n styleOverrides: {\n root: {\n '&.Mui-focusVisible': defaultFocusStyle,\n },\n contained: {\n boxShadow: 'none',\n '&:hover': {boxShadow: 'none'},\n '&:focus': {boxShadow: 'none'},\n },\n },\n },\n MuiIconButton: {\n styleOverrides: {\n root: {\n '&.Mui-focusVisible': defaultFocusStyle,\n },\n },\n },\n MuiCardActionArea: {defaultProps: {disableRipple: true}},\n MuiFormControl: {\n defaultProps: {\n variant: 'outlined',\n fullWidth: true,\n margin: 'dense',\n size: 'small',\n },\n },\n MuiButtonBase: {\n defaultProps: {disableRipple: true}, // No more ripple, on the whole application 💣!\n styleOverrides: {\n root: {\n ...typography,\n },\n },\n },\n MuiCheckbox: {\n defaultProps: {color: 'primary'},\n styleOverrides: {\n root: {\n '&.Mui-focusVisible': {\n backgroundColor: alpha(\n palette.primary.main,\n palette.action.focusOpacity\n ),\n },\n },\n },\n },\n MuiMenu: {\n defaultProps: {...commonPopoverPositioning.bottomLeft},\n styleOverrides: {\n root: {\n '& .MuiBackdrop-root': {\n backdropFilter: 'none',\n },\n },\n },\n },\n MuiSelect: {\n defaultProps: {\n size: 'small',\n MenuProps: {\n ...commonPopoverPositioning.bottomLeft,\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.keyCode === 32) {\n (e.target as HTMLLIElement).click();\n }\n },\n },\n },\n styleOverrides: {\n select: {\n '&:focus': {\n backgroundColor: 'none',\n },\n },\n },\n },\n MuiTextField: {\n defaultProps: {variant: 'outlined'},\n },\n MuiTabs: {\n styleOverrides: {\n root: {\n [theme.breakpoints.up('md')]: {\n minWidth: '160px',\n },\n },\n },\n },\n MuiPopover: {\n styleOverrides: {\n root: {\n '& .MuiBackdrop-root': {\n backdropFilter: 'none',\n },\n },\n },\n },\n MuiDataGrid: {\n styleOverrides: {\n root: {\n border: 'none',\n backgroundColor: theme.palette.common.white,\n },\n // @ts-ignore this is a valid name\n columnHeaderRow: {\n background: `${theme.palette.common.white} !important`,\n },\n toolbarContainer: {\n paddingTop: 16,\n paddingLeft: 24,\n paddingRight: 24,\n '& .MuiButtonBase-root': {\n minWidth: 'unset',\n '& .MuiButton-startIcon': {\n margin: 'unset',\n padding: 1,\n '& .MuiSvgIcon-root': {\n fontSize: 24,\n },\n },\n },\n },\n filterForm: {\n maxWidth: '100vw',\n alignItems: 'center',\n },\n filterFormDeleteIcon: {\n width: 'unset',\n },\n filterFormValueInput: {\n '& .MuiFormControl-root': {\n marginTop: 0,\n marginBottom: 0,\n },\n },\n virtualScrollerContent: {\n minHeight: 52,\n },\n row: {\n '&--dynamicHeight': {\n maxHeight: '250px !important',\n borderTop: `1px solid rgba(224, 224, 224, 1)`,\n paddingTop: 8,\n paddingBottom: 8,\n alignItems: 'center',\n '& .MuiDataGrid-cell': {\n borderTop: 'none',\n maxHeight: 250,\n },\n '&.MuiDataGrid-row--firstVisible': {\n borderTop: 'none',\n },\n },\n },\n cell: {\n '&:focus': {\n outline: 'none',\n },\n '&:focus-within': {\n outline: 'none',\n },\n '& .MuiDataGrid-actionsCell': {\n '& .MuiButtonBase-root': {\n padding: 8,\n minWidth: 'unset',\n '& .MuiSvgIcon-root': {\n fontSize: 24,\n },\n },\n },\n },\n columnHeader: {\n border: 'transparent',\n '&:focus': {\n outline: 'none',\n },\n },\n },\n },\n },\n};\n\n/**\n * Use for getting the default theme options but overriding the initial breakpoint (for testing)\n */\nexport const defaultThemeOptionsAtBreakpoint = (breakpoint: Breakpoint) =>\n R.mergeDeepRight(defaultThemeOptions, {\n props: {\n MuiWithWidth: {\n initialWidth: breakpoint,\n },\n },\n });\n\nconst defaultTheme = createTheme(defaultThemeOptions);\n\ntype Props = {\n theme?: typeof defaultTheme;\n};\n\n// `createCache` is not defined on the server, so we must gatekeep this call to prevent\n// the next server from crashing during module resolution\nconst cache = isClient\n ? createCache({\n key: 'css',\n stylisPlugins:\n process.env.NODE_ENV === 'test'\n ? []\n : [createExtraScopePlugin(':not(#\\\\20)')],\n })\n : ({} as EmotionCache);\n\nexport const ThemeProvider: React.FCC = ({\n children,\n theme = defaultTheme,\n}) => {\n return (\n \n {children}\n \n );\n};\n\n/**\n * This is just like ThemeProvider, but it's meant to be used\n * where legacy CSS is not a concern (Next.js)\n */\nexport const CleanThemeProvider: React.FCC = ({\n children,\n theme = defaultTheme,\n}) => {\n return (\n \n \n <>{children}\n \n );\n};\n\n/** Given a backgroundColor and adjustment mode,\n * get the standard style defs for common button states */\nexport const getButtonBackgroundColorStyles = (\n backgroundColor: string,\n /** Whether the button should darken or lighten on interaction.\n * By default this is derived by measuring the luminance of backgroundColor */\n adjustMode: 'light' | 'dark' = getLuminance(backgroundColor) > 0.5\n ? 'dark'\n : 'light'\n) => {\n const adjustFn = adjustMode === 'light' ? lighten : darken;\n\n return {\n backgroundColor,\n '&:hover, &:focus': {\n backgroundColor: adjustFn(\n backgroundColor,\n buttonStateAdjustmentCoefficients.hover\n ),\n },\n '&:active': {\n backgroundColor: adjustFn(\n backgroundColor,\n buttonStateAdjustmentCoefficients.active\n ),\n },\n transition: 'background 0.25s cubic-bezier(0.4, 0, 0.2, 1) 0ms',\n };\n};\n","import {\n ColorObject,\n decomposeColor,\n recomposeColor,\n} from '@mui/material/styles';\n\ntype RGBAColorValue = [number, number, number, number];\n\nfunction normalizeAlpha({type, values}: ColorObject): RGBAColorValue {\n return type === 'rgb'\n ? [values[0], values[1], values[2], 1]\n : [values[0], values[1], values[2], values[3] as number];\n}\n\nexport function overlayColor(baseColor: string, overlayColor: string): string {\n const base = normalizeAlpha(decomposeColor(baseColor));\n const add = normalizeAlpha(decomposeColor(overlayColor));\n const alpha = 1 - (1 - add[3]) * (1 - base[3]);\n\n const calcIndex = (i: number) =>\n Math.round(\n (add[i] * add[3]) / alpha + (base[i] * base[3] * (1 - add[3])) / alpha\n );\n\n return recomposeColor({\n type: 'rgba',\n values: [calcIndex(0), calcIndex(1), calcIndex(2), alpha],\n });\n}\n","import * as R from 'ramda';\nimport {SxProps, Theme, useTheme} from '@mui/material';\nimport React from 'react';\nimport styled from '@mui/system/styled';\n\n/** SxProps with the MUI Theme */\nexport type MuiSxProps = SxProps;\n/** Record of MuiSxProps. Intended to be used for migrating MUI v4 makeStyles and not for ongoing component work */\nexport type MuiSxPropsRecord = Record;\n\n/** Like MUI's styled but accepts the SX prop as its styling parameter */\nexport const styledSx =\n (Component: Parameters[0]) =>\n (sx: MuiSxProps): React.ComponentType => {\n const SxAbleComponent = styled(Component)({});\n return (props: TProps) => ;\n };\n\n/** Given a MuiSxPropsRecord, derives a function that allows for fluently composing its styles.\n * This derived function is API compatible with the commonly-used 'classnames' library, except\n * that it outputs an object instead of a string.\n * NOTE: the resulting merged object is only a single-level merge. Style props will be\n * overwritten if they are redeclared in subsequent sx props. This is consistent with CSS class behavior.\n */\nexport function makeComposeSx(styles: T) {\n type Key = keyof T;\n /**\n * An argument to composeSx().\n * K is a key of the MuiSxPropsRecord that is being composed.\n */\n type ComposeSxArg = Key | Partial> | ComposeSxArg[];\n\n return function composeSx(...args: ComposeSxArg[]): MuiSxProps {\n // We'll iterate over the args and build up an array of MuiSxProps to merge later\n const sxs: NonNullable[] = [];\n const processArg = (arg: ComposeSxArg) => {\n // Base cases\n if (typeof arg === 'string') return sxs.push(styles[arg] ?? {});\n\n if (typeof arg === 'object' && !Array.isArray(arg))\n Object.keys(arg).forEach(key => {\n if (arg[key]) {\n sxs.push(styles[key] ?? {});\n }\n });\n\n // Recursive case: if the arg is an array, apply this function to each element\n if (Array.isArray(arg)) {\n return arg.forEach(processArg);\n }\n };\n\n // Process all args\n args.forEach(processArg);\n\n // Merge all the MuiSxProps together\n return R.mergeAll(sxs);\n };\n}\n\n/** Given a function that returns a MuiSxPropsRecord, returns a hook that returns the\n * resolved style objects (as SxProps) and the derived composeSx function.\n * This is intended to be used for migrating MUI v4 makeStyles and not for ongoing component work.\n *\n * @deprecated prefer inline sx props\n */\nexport function makeSxStyles(\n makeStyles: (theme: Theme) => TStyles\n) {\n return () => {\n const theme = useTheme();\n const styles = makeStyles(theme);\n const composeSx = makeComposeSx(styles);\n\n return [styles, composeSx] as const;\n };\n}\n\n/** Adapts a MUI v4 classes declaration to use Sx styles targeting the appropriate child selectors */\nexport const classifySx = (\n /** Base name of the component without the leading .Mui (ex 'Avatar' translates to '.MuiAvatar' ) */\n componentName: string,\n /** Record of SxProps. Keys correspond to members of the classes API of the parent component */\n sx: MuiSxPropsRecord\n) => {\n const classifiedSx: MuiSxProps = {};\n Object.keys(sx).forEach(key => {\n /** @ts-expect-error TS doesn't like something about this, but the proper behavior is asserted by tests */\n classifiedSx[`& .Mui${componentName}-${key}`] = sx[key];\n });\n return classifiedSx;\n};\n","import {Logger} from '@practicegenius/domain/src/common/logger';\nimport * as React from 'react';\n\n/**\n * A handler for catastrophic, unrecoverable errors\n * When an error is caught, this:\n * - logs the error with the given message\n * - renders the `errorNode`\n *\n * Because this exposes no way to clear the error,\n * the errorNode should instruct the user how to proceed\n */\nexport class CatastrophicErrorBoundary extends React.Component<\n {\n errorLogMessage: string;\n errorNode: React.ReactNode;\n logger: Logger;\n children?: React.ReactNode;\n },\n {\n hasError: boolean;\n }\n> {\n static getDerivedStateFromError() {\n return {hasError: true};\n }\n\n state = {\n hasError: false,\n };\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {\n this.props.logger.error(this.props.errorLogMessage, {error, errorInfo});\n }\n\n render() {\n if (this.state.hasError) {\n return this.props.errorNode;\n }\n\n return this.props.children;\n }\n}\n","import React from 'react';\n\n/** Defers rendering its children for the specified amount of time (default 1 second) */\nexport const Deferred: React.FC<{\n forMs?: number;\n children?: React.ReactNode;\n}> = ({forMs = 1000, children}) => {\n const [render, setRender] = React.useState(false);\n\n React.useEffect(() => {\n const timeout = setTimeout(() => setRender(true), forMs);\n\n return () => clearTimeout(timeout);\n }, []);\n\n return render ? <>{children} : null;\n};\n","import React from 'react';\nimport {Box, Typography, Alert} from '@mui/material';\nimport {isNotNil} from '@practicegenius/pg-util/src/TypescriptUtils';\nimport {Button, ButtonVariant} from '../base/Material/components/Button';\n\ntype Props = {\n retryFn?: () => void;\n messageBody?: React.ReactNode;\n variant?: 'standard' | 'compact';\n};\n\nexport const FetchFailureMessage: React.FC = ({\n retryFn,\n messageBody,\n variant = 'standard',\n}) => {\n if (variant === 'compact')\n return (\n \n Retry\n \n ) : null\n }\n >\n {messageBody ?? 'Oops! There was a problem loading.'}\n \n );\n\n return (\n \n \n Oops! There is a problem.\n \n \n {messageBody ?? (\n <>\n It's not you - it's us! We have just been alerted to the problem and\n are working on fixing it. Please give us a call at{' '}\n (800) 560-1469 with any questions.\n \n )}\n \n {isNotNil(retryFn) && (\n \n \n \n )}\n \n );\n};\n","import React from 'react';\nimport {styled} from '@mui/material/styles';\nimport MuiTypography from '@mui/material/Typography';\nimport {compose, spacing, palette, breakpoints, typography} from '@mui/system';\nimport {makeLineClampJss} from '@practicegenius/pg-util/src/DomUtils';\nimport {makeSxStyles} from '../base/Material/utils/sx-helpers';\n\nconst useResponsiveTypographyStyles = ({\n lineClamp,\n preserveWhitespace,\n}: {\n lineClamp?: number;\n preserveWhitespace: boolean;\n}) =>\n makeSxStyles(theme => ({\n pageTitle: {\n fontSize: '26px',\n fontWeight: 600,\n lineHeight: '24px',\n color: theme.palette.text.primary,\n [theme.breakpoints.up('md')]: {\n fontSize: '37px',\n fontWeight: 400,\n lineHeight: '36px',\n letterSpacing: '0.25px',\n },\n },\n cardTitle: {\n fontSize: '22px',\n fontWeight: 400,\n lineHeight: '24px',\n letterSpacing: '0.15px',\n color: theme.palette.text.primary,\n [theme.breakpoints.up('md')]: {\n fontSize: '26px',\n },\n },\n sectionTitle: {\n fontSize: '17px',\n fontWeight: 600,\n lineHeight: '24px',\n letterSpacing: '0.15px',\n color: theme.palette.text.primary,\n [theme.breakpoints.up('md')]: {\n fontSize: '22px',\n },\n },\n subsectionTitle: {\n fontSize: '15px',\n fontWeight: 600,\n lineHeight: '24px',\n letterSpacing: '0.1px',\n color: theme.palette.text.primary,\n [theme.breakpoints.up('md')]: {\n fontSize: '17px',\n letterSpacing: '0.15px',\n },\n },\n subtitle: {\n fontSize: '15px',\n fontWeight: 600,\n lineHeight: '24px',\n letterSpacing: '0.1px',\n color: theme.palette.text.secondary,\n [theme.breakpoints.up('md')]: {\n fontSize: '17px',\n fontWeight: 400,\n letterSpacing: '0.15px',\n },\n },\n mainBody: {\n fontSize: '17px',\n fontWeight: 400,\n color: theme.palette.text.primary,\n lineHeight: '24px',\n letterSpacing: '0.15px',\n },\n secondaryBody: {\n fontSize: '15px',\n fontWeight: 400,\n lineHeight: '20px',\n letterSpacing: '0.25px',\n color: theme.palette.text.secondary,\n },\n lineClamp: (() => {\n if (!lineClamp) return {};\n return {\n ...makeLineClampJss(lineClamp),\n overflow: 'hidden',\n };\n })(),\n preserveWhitespace: (() =>\n preserveWhitespace ? {whiteSpace: 'break-spaces'} : {})(),\n }));\n\nconst componentMap: Record = {\n pageTitle: 'h4',\n cardTitle: 'h5',\n sectionTitle: 'h6',\n subsectionTitle: 'h6',\n subtitle: 'p',\n mainBody: 'p',\n secondaryBody: 'p',\n};\n\ntype MuiTypographyProps = React.ComponentProps;\ntype AllowedMuiTypographyProps = Omit<\n MuiTypographyProps,\n 'classes' | 'variant' | 'color'\n>;\n\nexport type CustomVariant =\n | 'pageTitle'\n | 'cardTitle'\n | 'sectionTitle'\n | 'subsectionTitle'\n | 'subtitle'\n | 'mainBody'\n | 'secondaryBody';\n\ntype TypographyProps = AllowedMuiTypographyProps & {\n variant: CustomVariant;\n lineClamp?: number;\n preserveWhitespace?: boolean;\n};\n\nconst CustomTypography: React.FC = React.forwardRef(\n (\n {variant, lineClamp, preserveWhitespace = false, className, ...props},\n ref\n ) => {\n const [styles, sn] = useResponsiveTypographyStyles({\n lineClamp,\n preserveWhitespace,\n })();\n const isCustom = Boolean(styles[variant]);\n\n return (\n \n );\n }\n);\n\n/**\n * Custom responsive Typography variants for my-dot. Accepts Typography props, plus\n * MUI system props for `palette`, `spacing`, and `breakpoints`. If included,\n * MUI system props will override default styling for Typography variants.\n *\n * Ex: \n *\n * As of 1/31/2024, this is now deprecated. This component is a lot less useful since MUI v5 blessed us\n * with the sx prop. The original idea was to have the product team give us a broader typography system\n * for responsiveness that would be global to everything in my-dot, but in practice they have not shown\n * a broader application of that system in newer designs, so everyone appears to have forgotten about it.\n * @deprecated See above, use MUI Typography\n */\nexport const Typography = styled(CustomTypography)(\n breakpoints(compose(spacing, palette, typography))\n);\n","import {\n AppToSitesMessage,\n SitesToAppMessage,\n} from '@practicegenius/domain/src/sites-mobile-app/messages';\nimport {isClient} from './environment';\n\ndeclare global {\n interface Window {\n ReactNativeWebView?: {\n postMessage: typeof postMessage;\n };\n }\n}\n\nconst USER_AGENT_KEY = 'RewardsHubMobile';\nconst userAgentVersionPattern = `^${USER_AGENT_KEY}\\\\/(?[\\\\d|\\\\.]{5,}).*`;\n\nconst mobileAppVersion = isClient\n ? window.navigator.userAgent.match(new RegExp(userAgentVersionPattern))\n ?.groups?.version\n : null;\n\nexport const inMobileApp = Boolean(mobileAppVersion);\n\n/** If we're in the mobile app, send a post message to it */\nexport const postMessageToMobileApp = (payload: SitesToAppMessage) => {\n if (!inMobileApp) return;\n\n // If we think we're in the mobile app but don't have `ReactNativeWeView`, then\n // we're probably in a testing environment of some sort.\n // In this case, we want to mock the `ReactNativeWebView` object so the UI will\n // work as it does in the mobile app. This also gives us the ability to inspect\n // the messages sent to the mobile app.\n if (!window.ReactNativeWebView) {\n const mockRnWebView = {\n messages: [] as unknown[],\n postMessage: (message: unknown) => mockRnWebView.messages.push(message),\n };\n window.ReactNativeWebView = mockRnWebView;\n }\n\n return window.ReactNativeWebView.postMessage(JSON.stringify(payload));\n};\n\n/** Initial processing steps for message payload from the mobile app */\nexport const parseAppToSitesMessage = (\n payload: any\n): AppToSitesMessage | null => {\n try {\n return JSON.parse(payload);\n } catch (e) {\n return null;\n }\n};\n\n/** Given a URL, generate a click handler that opens the link in an external browser\n * when rendered in the mobile app (and works normally elsewhere) */\nexport const onClickExternalLink =\n (url: string) => (e: React.MouseEvent) => {\n if (!inMobileApp) return;\n\n e.preventDefault();\n e.stopPropagation();\n\n postMessageToMobileApp({\n type: 'request_open_external_url',\n payload: {\n url,\n },\n });\n };\n","/* eslint-disable no-underscore-dangle */\n/**\n * This duplicates a number of environment variables from my-dot because we don't have access to them here.\n * In the future we should consider exporting these and deduplicating my-dot's versions of these.\n *\n * @see apps/my.patientrewardshub.com/src/javascript/config/environment.ts\n */\nexport const isClient = typeof window !== 'undefined';\n\n/**\n * Are we rendering in Kohana?\n */\nexport const isLegacyServer =\n isClient &&\n // @ts-ignore\n window.phpJs;\n\n/**\n * Are we rendering in Next.js?\n */\nexport const isNextServer = !isLegacyServer;\n","import {\n defaultTo,\n ifElse,\n pipe,\n identity,\n always,\n is,\n isNil,\n unless,\n} from 'ramda';\nimport {\n format,\n isSameDay,\n isSameMonth,\n isSameYear,\n isThisYear,\n getMinutes,\n roundToNearestMinutes,\n addMinutes,\n isFuture,\n} from 'date-fns';\nimport {parseISO} from 'date-fns/fp';\nimport {utcToZonedTime, zonedTimeToUtc} from 'date-fns-tz';\nimport {isNotNil} from './TypescriptUtils';\n\ntype FormatOptions = {\n dayOfWeekFmt?: string;\n dayFmt?: string;\n monthFmt?: string;\n yearFmt?: string;\n /** Prevent future dates from showing by limiting the displayed end date to the current date */\n limitEndDate?: boolean;\n};\n\nexport const formatDateRange = (\n startDate: Date | string,\n endDate: Date | string,\n options?: FormatOptions\n) => {\n let isInvalidDate = false;\n const dates = {start: new Date(startDate), end: new Date(endDate)};\n\n if (options?.limitEndDate && isFuture(dates.end)) {\n dates.end = new Date();\n }\n\n const checkDateError = (name: keyof typeof dates) => {\n if (Number.isNaN(dates[name].getDate())) isInvalidDate = true;\n };\n Object.keys(dates).forEach(name =>\n checkDateError(name as keyof typeof dates)\n );\n if (isInvalidDate) return 'Invalid date range';\n\n const startSameYear = isThisYear(dates.start);\n const endSameYear = isThisYear(dates.end);\n const sameYear = isSameYear(dates.start, dates.end);\n const sameMonth = isSameMonth(dates.start, dates.end);\n const sameDay = isSameDay(dates.start, dates.end);\n\n const {\n dayOfWeekFmt = 'EEE, ',\n dayFmt = 'do',\n monthFmt = 'MMM',\n yearFmt = 'yyyy',\n } = options || {};\n\n const startFormatStr = (() => {\n switch (true) {\n case !sameYear:\n return `${dayOfWeekFmt}${monthFmt} ${dayFmt}, ${yearFmt}`;\n case sameYear && sameDay && !startSameYear:\n return `${dayOfWeekFmt}${monthFmt} ${dayFmt}, ${yearFmt}`;\n default:\n return `${dayOfWeekFmt}${monthFmt} ${dayFmt}`;\n }\n })();\n\n const endFormatStr = (() => {\n switch (true) {\n case endSameYear && sameMonth:\n return `${dayFmt}`;\n case endSameYear && !sameMonth:\n return `${monthFmt} ${dayFmt}`;\n case !endSameYear && sameMonth:\n return `${dayFmt}, ${yearFmt}`;\n case !endSameYear && !sameMonth:\n return `${monthFmt} ${dayFmt}, ${yearFmt}`;\n default:\n return '';\n }\n })();\n\n const startText = format(dates.start, startFormatStr);\n const endFormatted = format(dates.end, endFormatStr);\n const endText = sameDay ? '' : ` - ${endFormatted}`;\n\n return startText + endText;\n};\n\n/**\n * @deprecated use format() directly with a CommonDateFormat\n */\nexport const formatSingleDate = (date: Date) =>\n Number.isNaN(date.getDate())\n ? 'Invalid date'\n : format(date, `EEE, MMM do, yyyy`);\n\n/**\n * @deprecated It turns out that this just doesn't work as expected. Better to explicitly use `format` from date-fns-tz and specify the expected timezone\n * @see https://date-fns.org/v2.16.1/docs/Time-Zones\n */\nexport const userZonedTimeToUtc = (\n time: string | number | Date,\n userTimeZone: string = Intl.DateTimeFormat().resolvedOptions().timeZone\n) => zonedTimeToUtc(time, userTimeZone);\n\n/**\n * NOTE: This should _only_ be used if the provided date string is not provided in ISO format.\n * If the date is provided in ISO format, then parseISO is strictly superior to this helper.\n */\nexport const utcToUserZonedTime = (\n time: string | number | Date,\n userTimeZone: string = Intl.DateTimeFormat().resolvedOptions().timeZone\n) => utcToZonedTime(time, userTimeZone, {timeZone: 'UTC'});\n\nexport const CommonDateFormats = {\n 'Mon, Jan 20': 'eee, LLL d',\n 'Mon, Jan 20, 2020': 'eee, LLL d, yyyy',\n 'Jan 20, 2020': 'LLL d, yyyy',\n '20 Jan, 2020': 'd LLL, yyyy',\n '1/5/2020': 'M/d/yyyy',\n '01/20/2020': 'MM/dd/yyyy',\n '20/01/2020': 'dd/MM/yyyy',\n '2020-01-20': 'yyyy-MM-dd',\n '2020-01-20 23:59:59': 'yyyy-MM-dd HH:mm:ss',\n '2020-01-20T01:59:00-0800': `yyyy-MM-dd'T'HH:mm:ssxx`,\n 'Jan 20, 2020 1:59pm': 'LLL d, yyyy h:mmaaa',\n 'Saturday, Sep 27, 2023': 'EEEE, LLL d, yyyy',\n};\n\nconst isValidDate = (date: Date) => !Number.isNaN(date.getTime());\nexport const parseIsoOrNull: (\n date: string | Date | null | undefined\n) => Date | null = ifElse(\n isNotNil,\n pipe(\n // @ts-expect-error\n ifElse(is(Date), identity, parseISO),\n ifElse(isValidDate, identity, always(null))\n ),\n defaultTo(null)\n);\n\n/** Works like roundToNearestMinutes in date-fns, but always rounds up (including values that line up perfectly with the step) */\nexport const getNextDateInStepMinutes = (\n date: Date,\n /** Step between dates in minutes */\n step: number\n) => {\n const currentMinute = getMinutes(date);\n return roundToNearestMinutes(\n addMinutes(\n currentMinute % step === 0 ? addMinutes(date, 1) : date,\n step / 2\n ),\n {nearestTo: step}\n );\n};\n\n/**\n * A dependency-free function to check if a value is Moment\n */\nexport const isMoment = (value: unknown) =>\n typeof value === 'object' &&\n value != null &&\n '_isAMomentObject' in value &&\n // @ts-ignore\n value._isAMomentObject != null;\n\n/** Parse a date from an API response */\nexport const parseNullableDate = unless(isNil, parseISO);\n","import React from 'react';\n\n/**\n * Retrieves input data from a form and returns it as a JSON object.\n * https://learnwithjason.dev/blog/get-form-values-as-json/\n */\nexport const formToJSON = (elements: HTMLFormElement): Record =>\n [].reduce.call(\n elements,\n (data, element: {name: string; value: string}) => {\n // @ts-ignore 3rd party code\n (data as Record)[element.name] = element.value;\n return data;\n },\n {}\n ) as Record;\n\nconst injectedScriptCache: string[] = [];\n\nconst injectScript = (src: string): Promise => {\n return new Promise((resolve, reject) => {\n if (injectedScriptCache.includes(src)) {\n return resolve();\n }\n\n injectedScriptCache.push(src);\n\n const script = document.createElement('script');\n script.onload = () => resolve();\n script.onerror = reject;\n script.src = src;\n document.head.appendChild(script);\n });\n};\n\n/**\n * Asyncronously insert script tags into the global document header.\n *\n * @param {string[]} sources\n */\nexport const injectScripts = async (sources: string[]): Promise => {\n await Promise.all(sources.map(src => injectScript(src)));\n};\n\n/**\n * Creates JSS for allowing a certain number of lines then truncating it\n * @param lines\n */\nexport const makeLineClampJss = (lines: number) =>\n ({\n display: '-webkit-box !important',\n WebkitLineClamp: lines,\n WebkitBoxOrient: 'vertical',\n } as const);\n\n/**\n * Use a Typography element from pg-ui.\n * Pass ref={textRef} and lineClamp={clampHeight} into the Typography element.\n * Pass toggleExpanded as your Show More/Less button's action.\n */\nexport const useShowMore = (lineClamp = 2, hasDynamicText = false) => {\n const [showExpandLink, setShowExpandLink] = React.useState(false);\n const [expanded, setExpanded] = React.useState(false);\n const textRef = React.useRef(null);\n const toggleExpanded = () => setExpanded(!expanded);\n const clampHeight = expanded ? 1000 : lineClamp;\n\n React.useEffect(\n () => {\n if (textRef?.current) {\n return textRef.current.scrollHeight > textRef.current.clientHeight\n ? setShowExpandLink(true)\n : setShowExpandLink(false);\n }\n },\n // to allow an initially hidden \"more\" button to display after first mount\n // useful for builder previews where element content is dynamic\n hasDynamicText ? undefined : []\n );\n return {textRef, showExpandLink, expanded, toggleExpanded, clampHeight};\n};\n","import * as R from 'ramda';\nimport {isNotNil} from './TypescriptUtils';\n\n/**\n * A transparent wrapper around R.pipe that's slightly less annoying to use in typescript\n * It allows you to directly specify the return (and arument) for the generated function,\n * and does no type checking on the in-between functions.\n */\nexport const pipe = (...fns: Function[]) =>\n R.pipe(\n // @ts-ignore\n ...fns\n ) as (x: TIn) => TOut;\n\n/**\n * Takes an array of functions and passes the same payload to each.\n * It will stop and return the value of any method that returns\n * something that is not nil.\n */\nexport const applyUntilNonNil =\n (fns: Array<(x: any) => T | null | undefined>) =>\n (value: any) => {\n // Iterate over functions and apply them to the value\n for (const fn of fns) {\n const result = fn(value);\n // Return the result if it is non-nil\n if (isNotNil(result)) {\n return result;\n }\n }\n // Return nil if no non-nil result is found\n return null;\n };\n","import camelCase from 'lodash/camelCase';\nimport snakeCase from 'lodash/snakeCase';\nimport kebabCase from 'lodash/kebabCase';\nimport * as R from 'ramda';\n\n/**\n * Transforms the keys of an object recursively\n * @source https://github.com/ramda/ramda/wiki/Cookbook#camelizekeys\n */\nconst transformObjectKeysDeep = R.curry(\n (\n transform: (s: string) => string,\n obj: Record\n ): Record =>\n // @ts-ignore\n R.cond([\n [\n R.is(Array),\n R.map(transformObjectKeysDeep(transform) as (obj: unknown) => unknown),\n ],\n [R.is(Function), R.identity],\n [\n R.is(Object),\n // @ts-ignore\n R.pipe(\n R.toPairs,\n // @ts-ignore Typedef issue in lib: tests prove this works\n R.map(\n R.juxt([\n R.o(transform, R.head),\n // @ts-expect-error\n R.o(transformObjectKeysDeep(transform), R.last),\n ])\n ),\n R.fromPairs\n ),\n ],\n [R.T, R.identity],\n // @ts-ignore\n ])(obj) as Record\n);\n\n/**\n * Camelcases the keys of an object only one level deep\n */\nexport const objectKeysToCamelCase = (\n obj: Record\n): Record =>\n Object.entries(obj).reduce(\n (acc, [k, v]) => ({\n ...acc,\n [camelCase(k)]: v,\n }),\n {}\n );\n\n/**\n * Camelcases the keys of an object recursively\n */\nexport const objectKeysToCamelCaseDeep: typeof objectKeysToCamelCase =\n transformObjectKeysDeep(camelCase);\n\nexport const objectKeysToSnakeCase = (\n obj: Record\n): Record =>\n Object.entries(obj).reduce(\n (acc, [k, v]) => ({\n ...acc,\n [snakeCase(k)]: v,\n }),\n {}\n );\n\n/**\n * Snakecases the keys of an object recursively\n */\nexport const objectKeysToSnakeCaseDeep: typeof objectKeysToSnakeCase =\n transformObjectKeysDeep(snakeCase);\n\nexport const objectKeysToKebabCase = (\n obj: Record\n): Record =>\n Object.entries(obj).reduce(\n (acc, [k, v]) => ({\n ...acc,\n [kebabCase(k)]: v,\n }),\n {}\n );\n\nexport const objectKeysToKebabCaseDeep: typeof objectKeysToKebabCase =\n transformObjectKeysDeep(kebabCase);\n\n/**\n * Drop keys in an object that are either null, undefined, or empty\n */\nexport const dropNilOrEmptyValues = R.reject(R.either(R.isEmpty, R.isNil));\n\n/**\n * Renames an object key\n *\n * @see https://github.com/ramda/ramda/wiki/Cookbook#rename-key-of-an-object\n */\nexport const renameKey = R.curry(\n (oldKey: string, newKey: string, obj: Record) =>\n R.assoc(newKey, R.prop(oldKey, obj), R.dissoc(oldKey, obj))\n);\n\n/** Rename multiple keys in an object. Keymap is in format [oldKey, newKey] */\nexport const renameKeys = R.curry(\n (keymap: [string, string][], obj: Record) => {\n const renameFns = keymap.map(R.apply(renameKey));\n // @ts-ignore\n return R.pipe(...renameFns)(obj);\n }\n);\n\n/** Returns a partial version of T that contains only the fields that vary between the two */\nexport const getObjectDiff = >(\n newObj: T,\n oldObj: T\n): Partial =>\n R.pickBy((value, key) => !R.equals(value, oldObj[key]), newObj);\n","/** @deprecated Just use the language */\nexport const isUndefined = (x: T | undefined): x is undefined =>\n x === undefined;\n/** @deprecated Just use the language */\nexport const isNotUndefined = (x: T | undefined): x is T => !isUndefined(x);\n\n/** @deprecated Just use the language */\nexport const isNull = (x: T | null): x is null => x === null;\n/** @deprecated Just use the language */\nexport const isNotNull = (x: T | null): x is T => !isNull(x);\n\nexport type Nil = undefined | null;\nexport const isNotNil = (x: T | Nil): x is T =>\n isNotUndefined(x) && isNotNull(x);\nexport const isNil = (x: T | Nil): x is Nil => !isNotNil(x);\n\nexport const voidOp = (): void => void 0;\n\n/** Expect that the given value is a `never`. This will always throw a runtime error.\n * This is commonly used as the default case handler in an exhasutive switch statement.\n */\nexport function assertNever(x: never): never {\n throw new Error(`Unexpected object: ${x}`);\n}\n\n/** Expect that the given value is a `never`, but do not throw.\n * This is a compile-time only check and should be paired with some type of runtime action */\nexport const assertNeverWeak = (x: never): void => void 0;\n\n/**\n * Makes optional members of an object type non-optional\n * https://github.com/microsoft/TypeScript/issues/28374#issuecomment-536521051\n */\nexport type DeepNonNullable = {\n [P in keyof T]-?: NonNullable;\n};\n\n/** Makes fields of an object T given in Ks nonnull */\nexport type WithNonNullKeys = {\n [K in keyof T]-?: K extends Ks ? NonNullable : T[K];\n};\n\n/**\n * Make optional members of an object required\n */\nexport type Require<\n Props extends object,\n Keys extends keyof Props = keyof Props\n> = Prettify & Required>>;\n\n/** Makes required members of an object optional */\nexport type WithPartial<\n Props extends Object,\n Keys extends keyof Props = keyof Props\n> = Prettify & Partial>>;\n\n/**\n * Like Partial, but deep\n * @see https://stackoverflow.com/a/61132308/11882366\n */\nexport type DeepPartial = {\n [P in keyof T]?: DeepPartial;\n};\n\n/**\n * Makes specified members of an object required and the rest optional.\n * Useful for keeping the type intact while making a few fields required.\n * @see https://stackoverflow.com/questions/69327990\n */\nexport type PartialRequire = Partial &\n Required>;\n\n/**\n * A silly function that returns the input passed to the second function as the given type\n * This is useful in ad-hoc function compositions with Ramda, since its type-defs are far from perfect\n * It has the weird thunkify-d signature because you can't use generics on a point-free function\n */\nexport const setType =\n () =>\n (x: unknown) =>\n x as T;\n\n/**\n * Make complex intersection types easier to read in intellisense\n * @see https://twitter.com/mattpocockuk/status/1622730173446557697\n */\nexport type Prettify = {\n [K in keyof T]: T[K];\n} & {};\n\n/**\n * Turns a value into any\n * @deprecated only used to make legacy modules fit TS without no-checking the whole file */\nexport const anyifyValue = (x: T): any => x;\n\n/**\n * Turns any function into a function that accepts and returns any\n * @deprecated only used to make legacy modules fit TS without no-checking the whole file */\nexport const anyifyFn = any>(x: T): any => x;\n\n/** Branded type implementation borrowed from egghead.io\n * @see https://egghead.io/blog/using-branded-types-in-typescript\n */\ndeclare const __brand: unique symbol;\ntype Brand = {[__brand]: B};\n/** Create a branded type */\nexport type Branded = T & Brand;\n\n/** Unpacks an array type */\nexport type Unpacked = T extends (infer U)[] ? U : T;\n\n/** Used for array types that can not be empty */\nexport type NonEmptyArray = [T, ...T[]];\n"],"names":["module","exports","PG_CORE_URL","PG_COMM_URL","MY_DOT_URL","PRH","HUBBUX","CULTURELLO","SANITY_URL","FILES_URL","BASE_URL","ASSETS_URL","GOOGLE_MAPS_KEY","PUSHER_KEY","PUSHER_CLUSTER","GOOGLE_RECAPTCHA_SITE_KEY","GIPHY_API_KEY","AuthenticationContext","isAuthenticated","useIsAuthenticated","AuthenticationContextProvider","children","Provider","value","Wrapper","styled","theme","margin","spacing","display","alignItems","flexDirection","CatastrophicErrorScreen","align","variant","SNACKBAR_ROOT_ID","SnackbarProvider","rootEl","setRootEl","root","document","querySelector","createElement","setAttribute","body","append","anchorOrigin","horizontal","vertical","domRoot","autoHideDuration","sharedQueryClient","renderedDevTools","SingletonReactQueryDevtools","buttonPosition","StandardCatastrophicErrorBoundary","appName","showError","CatastrophicErrorBoundary","errorLogMessage","logger","errorNode","SharedProvider","showErrorMessage","QueryClientProvider","client","UnauthenticatedStandardProvider","breakpoint","withUnauthenticatedStandardProvider","providerProps","Inner","props","StandardProvider","AuthApiProvider","UserProfileProvider","withStandardProvider","Context","SpinnerRoot","justifyContent","useUserProfile","ctx","Error","redirectOnError","profileQuery","status","data","window","location","href","retryFn","refetch","userProfileQueryKey","useUserProfileQuery","globalUserCoreAuth","queryKey","queryFn","then","profile","practiceRecord","practiceRecords","type","payload","notificationCounts","cookie","Intl","NumberFormat","format","points","staleTime","useInvalidateUserProfileQuery","queryClient","invalidateQueries","useUpdatePrivacyPreferences","updateUserProfile","updater","setQueryData","useUpdateUserProfileQueryData","enqueueSnackbar","mutationFn","preferenceData","_unsafe","post","onMutate","key","cancelQueries","previousUserProfile","getQueryData","onSuccess","_","onError","__","context","PUSHER_HOST","__TEST__","STORYBOOK_ENV","__HACKY_GLOBAL_USER_JWT","NextApiContext","NextGlobalUserAuthApiContext","sitesHttpClient","headers","transformRequest","stringify","useApiClients","Promise","all","coreJwt","globalUserJwt","token","coreAuth","baseURL","authToken","decodedToken","useGlobalUserApi","nextGlobalUserApiCtx","useApi","nextApiCtx","UnauthenticatedError","constructor","response","super","name","this","NotFoundError","ValidationError","errors","AccountRegisteredError","message","hint","SocialAccountRegisteredError","rethrowValidationErrors","transformErrors","error","InternalServerError","BadResponseError","TimeoutError","RateLimitError","handleHTTPErrors","interceptors","use","err","code","REQUEST_TIMEOUT_LENGTH","httpClient","config","timeout","pgCoreNoAuth","sitesDot","handleJwtError","includes","requestJwt","catch","requestGlobalJwt","refreshJwt","refreshToken","refresh_token","refreshSession","registerDeviceNotificationToken","deviceType","previousTokens","previous_tokens","unregisterDeviceNotificationToken","markContentShared","shareCode","FALLBACK_UNAUTH_COLOR","baseMembersThemeOptions","breakpoints","unit","values","xs","sm","md","lg","xl","typography","fontFamily","join","fontSize","palette","primary","main","contrastText","secondary","warning","action","hoverOpacity","focusOpacity","components","MuiFormControl","defaultProps","fullWidth","size","MuiInputBase","styleOverrides","color","borderRadius","opacity","MuiTextField","MuiFormLabel","textTransform","MuiButton","MuiIconButton","MuiLink","textDecoration","themePalette","blue","orange","green","red","purple","grey","themeColorMapping","getExpandedPaletteForColor","dark","light","sitesDotThemeOptions","createTheme","createSitesTheme","atBreakpoint","themeId","paletteOverride","baseThemeOptions","memberThemeColors","colors","getColorsForMemberThemeId","sitesDotTheme","unauthThemeColors","bodyEl","makeResult","primaryColor","getComputedStyle","getPropertyValue","trim","secondaryColor","ServiceBrand","select","prh","hubbux","culturello","unauthThemeOverrides","overrides","reduce","UnauthenticatedThemeProvider","practiceColors","color1","color8","AuthenticatedThemeProvider","user","getAtomicElements","Array","from","querySelectorAll","atomicUpdate","forEach","el","innerText","atomicUpdateImg","src","HTMLImageElement","current","host","replace","patientrewardshub","lang","practiceNoun","hubProduct","appUrlAndroid","appUrlIos","myDotUrl","googleRecaptchaSiteKey","criteria","level","Object","freeze","debug","info","critical","_window","Rollbar","transformCommonTimestamps","createdAt","updatedAt","transformIncomingGlobalUserProfile","birthdate","lastLoginAt","registrationCompletedAt","transformGlobalUserAddresses","transformGlobalUserContact","transformGlobalUserPractice","transformGlobalUserSocialAccount","userProfileIncludeTransformSpec","contacts","practices","indexedNotificationCounts","map","rawPracticeRecord","rawPracticeNotificationCountsRecord","id","joinedAt","startedAt","parents","siblings","parentContacts","childContacts","siblingContacts","addresses","socialAccounts","hubSettings","acc","setting","theme_id","Number","transformFullUserProfile","transformSpec","makeGlobalUserProfileTransfomer","keys","profileIncludes","fetchGlobalUserProfile","authorizedApiClient","get","params","include","getUserDisplayEmail","emails","primaryEmail","find","c","subType","responsibleEmail","contact","responsible","getGlobalUserEmails","decodeIncomingJwt","encoded","atob","decodeJwt","jwt","segments","split","length","JSON","parse","tokenToAuth","userId","sub","userType","subtype","practiceId","pid","timezone","zoneinfo","validateBirthDate","Date","isChild","now","isTeen","isAdult","handleHTTPErrorsUnsafely","makeErrResult","respError","errResult","mapData","resultifyResponse","responseOrErrorOrException","kind","getResponseError","okResult","ok","mapper","makeOkResult","addDefaultResponseTransformer","cfg","transformResponse","resultifyClientInstance","safeInstance","url","delete","head","options","put","patch","makeNoAuthApiClient","unsafeInstance","validateStatus","makeAuthApiClient","clientConfig","_auth","makeAxiosConfig","Authorization","bindRequestSpecLogger","instance","logForConfig","method","reqData","requestSpec","query","reply","console","log","process","env","LOG_REQUEST_SPEC","localStorage","getItem","createSafeInstance","makeNilApiClient","handler","resolve","UnauthenticatedException","NotFoundException","ValidationException","InternalServerException","BadResponseException","TimeoutException","RateLimitException","ApiErrorKind","useIsNextJs","useRouter","e","ButtonHeight","ButtonWidth","heightMap","SHORT","NORMAL","MEDIUM","TALL","widthMap","NARROW","WIDE","FULL_WIDTH","ELASTIC","ButtonVariant","muiColors","getBackgroundForBlank","bgFunctions","text","outlined","contained","base","overlay","StyledButton","width","transition","HideButtonText","visibility","Spinner","Button","ref","height","loading","loadingIndicatorColor","disabled","uppercase","otherProps","colorAsMui","parseMuiColor","styles","sn","hasThemeColor","styleColors","getContrastText","hoverBgArgs","focusBgArgs","bgFn","hoverBg","focusBg","backgroundColor","borderColor","common","black","noTransform","spinnerContainer","position","left","top","makeUseStyles","ButtonTextWrapper","disableFocusRipple","disableRipple","sx","success","autofillShadow","defaultFocusStyle","outline","commonPopoverPositioning","transformOrigin","defaultThemeOptions","MuiOutlinedInput","padding","input","WebkitBoxShadow","boxShadow","adornedStart","marginLeft","adornedEnd","marginRight","MuiAutocomplete","listbox","maxHeight","MuiModal","backdropFilter","MuiTableHead","fontWeight","MuiDialog","paperFullScreen","paddingTop","paddingBottom","borderBottom","MuiFab","marginBottom","MuiCardActionArea","MuiButtonBase","MuiCheckbox","MuiMenu","MuiSelect","MenuProps","onKeyDown","keyCode","target","click","MuiTabs","up","minWidth","MuiPopover","MuiDataGrid","border","white","columnHeaderRow","background","toolbarContainer","paddingLeft","paddingRight","filterForm","maxWidth","filterFormDeleteIcon","filterFormValueInput","marginTop","virtualScrollerContent","minHeight","row","borderTop","cell","columnHeader","defaultThemeOptionsAtBreakpoint","MuiWithWidth","initialWidth","defaultTheme","cache","stylisPlugins","scopes","createExtraScopePlugin","scope","element","prop","scopesArray","concat","ThemeProvider","C","getButtonBackgroundColorStyles","adjustMode","adjustFn","normalizeAlpha","overlayColor","baseColor","add","alpha","calcIndex","i","Math","round","makeSxStyles","makeStyles","composeSx","args","sxs","processArg","arg","push","isArray","makeComposeSx","state","hasError","getDerivedStateFromError","componentDidCatch","errorInfo","render","Deferred","forMs","setRender","setTimeout","clearTimeout","FetchFailureMessage","messageBody","A","severity","onClick","m","mt","componentMap","pageTitle","cardTitle","sectionTitle","subsectionTitle","subtitle","mainBody","secondaryBody","CustomTypography","lineClamp","preserveWhitespace","className","lineHeight","letterSpacing","overflow","whiteSpace","useResponsiveTypographyStyles","isCustom","Boolean","component","Typography","mobileAppVersion","navigator","userAgent","match","RegExp","groups","version","inMobileApp","postMessageToMobileApp","ReactNativeWebView","mockRnWebView","messages","postMessage","parseAppToSitesMessage","onClickExternalLink","preventDefault","stopPropagation","isClient","phpJs","formatDateRange","startDate","endDate","isInvalidDate","dates","start","end","limitEndDate","isNaN","getDate","checkDateError","startSameYear","endSameYear","sameYear","sameMonth","sameDay","dayOfWeekFmt","dayFmt","monthFmt","yearFmt","startFormatStr","endFormatStr","startText","endFormatted","utcToUserZonedTime","time","userTimeZone","DateTimeFormat","resolvedOptions","timeZone","utcToZonedTime","CommonDateFormats","parseIsoOrNull","date","getTime","getNextDateInStepMinutes","step","currentMinute","nearestTo","parseNullableDate","makeLineClampJss","lines","WebkitLineClamp","WebkitBoxOrient","useShowMore","hasDynamicText","showExpandLink","setShowExpandLink","expanded","setExpanded","textRef","clampHeight","scrollHeight","clientHeight","toggleExpanded","pipe","fns","transformObjectKeysDeep","transform","obj","Function","objectKeysToCamelCase","entries","k","v","objectKeysToCamelCaseDeep","objectKeysToSnakeCase","objectKeysToSnakeCaseDeep","objectKeysToKebabCase","dropNilOrEmptyValues","renameKey","oldKey","newKey","renameKeys","keymap","renameFns","isUndefined","x","isNotUndefined","isNull","isNotNull","isNotNil","isNil","voidOp","assertNever","setType"],"sourceRoot":""}