{"version":3,"file":"LazyUtilityPage.507dbd0afa5e4be9.prod.js","mappings":"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","sources":["webpack://aurora-new-frontend/./packages/common/packages/core/src/utils/formatOrFallback.ts","webpack://aurora-new-frontend/./packages/common/packages/core/src/hooks/use-tenant-currency/use-tenant-currency.generated.tsx","webpack://aurora-new-frontend/./node_modules/@apollo/client/react/hooks/useLazyQuery.js","webpack://aurora-new-frontend/./packages/common/packages/core/src/hooks/use-tenant-currency/use-tenant-currency.ts","webpack://aurora-new-frontend/./packages/common/packages/core/src/hooks/use-locale-format/use-locale-format.ts","webpack://aurora-new-frontend/./packages/lead-capture/src/pages/utility/utility.generated.tsx","webpack://aurora-new-frontend/./packages/lead-capture/src/shared-components/lcai-slider.tsx","webpack://aurora-new-frontend/./packages/lead-capture/src/pages/utility/components/utility-slider.tsx","webpack://aurora-new-frontend/./packages/lead-capture/src/pages/utility/utility-page.tsx","webpack://aurora-new-frontend/./packages/lead-capture/src/utils/image-matcher.tsx","webpack://aurora-new-frontend/./packages/lead-capture/src/shared-components/image.tsx"],"sourcesContent":["/**\n * Will format a value when it is not null/undefined. If it is null/undefined it will return the fallback.\n */\nexport const formatOrFallback = (\n value: Value,\n format: (value: NonNullable) => ReturnType,\n fallback: ReturnType,\n) => (value == null ? fallback : format(value!));\n\nexport const NOT_APPLICABLE = 'N/A';\n\nexport const formatOrNA = (value: T, format: (value: NonNullable) => string) =>\n formatOrFallback(value, format, NOT_APPLICABLE);\n","// @ts-ignore: Ignore unused { * as Types } import\nimport * as Types from '@aurorasolar/graphql-client-schema';\n\nimport { gql } from '@apollo/client';\nimport * as Apollo from '@apollo/client';\nconst defaultOptions = {} as const;\nexport type GetTenantCurrencyQueryVariables = Types.Exact<{ [key: string]: never; }>;\n\n\nexport type GetTenantCurrencyQuery = { __typename: 'Query', currentTenant?: { __typename: 'Tenant', id: string, currency?: Types.CurrencyTypes | null | undefined } | null | undefined };\n\n\nexport const GetTenantCurrencyDocument = gql`\n query GetTenantCurrency @trace_info(traceInfo: {pod: platformEnablement}) {\n currentTenant {\n id\n currency\n }\n}\n `;\n\n/**\n * __useGetTenantCurrencyQuery__\n *\n * To run a query within a React component, call `useGetTenantCurrencyQuery` and pass it any options that fit your needs.\n * When your component renders, `useGetTenantCurrencyQuery` returns an object from Apollo Client that contains loading, error, and data properties\n * you can use to render your UI.\n *\n * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;\n *\n * @example\n * const { data, loading, error } = useGetTenantCurrencyQuery({\n * variables: {\n * },\n * });\n */\nexport function useGetTenantCurrencyQuery(baseOptions?: Apollo.QueryHookOptions) {\n const options = {...defaultOptions, ...baseOptions}\n return Apollo.useQuery(GetTenantCurrencyDocument, options);\n }\nexport function useGetTenantCurrencyLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) {\n const options = {...defaultOptions, ...baseOptions}\n return Apollo.useLazyQuery(GetTenantCurrencyDocument, options);\n }\nexport type GetTenantCurrencyQueryHookResult = ReturnType;\nexport type GetTenantCurrencyLazyQueryHookResult = ReturnType;\nexport type GetTenantCurrencyQueryResult = Apollo.QueryResult;","import { useBaseQuery } from \"./utils/useBaseQuery.js\";\nexport function useLazyQuery(query, options) {\n return useBaseQuery(query, options, true);\n}\n//# sourceMappingURL=useLazyQuery.js.map","import { useEffect } from 'react';\n\nimport { tokens, useAppModule } from '@aurorasolar/common-module-loader';\n\nimport { CurrencyTypes } from '../../constants';\nimport { useGetTenantCurrencyLazyQuery } from './use-tenant-currency.generated';\n\nexport const useTenantCurrency = ({ skip } = { skip: false }) => {\n const client = useAppModule(tokens.ApolloClient);\n\n // HACK: The lazy query allows ApolloClient to be undefined during tests\n const [loadQuery, { data }] = useGetTenantCurrencyLazyQuery();\n\n useEffect(() => {\n if (!skip && client) {\n loadQuery();\n }\n }, [client, loadQuery, skip]);\n\n return { currency: data?.currentTenant?.currency ?? CurrencyTypes.Usd };\n};\n","import * as DS from '@aurorasolar/ds';\nimport { IIntlContext, formatNumberFactory, useIntl } from '@aurorasolar/intl';\n\nimport { CurrencyTypes } from '../../constants';\nimport { formatOrFallback } from '../../utils';\nimport { useTenantCurrency } from '../use-tenant-currency/use-tenant-currency';\n\n// TODO: move into @aurorasolar/common-localization\n\nexport interface EnergyFormatOptions {\n unit?: string;\n maximumFractionDigits?: number;\n minimumFractionDigits?: number;\n fallback?: string;\n}\n\nexport type LocaleFormatCurrencyFn = (\n value?: number | null,\n options?: {\n /** Content presented when `value` is nullish, defaults to a single dash. */\n fallback?: string;\n /** Lowest allowed precision, defaults to 2 digits. */\n minimumFractionDigits?: number;\n /** Greatest allowed precision, defaults to 2 digits. */\n maximumFractionDigits?: number;\n /**\n * - `undefined` (default) → use locale defaults and don't mess with currency decimals\n * - `\"highPrecision\"` → up to 4 decimal places (PPW, $/kWh, non-homeowner facing)\n * - `\"maxPrecision\"` → up to 15 decimal places (raw PPW input and display with arbitrary precision)\n *\n * **Why is this needed?**\n * Currency formatters always round up for greater than 2-decimal precision, so these\n * presets override the default behavior and ensure the desired level of precision.\n */\n preset?: 'highPrecision' | 'maxPrecision';\n /**\n * Rarely used, but for some edge cases if a number is too large it can cause UI\n * issues. Replicates the former `formatCurrencyWithDroppedCents` formatter function.\n */\n truncatePrecisionGTEValue?: number;\n },\n) => string;\n\nexport type LocaleFormatEnergyFn = (value: number | null, options?: EnergyFormatOptions) => string;\n\nexport type LocaleFormatListFn = (\n arr: React.ReactNode[],\n options?: Intl.ListFormatOptions,\n) => React.ReactNode[];\n\nexport type LocaleFormatPercentFn = (\n value?: number | null | undefined,\n options?: Intl.NumberFormatOptions,\n) => string;\n\nconst formatCurrencyFactory = (\n formatNumber: IIntlContext['formatNumber'],\n currency: CurrencyTypes,\n): LocaleFormatCurrencyFn => {\n return (\n value?: number | null,\n {\n fallback = DS.FALLBACK_PLACEHOLDER_STRING,\n minimumFractionDigits,\n maximumFractionDigits,\n preset,\n truncatePrecisionGTEValue = Number.POSITIVE_INFINITY,\n } = {},\n ) => {\n return formatOrFallback(\n value,\n (val) => {\n const baseFormattingOptions: Intl.NumberFormatOptions = {\n currency,\n maximumFractionDigits:\n (value ?? 0) >= truncatePrecisionGTEValue ? 0 : maximumFractionDigits,\n minimumFractionDigits,\n style: 'currency',\n };\n\n switch (preset) {\n case 'maxPrecision': {\n return formatNumber(val, { ...baseFormattingOptions, maximumFractionDigits: 15 });\n }\n\n case 'highPrecision': {\n return formatNumber(val, { ...baseFormattingOptions, maximumFractionDigits: 4 });\n }\n\n default:\n return formatNumber(val, baseFormattingOptions);\n }\n },\n fallback,\n );\n };\n};\n\nexport const generateCurrencyFormatter = (\n locale: IIntlContext['locale'],\n currency: CurrencyTypes,\n): LocaleFormatCurrencyFn => {\n return formatCurrencyFactory(formatNumberFactory(locale), currency);\n};\n\nexport type LocaleFormatBag = IIntlContext & {\n currency: CurrencyTypes;\n /** Meant for composition with DS.NumericInput `prefix` field. */\n currencyPrefix: string;\n /** Meant for composition with DS.NumericInput `suffix` field. */\n currencySuffix: string;\n currencySymbol: string;\n formatCurrency: LocaleFormatCurrencyFn;\n formatDateTime: (date: string | Date | number, options?: Intl.DateTimeFormatOptions) => string;\n formatEnergy: LocaleFormatEnergyFn;\n formatHour: (hour: number, options?: { hour12: boolean }) => string;\n formatLatLong: (value?: number | null, fallback?: string) => string;\n formatList: LocaleFormatListFn;\n formatPercent: LocaleFormatPercentFn;\n /** Meant for composition with DS.NumericInput `prefix` field. */\n percentPrefix: string;\n /** Meant for composition with DS.NumericInput `suffix` field. */\n percentSuffix: string;\n percentSymbol: string;\n toFixed: (\n value?: number | null,\n minimumFractionDigits?: number,\n maximumFractionDigits?: number,\n fallback?: string,\n ) => string;\n};\n\n/**\n * To avoid recomputing the formatters object every time the hook is composed,\n * cache the result to a Map.\n */\nconst formatterCache = new Map();\n\nfunction getLocaleBag(intl: IIntlContext, currency: CurrencyTypes): LocaleFormatBag {\n const key = intl.locale + intl.stringLocale + currency;\n\n if (!formatterCache.has(key)) {\n const currencyParts = new Intl.NumberFormat(intl.locale, {\n currency,\n currencyDisplay: 'narrowSymbol',\n style: 'currency',\n }).formatToParts(1);\n\n const currencyValueIndex = currencyParts.findIndex((x) => x.type === 'integer');\n const currencySymbolIndex = currencyParts.findIndex((x) => x.type === 'currency');\n const currencySymbol = currencyParts[currencySymbolIndex].value;\n\n // TODO: RTL handling (maybe use rtl-detect library)\n const currencySymbolIsSuffix = currencySymbolIndex > currencyValueIndex;\n\n const percentParts = new Intl.NumberFormat(intl.locale, { style: 'percent' }).formatToParts(1);\n\n const percentValueIndex = percentParts.findIndex((x) => x.type === 'integer');\n const percentSymbolIndex = percentParts.findIndex((x) => x.type === 'percentSign');\n const percentSymbol = percentParts[percentSymbolIndex].value;\n\n // TODO: RTL handling (maybe use rtl-detect library)\n const percentSymbolIsSuffix = percentSymbolIndex > percentValueIndex;\n\n formatterCache.set(key, {\n ...intl,\n currency,\n /** Meant for composition with DS.NumericInput `prefix` field. */\n currencyPrefix: currencySymbolIsSuffix ? '' : currencySymbol,\n /** Meant for composition with DS.NumericInput `suffix` field. */\n currencySuffix: currencySymbolIsSuffix ? currencySymbol : '',\n currencySymbol,\n formatCurrency: formatCurrencyFactory(intl.formatNumber, currency),\n formatDateTime: (date, options) => intl.formatDateTime(new Date(date), options),\n // TODO: This should use the same formatting logic as in\n // @aurorasolar/common-core/src/utils/formatWattage.ts\n formatEnergy: (\n value,\n {\n unit = 'kWh',\n maximumFractionDigits = 2,\n minimumFractionDigits = 0,\n fallback = DS.FALLBACK_PLACEHOLDER_STRING,\n } = {},\n ) =>\n formatOrFallback(\n value,\n (val) =>\n `${intl.formatNumber(val, {\n maximumFractionDigits:\n maximumFractionDigits > minimumFractionDigits\n ? maximumFractionDigits\n : minimumFractionDigits,\n minimumFractionDigits,\n })} ${unit}`,\n fallback,\n ),\n formatHour: (hour, options) => {\n if (!options?.hour12) {\n return hour < 10 ? `0${hour}:00` : `${hour}:00`;\n }\n switch (true) {\n case hour === 0:\n return '12 am';\n case hour < 12:\n return `${hour} am`;\n case hour === 12:\n return '12 pm';\n case hour > 12:\n default:\n return `${hour - 12} pm`;\n }\n },\n formatLatLong: (value, fallback = DS.FALLBACK_PLACEHOLDER_STRING) =>\n formatOrFallback(\n value,\n (val) => intl.formatNumber(val, { maximumFractionDigits: 3, minimumFractionDigits: 3 }),\n fallback,\n ),\n formatPercent: (value, options) =>\n formatOrFallback(\n value,\n (val) =>\n intl.formatNumber(val, {\n maximumFractionDigits: 2,\n minimumFractionDigits: 2,\n style: 'percent',\n ...options,\n }),\n DS.FALLBACK_PLACEHOLDER_STRING,\n ),\n /** Meant for composition with DS.NumericInput `prefix` field. */\n percentPrefix: percentSymbolIsSuffix ? '' : percentSymbol,\n /** Meant for composition with DS.NumericInput `suffix` field. */\n percentSuffix: percentSymbolIsSuffix ? percentSymbol : '',\n percentSymbol,\n toFixed: (\n value,\n minimumFractionDigits = 2,\n maximumFractionDigits = 2,\n fallback = DS.FALLBACK_PLACEHOLDER_STRING,\n ) =>\n formatOrFallback(\n value,\n (val) =>\n intl.formatNumber(val, {\n maximumFractionDigits:\n maximumFractionDigits > minimumFractionDigits\n ? maximumFractionDigits\n : minimumFractionDigits,\n minimumFractionDigits,\n }),\n fallback,\n ),\n });\n }\n\n return formatterCache.get(key)!;\n}\n\nexport const useLocaleFormat = ({ currency }: { currency?: CurrencyTypes | null } = {}) => {\n const intl = useIntl();\n const { currency: tenantCurrency } = useTenantCurrency({ skip: Boolean(currency) });\n\n return getLocaleBag(intl, currency || tenantCurrency);\n};\n","// @ts-ignore: Ignore unused { * as Types } import\nimport * as Types from '@aurorasolar/graphql-client-schema';\n\nimport { gql } from '@apollo/client';\nimport * as Apollo from '@apollo/client';\nconst defaultOptions = {} as const;\nexport type SubmitLeadCaptureUtilityBillMutationVariables = Types.Exact<{\n id: Types.Scalars['ID']['input'];\n utilityBill: Types.SubmittedLeadCaptureUtilityBill;\n}>;\n\n\nexport type SubmitLeadCaptureUtilityBillMutation = { __typename: 'Mutation', submitLeadCaptureUtilityBill: { __typename: 'LeadCaptureProject', id: string, utilityBill?: { __typename: 'LeadCaptureUtilityBill', averageMonthlyBill?: number | null | undefined } | null | undefined } };\n\n\nexport const SubmitLeadCaptureUtilityBillDocument = gql`\n mutation SubmitLeadCaptureUtilityBill($id: ID!, $utilityBill: SubmittedLeadCaptureUtilityBill!) @trace_info(traceInfo: {pod: leads}) {\n submitLeadCaptureUtilityBill(id: $id, utilityBill: $utilityBill) {\n id\n utilityBill {\n averageMonthlyBill\n }\n }\n}\n `;\nexport type SubmitLeadCaptureUtilityBillMutationFn = Apollo.MutationFunction;\n\n/**\n * __useSubmitLeadCaptureUtilityBillMutation__\n *\n * To run a mutation, you first call `useSubmitLeadCaptureUtilityBillMutation` within a React component and pass it any options that fit your needs.\n * When your component renders, `useSubmitLeadCaptureUtilityBillMutation` returns a tuple that includes:\n * - A mutate function that you can call at any time to execute the mutation\n * - An object with fields that represent the current status of the mutation's execution\n *\n * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;\n *\n * @example\n * const [submitLeadCaptureUtilityBillMutation, { data, loading, error }] = useSubmitLeadCaptureUtilityBillMutation({\n * variables: {\n * id: // value for 'id'\n * utilityBill: // value for 'utilityBill'\n * },\n * });\n */\nexport function useSubmitLeadCaptureUtilityBillMutation(baseOptions?: Apollo.MutationHookOptions) {\n const options = {...defaultOptions, ...baseOptions}\n return Apollo.useMutation(SubmitLeadCaptureUtilityBillDocument, options);\n }\nexport type SubmitLeadCaptureUtilityBillMutationHookResult = ReturnType;\nexport type SubmitLeadCaptureUtilityBillMutationResult = Apollo.MutationResult;\nexport type SubmitLeadCaptureUtilityBillMutationOptions = Apollo.BaseMutationOptions;","import { Slider } from '@blueprintjs/core';\nimport { Flex } from 'reflexbox/styled-components';\nimport styled from 'styled-components';\n\nimport { Colors } from '@aurorasolar/common-core/src/colors';\nimport { LocaleFormatCurrencyFn, useLocaleFormat } from '@aurorasolar/common-core/src/hooks';\nimport { SPACES } from '@aurorasolar/common-core/src/layout';\n\nimport { LCAIText } from '../typography/lcai-text/lcai-text';\n\nexport const SLIDER_LEFT_LABEL_TESTID = 'slider-left-label';\nexport const SLIDER_RIGHT_LABEL_TESTID = 'slider-right-label';\n\nconst SLIDER_NOTCH_CLASS = 'bp3-custom-slider-label--notched';\nconst SLIDER_HIDDEN_LABEL_CLASS = 'bp3-custom-slider-label--hidden';\nconst HANDLE_SIDE_OFFSET = SPACES[2];\nconst TOOLTIP_SHADOW = '0 1px 5px rgba(164, 164, 164, 0.25)';\nconst HANDLE_SHADOW = '0 0 6px rgba(0, 0, 0, 0.25)';\nconst LABEL_COLOR = Colors.GRAY_600;\n\nconst LabelWrapper = styled.div`\n display: flex;\n text-align: center;\n`;\n\nconst Label = styled(LCAIText).attrs(() => ({\n color: LABEL_COLOR,\n fontWeight: 'medium',\n textTransform: 'uppercase',\n type: 'body-4',\n}))`\n letter-spacing: 0.75px;\n`;\n\nconst StyledSlider = styled(Slider)`\n border-left: solid ${HANDLE_SIDE_OFFSET}px transparent;\n border-right: solid ${HANDLE_SIDE_OFFSET}px transparent;\n height: 56px;\n display: flex;\n align-items: center;\n\n .bp3-slider-axis .bp3-slider-label {\n transform: translate(-50%, -50%);\n\n .${SLIDER_HIDDEN_LABEL_CLASS} {\n display: none;\n }\n\n .${SLIDER_NOTCH_CLASS} {\n width: 2px;\n color: transparent;\n height: ${SPACES[2]}px;\n background-color: ${Colors.GRAY_500};\n border-radius: 1px;\n overflow: hidden;\n }\n }\n\n .bp3-slider-track {\n background: ${Colors.GRAY_400};\n height: 4px;\n top: auto;\n\n .bp3-slider-progress {\n display: none;\n }\n }\n\n .bp3-slider-handle {\n width: ${SPACES[4]}px;\n height: ${SPACES[4]}px;\n top: auto;\n box-shadow: ${HANDLE_SHADOW};\n background: ${Colors.GRAY_800};\n border-radius: 50%;\n\n .bp3-slider-label {\n background: ${Colors.WHITE};\n border: 0.5px solid ${Colors.GRAY_300};\n padding: ${SPACES[0]}px ${SPACES[1]}px;\n box-shadow: ${TOOLTIP_SHADOW};\n border-radius: 4px;\n color: ${Colors.BLACK};\n transform: scale(0.9) translate(calc(4px - 50%), -48px);\n top: auto;\n opacity: 0;\n transition: opacity 0.2s ease, transform 0.2s ease;\n transition-delay: 0.2s;\n white-space: nowrap;\n\n /* Tooltip arrow */\n &::before {\n content: '';\n background: white;\n position: absolute;\n transform: translateX(-50%) rotate(45deg);\n height: 14px;\n width: 14px;\n bottom: -8px;\n left: 50%;\n border-bottom: 0.5px solid ${Colors.GRAY_300};\n border-right: 0.5px solid ${Colors.GRAY_300};\n border-radius: 0 0 3px 0;\n }\n }\n\n &:hover,\n &.bp3-active {\n .bp3-slider-label {\n opacity: 1;\n transform: scale(1) translate(calc(4px - 50%), -52px);\n transition-delay: 0s;\n }\n }\n }\n`;\n\nconst labelRenderMethod = (\n labelGenerator: { (value: number, formatCurrency: LocaleFormatCurrencyFn): string },\n formatCurrency: LocaleFormatCurrencyFn,\n) => {\n return (value: number) => {\n return (\n
\n \n {labelGenerator(value, formatCurrency)}\n \n
\n );\n };\n};\n\nexport interface LCAISliderProps {\n labelGenerator: (value: number, formatCurrency: LocaleFormatCurrencyFn) => string;\n leftLabel: string;\n rightLabel: string;\n min: number;\n max: number;\n value: number;\n onChange: (value: number) => void;\n stepSize?: number;\n}\n\nexport const LCAISlider = ({\n labelGenerator,\n leftLabel,\n rightLabel,\n min,\n max,\n value,\n onChange,\n stepSize = 25,\n}: LCAISliderProps) => {\n const { formatCurrency } = useLocaleFormat();\n\n return (\n \n {leftLabel && (\n \n \n \n )}\n\n \n {rightLabel && (\n \n \n \n )}\n \n );\n};\n","import { useState } from 'react';\nimport { Box } from 'reflexbox/styled-components';\n\nimport { LocaleFormatCurrencyFn, useLocaleFormat } from '@aurorasolar/common-core/src/hooks';\n\nimport { CurrencyTypes } from '@aurorasolar/graphql-client-schema';\nimport { BoxWithMargin, LCAISlider } from '../../../shared-components';\nimport { LCAIText } from '../../../typography';\nimport { HEADER_COLOR } from '../../../utils/constants';\n\nexport const UTILITY_BILL_VALUE_TESTID = 'utility-bill-value';\n\nconst MIN_BILL = 25;\nconst MIN_LABEL = 'Under ';\nconst MAX_BILL = 600;\nconst MAX_LABEL = 'Over ';\n\ninterface UtilitySliderProps {\n currency?: string | null;\n defaultBill: number;\n updateBill: (value: number) => void;\n}\n\nexport const UtilitySlider = ({ currency, defaultBill, updateBill }: UtilitySliderProps) => {\n const { formatCurrency } = useLocaleFormat({ currency: currency as CurrencyTypes });\n const [utilityBill, setUtilityBill] = useState(defaultBill);\n\n const onBillChange = (value: number) => {\n setUtilityBill(value);\n updateBill(value);\n };\n\n return (\n <>\n \n \n {generateUtilitySliderLabel(utilityBill, formatCurrency)}\n \n \n \n \n \n \n );\n};\n\nconst generateUtilitySliderLabel = (value: number, formatCurrency: LocaleFormatCurrencyFn) => {\n let label = '';\n\n if (value === MIN_BILL) {\n label += MIN_LABEL;\n }\n\n if (value === MAX_BILL) {\n label += MAX_LABEL;\n }\n\n label += formatCurrency(value, { maximumFractionDigits: 0 });\n\n return label;\n};\n","import { useEffect, useRef } from 'react';\nimport { useDebouncedCallback } from '@aurorasolar/common-core/src/hooks';\nimport { AuroraIcon, AuroraIconType } from '@aurorasolar/common-core/src/icon';\nimport {\n Analytics,\n AnalyticsEventTypes,\n AnalyticsPageTypes,\n AppRouterNavigation,\n useAppModule,\n} from '@aurorasolar/common-module-loader';\n\nimport { useRouteData } from '../../hooks';\nimport { AnimateView, Image, SplitView, TopRail } from '../../shared-components';\nimport { LCAIButton, LCAIButtonIntent, LCAIText } from '../../typography';\nimport { DEBOUNCE_TIME, HEADER_COLOR, PROGRESS_VALUES } from '../../utils/constants';\nimport { SourcePage } from '../../utils/source-page';\nimport { useSubmitLeadCaptureUtilityBillMutation } from './utility.generated';\nimport { UtilitySlider } from './components/utility-slider';\n\nconst DEFAULT_BILL = 100;\nexport interface UtilityPageProps {\n projectId: string;\n sourcePage: SourcePage;\n}\n\nexport const UtilityPage = ({ projectId, sourcePage }: UtilityPageProps) => {\n const navigation = useAppModule(AppRouterNavigation);\n const analytics = useAppModule(Analytics);\n\n const { customSettings, currency, firstCoreQuestionId, formBeforeResults, templateId } =\n useRouteData();\n const [submitUtilityBill] = useSubmitLeadCaptureUtilityBillMutation();\n\n const billRef = useRef({\n bill: DEFAULT_BILL,\n });\n\n const updateBill = (value: number) => {\n billRef.current.bill = value;\n };\n\n useEffect(() => {\n analytics?.page(AnalyticsPageTypes.LeadCaptureUtility, {\n project_id: projectId,\n });\n }, [analytics, projectId]);\n\n const saveUtilityBill = useDebouncedCallback(\n async () => {\n submitUtilityBill({\n variables: {\n id: projectId,\n utilityBill: {\n averageMonthlyBill: billRef.current.bill,\n },\n },\n });\n\n await analytics?.track(AnalyticsEventTypes.LeadCaptureEnteredConsumption, {\n project_id: projectId,\n });\n\n let url = `/projects/${projectId}/qualification/${firstCoreQuestionId}`;\n\n if (!firstCoreQuestionId) {\n if (formBeforeResults) {\n url = `/projects/${projectId}/quote`;\n } else {\n url = `/projects/${projectId}/progress`;\n }\n }\n\n navigation?.navigate(url, { replace: true });\n },\n [analytics, firstCoreQuestionId, formBeforeResults, projectId, navigation, submitUtilityBill],\n DEBOUNCE_TIME,\n );\n\n return (\n <>\n \n \n \n \n Next\n \n }\n hasProgressBar\n leftContent={\n <>\n \n What is your average monthly electric bill?\n \n \n \n }\n rightContent={\n \n }\n />\n \n \n );\n};\n\nexport default UtilityPage;\n","import { SourcePage } from './source-page';\n\nexport interface LCAIImage {\n alt: string;\n name: string;\n position?: string;\n}\n\nexport const IMAGES = {\n AddressImage: { alt: 'View of earth from space', name: 'location' },\n BillUploadImage: {\n alt: 'Bungalow with solar panels with lots of shrubs and two trees in the foreground',\n name: 'bill-upload',\n position: '0% 90%',\n },\n ComingSoonImage: {\n alt: 'Women in kitchen with wood shelves containing dishes',\n name: 'coming-soon',\n },\n DropOffImage: {\n alt: \"Bird's-eye view of a neighborhood at sunrise showing roofs with and without solar\",\n name: 'drop-off',\n },\n LandingImage: {\n alt: 'Patio scene with solar home in background',\n name: 'how-it-works',\n position: 'center 30%',\n },\n ProfileReviewImage: {\n alt: 'An older couple reviewing their solar needs with a solar expert',\n name: 'profile-review',\n position: '60% 10%',\n },\n QuoteImage: {\n alt: 'Yellow brick house with solar panels with greenery in foreground',\n name: 'get-in-touch',\n },\n ThankYouImage: {\n alt: 'Open french doors to balcony containing potted plants with trees in the distance',\n name: 'thank-you',\n },\n UtilityImage: {\n alt: 'String of electric lights hanging between trees',\n name: 'savings',\n position: 'center 75%',\n },\n};\n\nconst MAPPED_IMAGES = {\n [SourcePage.ADDRESS]: IMAGES.AddressImage,\n [SourcePage.ADDRESS_DROP]: IMAGES.DropOffImage,\n [SourcePage.BILL_UPLOAD]: IMAGES.BillUploadImage,\n [SourcePage.ERROR]: IMAGES.ComingSoonImage,\n [SourcePage.GENERIC_DROP]: IMAGES.DropOffImage,\n [SourcePage.LANDING]: IMAGES.LandingImage,\n [SourcePage.OWNERSHIP_DROP]: IMAGES.ComingSoonImage,\n [SourcePage.QUOTE]: IMAGES.QuoteImage,\n [SourcePage.THANK_YOU]: IMAGES.ThankYouImage,\n [SourcePage.UTILITY]: IMAGES.UtilityImage,\n};\n\nexport function ImageMatcher(sourcePage: SourcePage): LCAIImage {\n return MAPPED_IMAGES[sourcePage];\n}\n","import styled from 'styled-components';\n\nimport { CustomImageFragment } from '../lead-capture.generated';\nimport { S3_IMAGE_LOCATION } from '../utils/constants';\nimport { ImageMatcher } from '../utils/image-matcher';\nimport { SourcePage } from '../utils/source-page';\n\nconst DEFAULT_POSITION = 'center';\n\nexport interface ImageProps {\n customImage?: CustomImageFragment | null;\n alt?: string;\n children?: JSX.Element;\n name?: string;\n position?: string;\n sourcePage?: SourcePage;\n}\n\nexport const Image = ({\n alt,\n children,\n customImage,\n name,\n position = DEFAULT_POSITION,\n sourcePage,\n}: ImageProps) => {\n const matchedImage = sourcePage && ImageMatcher(sourcePage);\n\n const webpSrc = `${S3_IMAGE_LOCATION + (matchedImage?.name || name)}.webp`;\n const jpgSrc = `${S3_IMAGE_LOCATION + (matchedImage?.name || name)}.jpg`;\n\n const url = (customImage?.isActive && customImage?.url) || webpSrc;\n const fallbackUrl = (customImage?.isActive && customImage?.fallbackUrl) || jpgSrc;\n const altText = (customImage?.isActive && customImage?.altText) || matchedImage?.alt || alt;\n const positionAttr = (!customImage?.isActive && matchedImage?.position) || position;\n\n return (\n \n \n \n {altText}\n \n {children}\n \n );\n};\n\nconst ImageContainer = styled.div`\n position: relative;\n height: 100%;\n`;\n\nconst Img = styled.img`\n object-fit: cover;\n object-position: ${(props: Pick) => `${props.position}`};\n height: 100%;\n width: 100%;\n`;\n"],"names":["formatOrFallback","value","format","fallback","defaultOptions","GetTenantCurrencyDocument","useGetTenantCurrencyLazyQuery","baseOptions","options","query","useBaseQuery","formatCurrencyFactory","formatNumber","currency","minimumFractionDigits","maximumFractionDigits","preset","truncatePrecisionGTEValue","Number","POSITIVE_INFINITY","val","baseFormattingOptions","style","formatterCache","Map","useLocaleFormat","intl","tenantCurrency","skip","client","tokens","loadQuery","data","useEffect","currentTenant","Usd","useTenantCurrency","Boolean","key","locale","stringLocale","has","currencyParts","Intl","NumberFormat","currencyDisplay","formatToParts","currencyValueIndex","findIndex","x","type","currencySymbolIndex","currencySymbol","currencySymbolIsSuffix","percentParts","percentValueIndex","percentSymbolIndex","percentSymbol","percentSymbolIsSuffix","set","currencyPrefix","currencySuffix","formatCurrency","formatDateTime","date","Date","formatEnergy","unit","formatHour","hour","hour12","formatLatLong","formatPercent","percentPrefix","percentSuffix","toFixed","get","getLocaleBag","SubmitLeadCaptureUtilityBillDocument","SLIDER_HIDDEN_LABEL_CLASS","HANDLE_SIDE_OFFSET","LABEL_COLOR","GRAY_600","LabelWrapper","div","Label","attrs","color","fontWeight","textTransform","StyledSlider","GRAY_500","GRAY_400","GRAY_800","WHITE","GRAY_300","BLACK","labelRenderMethod","labelGenerator","className","LCAISlider","leftLabel","rightLabel","min","max","onChange","stepSize","alignItems","labelRenderer","showTrackFill","UtilitySlider","defaultBill","updateBill","utilityBill","setUtilityBill","useState","generateUtilitySliderLabel","marginTop","label","UtilityPage","projectId","sourcePage","navigation","analytics","customSettings","firstCoreQuestionId","formBeforeResults","templateId","submitUtilityBill","useSubmitLeadCaptureUtilityBillMutation","billRef","useRef","bill","page","LeadCaptureUtility","project_id","saveUtilityBill","async","variables","id","averageMonthlyBill","current","track","LeadCaptureEnteredConsumption","url","navigate","replace","progressValue","UTILITY","buttons","intent","PRIMARY_LIGHT","onClick","name","BTN_ARROW","hasProgressBar","leftContent","rightContent","customImage","utilityBillPageImage","IMAGES","AddressImage","alt","BillUploadImage","position","ComingSoonImage","DropOffImage","LandingImage","ProfileReviewImage","QuoteImage","ThankYouImage","UtilityImage","MAPPED_IMAGES","ADDRESS","ADDRESS_DROP","BILL_UPLOAD","ERROR","GENERIC_DROP","LANDING","OWNERSHIP_DROP","QUOTE","THANK_YOU","Image","children","matchedImage","ImageMatcher","webpSrc","jpgSrc","isActive","fallbackUrl","altText","positionAttr","ImageContainer","srcSet","Img","src","img","props"],"sourceRoot":""}