\n
\n
\n \n {intl.formatMessage(messages.appointmentDetailsTitle)}\n
\n {!drawRequest && handleScheduleDraw && (\n
\n )}\n
\n {drawRequest && (\n <>\n
\n
\n
\n {intl.formatMessage(messages.appointmentDetailsHeader)}\n
\n
\n {intl.formatMessage(messages.appointmentDetailsParagraph)}\n
\n
\n
\n {showAddress && (\n
\n )}\n
\n {drawRequest?.jobStatus && isEditableStatus ? (\n
\n {!hideCancelButton && (\n \n )}\n \n
\n ) : (\n
\n
{appointmentDetailsReferenceText}
\n
\n )}\n >\n )}\n
\n );\n};\n\nexport default AppointmentDetails;\n","export { default } from \"./appointmentDetails\";\n","import React, { useMemo, useContext } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nimport { getTimeSlot } from \"@app/utils\";\nimport { DrawRequestTimeslots } from \"@app/provider/drawRequest\";\nimport { MobilePhlebotomyStatus } from \"@app/provider/types\";\nimport { IntlContext } from \"@app/provider\";\n\nimport \"./appointmentTimeslots.scss\";\nimport { TestCardStatus } from \"@app/provider/testData/types\";\n\nconst messages = defineMessages({\n appointmentTimeslotsSelectedTimeSlotsConfirmation: {\n id: \"appointmentTimeslotsSelectedTimeSlotsConfirmation\",\n defaultMessage: \"Preferred time slots\",\n },\n appointmentTimeslotsSelectedTimeSlots: {\n id: \"appointmentTimeslotsSelectedTimeSlots\",\n defaultMessage: \"Selected time slots\",\n },\n appointmentTimeslotsUpcomingAppointment: {\n id: \"appointmentTimeslotsUpcomingAppointment\",\n defaultMessage: \"Upcoming Appointment\",\n },\n});\n\ntype AppointmentTimeslotsDrawRequest = DrawRequestTimeslots & {\n jobStatus?: MobilePhlebotomyStatus;\n jobEnd?: string;\n jobStart?: string;\n};\n\ntype Props = {\n drawRequest: AppointmentTimeslotsDrawRequest;\n selectedTimeZone?: string;\n isConfirmationStep?: boolean;\n status?: TestCardStatus;\n};\n\nconst AppointmentTimeslots: React.FC = ({\n drawRequest,\n selectedTimeZone,\n isConfirmationStep,\n status,\n}) => {\n const intl = useIntl();\n const { currentLanguage } = useContext(IntlContext);\n const isApptConfirmed = status === TestCardStatus.APPT_CONFIRMED;\n\n const timeSlotsTitle = useMemo(() => {\n if (isConfirmationStep) {\n return intl.formatMessage(\n messages.appointmentTimeslotsSelectedTimeSlotsConfirmation\n );\n }\n\n return intl.formatMessage(\n isApptConfirmed\n ? messages.appointmentTimeslotsUpcomingAppointment\n : messages.appointmentTimeslotsSelectedTimeSlots\n );\n }, [drawRequest, isConfirmationStep, currentLanguage]);\n\n const renderTimeSlot = () => {\n if (isApptConfirmed) {\n return (\n \n {drawRequest.jobStart && drawRequest.jobEnd && (\n \n {getTimeSlot(\n drawRequest.jobStart,\n drawRequest.jobEnd,\n selectedTimeZone\n )}\n \n )}\n
\n );\n }\n return (\n \n \n {getTimeSlot(drawRequest.start1, drawRequest.end1, selectedTimeZone)}\n \n {drawRequest.start2 && drawRequest.end2 && (\n <>\n
\n \n {getTimeSlot(\n drawRequest.start2,\n drawRequest.end2,\n selectedTimeZone\n )}\n \n >\n )}\n {drawRequest.start3 && drawRequest.end3 && (\n <>\n
\n \n {getTimeSlot(\n drawRequest.start3,\n drawRequest.end3,\n selectedTimeZone\n )}\n \n >\n )}\n
\n );\n };\n\n return (\n \n
{timeSlotsTitle}
\n {drawRequest && renderTimeSlot()}\n \n );\n};\n\nexport default AppointmentTimeslots;\n","export { default as AppointmentTimeslots } from \"./appointmentTimeslots\";\n","import React, { useEffect, FC, useContext, useState } from \"react\";\nimport Svg from \"@natera/material/lib/svg\";\nimport EmpowerImage from \"@assets/svg/empower-risk-alert.svg\";\nimport BookMarkStarSVG from \"@assets/svg/icons/book-mark-star.svg\";\nimport { InfoCard } from \"@natera/patient\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { HEAP_EVENTS } from \"@app/provider/types\";\nimport { UserContext } from \"@app/provider\";\nimport Button from \"@natera/material/lib/button\";\nimport { useDialog } from \"@natera/platform/lib/hooks\";\nimport EmpowerAlertDialog from \"@app/components/empowerAlertDialog\";\nimport EmpowerAlertPopUp from \"@app/components/empowerAlertPopUp\";\n\nimport \"./empowerAlertBanner.scss\";\n\nconst messages = defineMessages({\n empowerAlertBannerText: {\n id: \"empowerAlertBannerText\",\n defaultMessage: \"You may qualify for hereditary cancer testing\",\n },\n empowerAlertBannerLinkButton: {\n id: \"empowerAlertBannerLinkButton\",\n defaultMessage: \"Learn more\",\n },\n});\n\nexport interface EmpowerAlertBannerProps {\n limsId?: number;\n}\n\nconst EmpowerAlertBanner: FC = ({ limsId }) => {\n const intl = useIntl();\n const { uppUser } = useContext(UserContext);\n\n const empowerAlertDialog = useDialog(EmpowerAlertDialog);\n const empowerAlertPopUpDialog = useDialog(EmpowerAlertPopUp);\n\n const [\n empowerAlertDialogWasClosed,\n setEmpowerAlertDialogWasClosed,\n ] = useState(false);\n\n useEffect(() => {\n empowerAlertDialogWasClosed && openEmpowerAlertPopUp();\n }, [empowerAlertDialogWasClosed]);\n\n const openEmpowerAlertPopUp = () => {\n empowerAlertPopUpDialog.open({\n onCloseDialog: empowerAlertPopUpDialog.close,\n limsId: limsId,\n });\n };\n\n const closeEmpowerAlertDialog = () => {\n empowerAlertDialog.close();\n setEmpowerAlertDialogWasClosed(true);\n };\n\n const openEmpowerAlertDialog = () => {\n setEmpowerAlertDialogWasClosed(false);\n empowerAlertDialog.open({\n onCloseDialog: () => closeEmpowerAlertDialog(),\n });\n\n heap.track(HEAP_EVENTS.upp_empower_risk_alert_click, {\n identity: uppUser?.patientUID,\n lims_clinic_id: limsId,\n });\n };\n\n useEffect(() => {\n heap.track(HEAP_EVENTS.upp_empower_risk_alert_banner, {\n identity: uppUser?.patientUID,\n lims_clinic_id: limsId,\n });\n }, []);\n\n return (\n <>\n {empowerAlertDialog.getDialog()}\n {empowerAlertPopUpDialog.getDialog()}\n \n }\n >\n \n
\n {intl.formatMessage(messages.empowerAlertBannerText)}\n
\n
\n
\n \n >\n );\n};\n\nexport default EmpowerAlertBanner;\n","export { default } from \"./empowerAlertBanner\";\n","export { default as RenewalBanner } from \"./renewalBanner\";\nexport { default as EmpowerAlertBanner } from \"./empowerAlertBanner\";\n","export { default } from \"./renewalBanner\";\n","import * as React from \"react\";\nimport { FC, useContext } from \"react\";\nimport Svg from \"@natera/material/lib/svg\";\nimport ReminderImage from \"@assets/svg/icons/renewal-reminder.svg\";\nimport { InfoCard } from \"@natera/patient\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { HEAP_EVENTS } from \"@app/provider/types\";\nimport { UserContext } from \"@app/provider\";\nimport Button from \"@natera/material/lib/button\";\n\nimport \"./renewalBanner.scss\";\n\nconst messages = defineMessages({\n renewalBannerText: {\n id: \"renewalBannerText\",\n defaultMessage: \"It's time to renew your Signatera test\",\n },\n renewalBannerLinkButton: {\n id: \"renewalBannerLinkButton\",\n defaultMessage: \"Learn more\",\n },\n});\n\nexport interface RenewalBannerProps {\n openRenewalDialog: () => void;\n isMobilePhlebotomyPage?: boolean;\n limsId?: number;\n orderUidPublic?: string;\n}\n\nconst RenewalBanner: FC = ({\n openRenewalDialog,\n isMobilePhlebotomyPage,\n limsId,\n orderUidPublic,\n}) => {\n const intl = useIntl();\n const { uppUser } = useContext(UserContext);\n\n const openDialog = (event: React.SyntheticEvent) => {\n event.preventDefault();\n event.stopPropagation();\n openRenewalDialog();\n heap.track(\n isMobilePhlebotomyPage\n ? HEAP_EVENTS.upp_renewal_mp_signatera_click\n : HEAP_EVENTS.upp_renewal_homepage_signatera_click,\n {\n identity: uppUser?.patientUID,\n lims_clinic_id: limsId,\n public_order_uid: orderUidPublic,\n }\n );\n };\n\n return (\n \n }\n >\n \n
\n {intl.formatMessage(messages.renewalBannerText)}\n
\n
\n
\n \n );\n};\n\nexport default RenewalBanner;\n","import React, { FC, ReactElement } from \"react\";\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport \"./baseModalDialog.scss\";\nimport { defineMessages } from \"react-intl\";\n\n// overrides @natera/material/lib/dialog component translations\nconst messages = defineMessages({\n dialogCloseButtonAriaLabel: {\n id: \"material.dialog.ariaLabelCloseButton\",\n defaultMessage: \"Close\",\n },\n});\n\ninterface BaseModalDialogProps {\n header: ReactElement | string;\n content?: ReactElement;\n actions?: ReactElement;\n handleClose?: () => void;\n altText?: string;\n}\n\nconst BaseModalDialog: FC = ({\n header,\n content,\n actions,\n handleClose,\n altText,\n}) => {\n const handleCloseDialog = () => handleClose && handleClose();\n return (\n \n );\n};\n\nexport default BaseModalDialog;\n","export { default } from \"./baseModalDialog\";\n","import React, { useContext, useEffect, useState } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Link } from \"@natera/navigation\";\nimport { Svg } from \"@natera/material/lib/svg\";\nimport billingUpdatesIcon from \"@assets/svg/icons/billing-updates.svg\";\nimport linkArrowIcon from \"@assets/svg/icons/link-arrow.svg\";\nimport { routes } from \"@app/routing\";\nimport { PreBillAPIContext } from \"@app/preBill/provider\";\nimport \"./billingUpdatesCard.scss\";\n\nconst messages = defineMessages({\n billingUpdatesText: {\n id: \"billingUpdatesText\",\n defaultMessage: \"You have new billing updates\",\n },\n});\n\nconst BillingUpdatesCard: React.FC = () => {\n const intl = useIntl();\n const [activeOrdersCount, setActiveOrdersCount] = useState(0);\n const { listActiveOrdersForPatient } = useContext(PreBillAPIContext);\n\n useEffect(() => {\n let mounted = true;\n\n const loadActiveOrders = async () => {\n try {\n const response = await listActiveOrdersForPatient();\n\n if (!mounted) return;\n\n setActiveOrdersCount(response.activeOrders.length);\n } catch (error) {\n console.error(\"Failed to load active orders:\", error);\n }\n };\n\n loadActiveOrders();\n\n return () => {\n mounted = false;\n };\n }, []);\n\n if (activeOrdersCount === 0) {\n return null;\n }\n\n return (\n \n \n \n \n {intl.formatMessage(messages.billingUpdatesText)} ({activeOrdersCount}\n )\n \n \n \n
\n );\n};\n\nexport default BillingUpdatesCard;\n","export { default } from \"./billingUpdatesCard\";\n","import React from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport classNames from \"classnames\";\nimport \"./billingUpdatesPageNotificationCard.scss\";\nimport { PreBillTestTypes } from \"@app/preBill/models\";\nimport { capitalizeFirstLetter } from \"@app/utils\";\n\nconst messages = defineMessages({\n billingUpdatesNotificationReviewBy: {\n id: \"billingUpdatesNotificationReviewBy\",\n defaultMessage: \"Review by\",\n },\n billingUpdatesNotificationPanoromaTestDescription: {\n id: \"billingUpdatesNotificationPanoromaTestDescription\",\n defaultMessage: \"Noninvasive prenatal testing (NIPT)\",\n },\n billingUpdatesNotificationHorizonTestDescription: {\n id: \"billingUpdatesNotificationHorizonTestDescription\",\n defaultMessage: \"Advanced carrier screening\",\n },\n billingUpdatesNotificationEmpowerTestDescription: {\n id: \"billingUpdatesNotificationEmpowerTestDescription\",\n defaultMessage: \"Hereditary cancer screening\",\n },\n});\n\nexport interface NotificationProps {\n notification: {\n id: string;\n testType: string;\n date: string | null;\n isRead: boolean;\n tokenizedLink: string;\n };\n onClick: () => void;\n}\n\nconst BillingUpdatesPageNotificationCard = ({\n notification,\n onClick,\n}: NotificationProps): JSX.Element => {\n const intl = useIntl();\n\n const descriptions = {\n [PreBillTestTypes.PANORAMA]: intl.formatMessage(\n messages.billingUpdatesNotificationPanoromaTestDescription\n ),\n [PreBillTestTypes.HORIZON]: intl.formatMessage(\n messages.billingUpdatesNotificationHorizonTestDescription\n ),\n [PreBillTestTypes.EMPOWER]: intl.formatMessage(\n messages.billingUpdatesNotificationEmpowerTestDescription\n ),\n [PreBillTestTypes.PANORAMA_HORIZON]: `${intl.formatMessage(\n messages.billingUpdatesNotificationPanoromaTestDescription\n )} & ${intl.formatMessage(\n messages.billingUpdatesNotificationHorizonTestDescription\n )}`,\n };\n\n return (\n \n
\n {!notification.isRead && (\n
\n )}\n
\n
\n
\n {`${capitalizeFirstLetter(notification.testType)} - ${\n descriptions[\n notification.testType.toLocaleUpperCase() as PreBillTestTypes\n ] ||\n intl.formatMessage(\n messages.billingUpdatesNotificationPanoromaTestDescription\n )\n }`}\n
\n {notification.date && (\n
\n {intl.formatMessage(messages.billingUpdatesNotificationReviewBy)} [\n {notification.date}]\n
\n )}\n
\n
\n );\n};\n\nexport default BillingUpdatesPageNotificationCard;\n","export { default } from \"./billingUpdatesPageNotificationCard\";\nexport type { NotificationProps } from \"./billingUpdatesPageNotificationCard\";\n","import React, { FC } from \"react\";\n\nimport { ButtonProps as BaseButtonProps } from \"@natera/material/lib/button\";\nimport { Button } from \"@natera/form\";\n\nimport \"./buttonNoShadow.scss\";\n\nconst ButtonNoShadow: FC = (props) => {\n return ;\n};\n\nexport default ButtonNoShadow;\n","export { default as ButtonNoShadow } from \"./buttonNoShadow\";\n","export { default as TestTitle } from \"./testTitle\";\nexport { default as TestDescription } from \"./testDescription\";\n","import React, { FC, useContext, useMemo } from \"react\";\nimport { TestType } from \"@app/provider/testData/types\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { IntlContext } from \"@app/provider\";\n\nconst messages = defineMessages({\n testRenasightDescription: {\n id: \"testRenasightDescription\",\n defaultMessage: \"Kidney Gene Panel\",\n },\n testProsperaDescription: {\n id: \"testProsperaDescription\",\n defaultMessage: \"Transplant Assessment\",\n },\n testHorizonDescription: {\n id: \"testHorizonDescription\",\n defaultMessage: \"Carrier Screening\",\n },\n testPanoramaDescription: {\n id: \"testPanoramaDescription\",\n defaultMessage: \"Non-Invasive Prenatal Testing-NIPT\",\n },\n testEmpowerDescription: {\n id: \"testEmpowerDescription\",\n defaultMessage: \"Hereditary Cancer Test\",\n },\n testVistaraDescription: {\n id: \"testVistaraDescription\",\n defaultMessage: \"Single-Gene NIPT\",\n },\n testAlteraDescription: {\n id: \"testAlteraDescription\",\n defaultMessage: \"Tumor Genomic Profile Test\",\n },\n testSignateraDescription: {\n id: \"testSignateraDescription\",\n defaultMessage: \"Molecular Residual Disease Test\",\n },\n});\n\ninterface Props {\n testType: TestType;\n}\n\nconst TestDescription: FC = ({ testType }) => {\n const intl = useIntl();\n const { currentLanguage } = useContext(IntlContext);\n\n const descriptions: { [key: string]: string } = useMemo(\n () => ({\n [TestType.RENASIGHT]: intl.formatMessage(\n messages.testRenasightDescription\n ),\n [TestType.PROSPERA]: intl.formatMessage(messages.testProsperaDescription),\n [TestType.HORIZON]: intl.formatMessage(messages.testHorizonDescription),\n [TestType.PANORAMA]: intl.formatMessage(messages.testPanoramaDescription),\n [TestType.EMPOWER]: intl.formatMessage(messages.testEmpowerDescription),\n [TestType.VISTARA]: intl.formatMessage(messages.testVistaraDescription),\n [TestType.ALTERA]: intl.formatMessage(messages.testAlteraDescription),\n [TestType.SIGNATERA]: intl.formatMessage(\n messages.testSignateraDescription\n ),\n }),\n [currentLanguage]\n );\n\n return <>{descriptions[testType] || \"\"}>;\n};\n\nexport default TestDescription;\n","import React, { FC } from \"react\";\nimport { TestType } from \"@app/provider/testData/types\";\nimport { defineMessages } from \"react-intl\";\nimport useTestTitles from \"@app/hooks/useTestTitles\";\n\nexport const titles = defineMessages({\n testRenasightTitle: {\n id: \"common.testcards.renasight\",\n defaultMessage: \"Renasight\",\n },\n testProsperaTitle: {\n id: \"common.testcards.prospera\",\n defaultMessage: \"Prospera\",\n },\n testHorizonTitle: {\n id: \"common.testcards.horizon\",\n defaultMessage: \"Horizon\",\n },\n testPanoramaTitle: {\n id: \"common.testcards.panorama\",\n defaultMessage: \"Panorama\",\n },\n testEmpowerTitle: {\n id: \"common.testcards.empower\",\n defaultMessage: \"Empower\",\n },\n testSignateraTitle: {\n id: \"common.testcards.signatera\",\n defaultMessage: \"Signatera\",\n },\n testAlteraTitle: {\n id: \"common.testcards.altera\",\n defaultMessage: \"Altera\",\n },\n testVistaraTitle: {\n id: \"common.testcards.vistara\",\n defaultMessage: \"Vistara\",\n },\n testSpectrumTitle: {\n id: \"common.testcards.spectrum\",\n defaultMessage: \"Spectrum\",\n },\n testAnoraTitle: {\n id: \"common.testcards.anora\",\n defaultMessage: \"Anora\",\n },\n commonOncologyTitle: {\n id: \"common.titles.oncology\",\n defaultMessage: \"Oncology\",\n },\n commonOHTitle: {\n id: \"common.titles.OH\",\n defaultMessage: \"Organ Health\",\n },\n commonWHTitle: {\n id: \"common.titles.WH\",\n defaultMessage: \"Women’s Health\",\n },\n});\n\ninterface Props {\n testType: TestType;\n}\nconst TestTitle: FC = ({ testType }) => {\n const testTitles = useTestTitles();\n\n return <>{testTitles[testType]}>;\n};\n\nexport default TestTitle;\n","import React, { FC } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Address } from \"@app/provider\";\nimport { CommonFormActions } from \"@app/components\";\nimport { AddressForm } from \"@app/components/forms\";\n\nexport const messages = defineMessages({\n commonAddressFormSave: {\n id: \"commonAddressFormSave\",\n defaultMessage: \"Save\",\n },\n commonAddressFormUpdate: {\n id: \"commonAddressFormUpdate\",\n defaultMessage: \"Update\",\n },\n});\n\ninterface Props {\n address?: Address;\n handleSubmit: (address: Partial) => void;\n handleCancel: () => void;\n submitButtonText?: string;\n}\n\nconst CommonAddressForm: FC = ({\n address,\n handleSubmit,\n handleCancel,\n submitButtonText,\n}) => {\n const intl = useIntl();\n\n const defaultSubmitButtonText = address\n ? intl.formatMessage(messages.commonAddressFormUpdate)\n : intl.formatMessage(messages.commonAddressFormSave);\n\n return (\n \n }\n />\n );\n};\n\nexport default CommonAddressForm;\n","export { default } from \"./commonAddressForm\";\n","import React, { FC } from \"react\";\nimport { Notification } from \"@app/components\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nconst messages = defineMessages({\n commonErrorNotificationText: {\n id: \"commonErrorNotificationText\",\n defaultMessage: \"We're sorry. Something went wrong.\",\n },\n});\n\nconst CommonErrorNotification: FC = () => {\n const intl = useIntl();\n\n return (\n \n {intl.formatMessage(messages.commonErrorNotificationText)}\n \n );\n};\nexport default CommonErrorNotification;\n","export { default } from \"./commonErrorNotification\";\n","import React, { FC } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Button } from \"@natera/form\";\nimport CommonFormActionsView from \"../commonFormActionsView\";\n\nexport const messages = defineMessages({\n commonAddressFormActionsCancelButtonText: {\n id: \"commonFormActionsCancelButtonText\",\n defaultMessage: \"Cancel\",\n },\n});\n\ninterface Props {\n submitButtonText: string;\n submitButtonDisabled?: boolean;\n handleCancel?: () => void;\n}\n\nconst CommonFormActions: FC = ({\n submitButtonText,\n submitButtonDisabled,\n handleCancel,\n}) => {\n const intl = useIntl();\n\n return (\n \n {handleCancel && (\n \n )}\n \n \n );\n};\n\nexport default CommonFormActions;\n","export { default } from \"./commonFormActions\";\n","import React, { FC } from \"react\";\nimport \"./commonFormActionsView.scss\";\n\nconst CommonFormActionsView: FC = ({ children }) => {\n return {children}
;\n};\n\nexport default CommonFormActionsView;\n","export { default } from \"./commonFormActionsView\";\n","import { RadioGroup, RadioButton } from \"@natera/form\";\nimport classNames from \"classnames\";\nimport React from \"react\";\n\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Payor } from \"@app/provider/payor\";\n\nimport \"./companySelector.scss\";\n\nconst messages = defineMessages({\n insuranceCompanyLabelOther: {\n id: \"insuranceCompanyLabelOther\",\n defaultMessage: \"Other\",\n },\n});\n\nexport enum PredefinedCompanyName {\n Aetna = \"Aetna\",\n BlueCrossBlueShield = \"Blue Cross Blue Shield\",\n Cigna = \"Cigna\",\n Humana = \"Humana\",\n Medicaid = \"Medicaid\",\n Tricare = \"Tricare\",\n UnitedHealthcareGroup = \"United Healthcare Group\",\n Other = \"Other\",\n}\n\ntype PredefinedCompaniesType = { [key: string]: Payor };\n\nexport const PredefinedCompanies: PredefinedCompaniesType = {\n Aetna: {\n displayName: PredefinedCompanyName.Aetna,\n groupId: \"AETNA\",\n },\n BlueCrossBlueShield: {\n displayName: PredefinedCompanyName.BlueCrossBlueShield,\n groupId: \"BCBS\",\n },\n Cigna: {\n displayName: PredefinedCompanyName.Cigna,\n groupId: \"CIGNA\",\n },\n Humana: {\n displayName: PredefinedCompanyName.Humana,\n groupId: \"HUMANA\",\n },\n Medicaid: {\n displayName: PredefinedCompanyName.Medicaid,\n groupId: \"STATE MEDICAID\",\n },\n Tricare: {\n displayName: PredefinedCompanyName.Tricare,\n groupId: \"TRICARE\",\n },\n UnitedHealthcareGroup: {\n displayName: PredefinedCompanyName.UnitedHealthcareGroup,\n groupId: \"UHC\",\n },\n Other: {\n displayName: PredefinedCompanyName.Other,\n },\n};\n\ntype Props = {\n value?: Payor;\n onChange: (company?: Payor) => void;\n companies: Payor[];\n};\n\nconst CompanySelector: React.FC = ({ value, onChange, companies }) => {\n const intl = useIntl();\n\n const getCompanyLabel = (company: Payor) =>\n company.displayName === PredefinedCompanyName.Other\n ? intl.formatMessage(messages.insuranceCompanyLabelOther)\n : company.displayName;\n\n const changeHandler = (companyName: string) => {\n const selectedCompany = Object.values(PredefinedCompanies).find(\n (company) => company.displayName === companyName\n );\n onChange(selectedCompany);\n };\n\n return (\n \n {companies.map((company) => (\n \n ))}\n \n );\n};\n\nexport default CompanySelector;\n","export { default as CompanySelector } from \"./companySelector\";\n","import React, { FC, useContext } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { Button } from \"@natera/form\";\nimport { ConfigContext } from \"@app/provider\";\nimport { openNewWindow } from \"@app/utils\";\nimport \"./compassionateCareDialog.scss\";\n\nconst messages = defineMessages({\n compassionateCareDialogTitle: {\n id: \"compassionateCareDialogTitle\",\n defaultMessage: \"Our Compassionate Care Program\",\n },\n compassionateCareDialogDesc: {\n id: \"compassionateCareDialogDesc\",\n defaultMessage:\n \"We understand genetic testing may pose a financial hardship to some people. Patients who qualify for our compassionate care program receive a reduced genetic testing bill and may owe nothing, depending on their financial situation.\",\n },\n compassionateCareDialogBack: {\n id: \"compassionateCareDialogBack\",\n defaultMessage: \"Go Back\",\n },\n compassionateCareDialogApply: {\n id: \"compassionateCareDialogApply\",\n defaultMessage: \"Apply Now\",\n },\n compassionateCareDialogFooterText: {\n id: \"compassionateCareDialogFooterText\",\n defaultMessage:\n \"Our program criteria is based on U.S. Federal Poverty guidelines published by the Department of Health and Human Services, and applies to patient families with annual household income up to 4x the Federal Poverty Line.\",\n },\n});\n\ninterface CompassionateCareDialogProps {\n onCloseDialog: () => void;\n}\n\nconst CompassionateCareDialog: FC = ({\n onCloseDialog,\n}) => {\n const intl = useIntl();\n const { config } = useContext(ConfigContext);\n\n const handleApply = () => {\n openNewWindow(config.links.COMPASSIONATE_CARE);\n onCloseDialog();\n };\n\n return (\n \n );\n};\n\nexport default CompassionateCareDialog;\n","export { default } from \"./compassionateCareDialog\";\n","import React, { FC, ReactElement, useContext, useRef } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { DateRange as RangeModifier } from \"@natera/material/lib/date\";\nimport { TestHistoryContext } from \"@app/provider\";\nimport DayRangePicker from \"@app/components/dayRangePicker\";\nimport { handleKeyDownByRef } from \"@app/utils/handleKeyDown\";\n\nimport \"./dateRange.scss\";\n\nconst messages = defineMessages({\n selectDateRange: {\n id: \"selectDateRange\",\n defaultMessage: \"Select date range\",\n },\n});\n\ninterface Props {\n content?: ReactElement;\n actions?: ReactElement;\n handleClose?: () => undefined;\n rangeDate: (date$: RangeModifier) => void;\n}\n\nconst DateRange: FC = ({ rangeDate }) => {\n const intl = useIntl();\n const [day, setDay] = React.useState(undefined);\n const { getTestHistory, reset } = useContext(TestHistoryContext);\n\n const divRef = useRef(null);\n\n const onSelectRange = (date$: RangeModifier) => {\n setDay(date$);\n rangeDate(date$);\n\n if (date$) {\n date$.from?.setHours(0, 0, 0, 0);\n date$.to?.setHours(23, 59, 59, 999);\n getTestHistory(date$.from, date$.to, 0);\n } else {\n reset();\n getTestHistory();\n }\n };\n\n return (\n \n \n
\n );\n};\n\nexport default DateRange;\n","export { default } from \"./dateRange\";\n","import React from \"react\";\nimport { Textfield } from \"@natera/form\";\nimport CalendarIcon from \"@assets/svg/icons/calendar.svg\";\nimport classNames from \"classnames\";\nimport {\n DateRange as RangeModifier,\n DayRangePickerWrapper,\n} from \"@natera/material/lib/date\";\nimport { defineMessages } from \"react-intl\";\nimport Svg from \"@natera/material/lib/svg\";\nimport { handleKeyDownByMenu } from \"@app/utils/handleKeyDown\";\nimport { weekDayFormatter } from \"@app/utils\";\n\n// overrides @natera/material/lib/date Range picker component translations\nconst messages = defineMessages({\n materialInputMaskPlaceholder: {\n id: \"material.inputMask.placeholder\",\n defaultMessage: \"MM/DD/YYYY\",\n },\n materialRangePlaceholder: {\n id: \"material.range.placeholder\",\n defaultMessage: \"MM/DD/YYYY - MM/DD/YYYY\",\n },\n materialRangeFrom: {\n id: \"material.range.from\",\n defaultMessage: \"From\",\n },\n materialRangeTo: {\n id: \"material.range.to\",\n defaultMessage: \"To\",\n },\n materialRangeClear: {\n id: \"material.range.clear\",\n defaultMessage: \"Clear\",\n },\n materialRangeCancel: {\n id: \"material.range.cancel\",\n defaultMessage: \"Cancel\",\n },\n materialRangeOk: {\n id: \"material.range.ok\",\n defaultMessage: \"Apply\",\n },\n materialRangePreviousMonth: {\n id: \"material.date.previousMonth\",\n defaultMessage: \"Previous month\",\n },\n materialRangeNextMonth: {\n id: \"material.date.nextMonth\",\n defaultMessage: \"Next month\",\n },\n});\n\ninterface Props {\n name: string;\n value?: string;\n onSelectRange: (date$: RangeModifier) => void;\n}\n\nconst DayRangePicker: React.FunctionComponent = ({\n name,\n value,\n onSelectRange,\n}) => {\n return (\n \n {(menu) => (\n <>\n \n }\n onClick={menu.toggleMenu}\n onKeyDown={handleKeyDownByMenu(menu)}\n value={value}\n readOnly\n fullWidth\n />\n \n >\n )}\n \n );\n};\n\nexport default DayRangePicker;\n","import React, { FC } from \"react\";\nimport { Link } from \"@natera/navigation\";\nimport Svg from \"@natera/material/lib/svg\";\nimport \"./detailInformationButton.scss\";\n\nexport interface DetailInformationButtonProps {\n route: string;\n name: string;\n startIcon: string;\n endIcon: string;\n}\n\nconst DetailInformationButton: FC = ({\n route,\n name,\n startIcon,\n endIcon,\n}) => {\n return (\n \n \n {name}
\n \n \n );\n};\n\nexport default DetailInformationButton;\n","export { default } from \"./detailInformationButton\";\n","import React, { FC } from \"react\";\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Button } from \"@natera/form\";\nimport \"./cancelAppointmentDialog.scss\";\n\nconst messages = defineMessages({\n cancelAppointmentDialogTitle: {\n id: \"cancelAppointmentDialogTitle\",\n defaultMessage: \"Would you like to cancel your appointment?\",\n },\n cancelAppointmentDialogContent: {\n id: \"cancelAppointmentDialogContent\",\n defaultMessage: \"Your blood draw appointment will be cancelled\",\n },\n cancelAppointmentDialogCancelAppointmentButton: {\n id: \"cancelAppointmentDialogCancelAppointmentButton\",\n defaultMessage: \"Cancel Appointment\",\n },\n cancelAppointmentDialogKeepAppointmentButton: {\n id: \"cancelAppointmentDialogKeepAppointmentButton\",\n defaultMessage: \"Keep Appointment\",\n },\n});\n\ninterface CancelAppointmentDialogProps {\n onClickCancel: () => Promise;\n onClose: () => void;\n}\n\nconst CancelAppointmentDialog: FC = ({\n onClickCancel,\n onClose,\n}) => {\n const intl = useIntl();\n\n const [cancelLoading, setCancelLoading] = React.useState(false);\n\n const header = intl.formatMessage(messages.cancelAppointmentDialogTitle);\n\n const content = (\n {intl.formatMessage(messages.cancelAppointmentDialogContent)}
\n );\n\n const handleCancel = async () => {\n try {\n setCancelLoading(true);\n await onClickCancel();\n } finally {\n setCancelLoading(false);\n onClose();\n }\n };\n\n const actions = (\n <>\n \n \n >\n );\n\n return (\n \n );\n};\n\nexport default CancelAppointmentDialog;\n","import React, { FC, useContext, useMemo } from \"react\";\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { IntlContext } from \"@app/provider\";\nimport { Button } from \"@natera/form\";\nimport { BusinessUnits } from \"@app/provider/drawRequest\";\nimport { contactPhoneMapper } from \"@app/utils/contactPhoneMapper\";\n\nimport \"./cancelAppointmentDialogFail.scss\";\n\nconst messages = defineMessages({\n cancelAppointmentDialogFailTitle: {\n id: \"cancelAppointmentDialogFailTitle\",\n defaultMessage: \"Apologies\",\n },\n cancelAppointmentDialogFailText: {\n id: \"cancelAppointmentDialogFailText\",\n defaultMessage:\n \"We are unable to cancel your appointment request at this time.\",\n },\n cancelAppointmentDialogFailTextContact: {\n id: \"cancelAppointmentDialogFailTextContact\",\n defaultMessage: \"Please contact us to get help\",\n },\n cancelAppointmentDialogFailTextContactWH: {\n id: \"cancelAppointmentDialogFailTextContactWH\",\n defaultMessage: \"Please contact us to get help\",\n },\n cancelAppointmentDialogFailBackButton: {\n id: \"cancelAppointmentDialogFailBackButton\",\n defaultMessage: \"Back\",\n },\n cancelAppointmentDialogFailCrossButtonLabel: {\n id: \"cancelAppointmentDialogFailCrossButtonLabel\",\n defaultMessage: \"Close\",\n },\n});\n\ninterface CancelAppointmentDialogFailProps {\n onClose: () => void;\n businessUnit?: BusinessUnits;\n}\n\nconst CancelAppointmentDialogFail: FC = ({\n onClose,\n businessUnit = BusinessUnits.ORGAN_HEALTH,\n}) => {\n const intl = useIntl();\n\n const header = intl.formatMessage(messages.cancelAppointmentDialogFailTitle);\n const { currentLanguage } = useContext(IntlContext);\n\n const appointmentDialogFailTextContact = useMemo(() => {\n switch (businessUnit) {\n case BusinessUnits.WOMENS_HEALTH:\n return intl.formatMessage(\n messages.cancelAppointmentDialogFailTextContactWH\n );\n default:\n return intl.formatMessage(\n messages.cancelAppointmentDialogFailTextContact\n );\n }\n }, [businessUnit, currentLanguage]);\n\n const content = (\n <>\n \n {intl.formatMessage(messages.cancelAppointmentDialogFailText)}\n \n
\n {appointmentDialogFailTextContact}\n
\n {contactPhoneMapper(businessUnit)}\n >\n );\n\n const actions = (\n \n );\n\n const altText = intl.formatMessage(\n messages.cancelAppointmentDialogFailCrossButtonLabel\n );\n\n return (\n \n );\n};\n\nexport default CancelAppointmentDialogFail;\n","import React, { FC } from \"react\";\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Button } from \"@natera/form\";\n\nconst messages = defineMessages({\n cancelAppointmentDialogSuccessTitle: {\n id: \"cancelAppointmentDialogSuccessTitle\",\n defaultMessage: \"Your appointment has been successfully cancelled\",\n },\n cancelAppointmentDialogSuccessBackButton: {\n id: \"cancelAppointmentDialogSuccessBackButton\",\n defaultMessage: \"Back\",\n },\n});\n\ninterface CancelAppointmentDialogSuccessProps {\n onClose: () => void;\n}\n\nconst CancelAppointmentDialogSuccess: FC = ({\n onClose,\n}) => {\n const intl = useIntl();\n\n const header = intl.formatMessage(\n messages.cancelAppointmentDialogSuccessTitle\n );\n\n const actions = (\n \n );\n\n return (\n \n );\n};\n\nexport default CancelAppointmentDialogSuccess;\n","export { default as CancelAppointmentDialog } from \"./cancelAppointmentDialog\";\nexport { default as CancelAppointmentDialogFail } from \"./cancelAppointmentDialogFail\";\nexport { default as CancelAppointmentDialogSuccess } from \"./cancelAppointmentDialogSuccess\";\n","import React, { FC } from \"react\";\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Button } from \"@natera/form\";\nimport \"./cancelSimpleOrderTestDialogFail.scss\";\n\nconst messages = defineMessages({\n cancelSimpleOrderTestDialogFailTitle: {\n id: \"cancelSimpleOrderTestDialogFailTitle\",\n defaultMessage: \"We are currently experiencing a service disruption.\",\n },\n cancelSimpleOrderTestDialogFailText1: {\n id: \"cancelSimpleOrderTestDialogFailText1\",\n defaultMessage: \"We apologize for the inconvenience.\",\n },\n cancelSimpleOrderTestDialogFailText2: {\n id: \"cancelSimpleOrderTestDialogFailText2\",\n defaultMessage: \"Please try again later.\",\n },\n cancelSimpleOrderTestDialogFailOKButton: {\n id: \"cancelSimpleOrderTestDialogFailOKButton\",\n defaultMessage: \"Ok\",\n },\n});\n\ninterface Props {\n onClose: () => void;\n}\n\nconst CancelSimpleOrderTestDialogFail: FC = ({ onClose }) => {\n const intl = useIntl();\n\n const header = intl.formatMessage(\n messages.cancelSimpleOrderTestDialogFailTitle\n );\n\n const content = (\n <>\n \n {intl.formatMessage(messages.cancelSimpleOrderTestDialogFailText1)}\n \n
\n \n {intl.formatMessage(messages.cancelSimpleOrderTestDialogFailText2)}\n \n >\n );\n\n const actions = (\n \n );\n\n return (\n \n );\n};\n\nexport default CancelSimpleOrderTestDialogFail;\n","export { default as CancelSimpleOrderTestDialogFail } from \"./cancelSimpleOrderTestDialogFail\";\n","export {\n CancelAppointmentDialog,\n CancelAppointmentDialogFail,\n CancelAppointmentDialogSuccess,\n} from \"./cancelAppointmentDialogs\";\n\nexport { CancelSimpleOrderTestDialogFail } from \"./cancelSimpleOrderTestDialog\";\n","import React, { FC } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { Button } from \"@natera/form\";\n\nimport { useNavigate } from \"react-router-dom\";\nimport { routes } from \"@app/routing\";\nimport \"./drawRequestDialog.scss\";\n\nconst messages = defineMessages({\n drawRequestBack: {\n id: \"drawRequestBack\",\n defaultMessage: \"Back To Home\",\n },\n});\n\ninterface DrawRequestDialogProps {\n title: string;\n description?: string;\n}\n\nconst DrawRequestDialog: FC = ({\n title,\n description,\n}) => {\n const intl = useIntl();\n const navigate = useNavigate();\n\n const handleBack = () => {\n navigate(routes.home);\n };\n\n return (\n \n
\n
\n );\n};\n\nexport default DrawRequestDialog;\n","export { default } from \"./drawRequestDialog\";\n","import React from \"react\";\nimport classNames from \"classnames\";\n\nimport \"./dropdownWrapper.scss\";\n\nexport interface DropdownWrapperProps\n extends React.HTMLAttributes {\n isOpen?: boolean;\n}\n\nexport const DropdownWrapper: React.FC = ({\n isOpen = false,\n children,\n ...props\n}) => {\n return (\n \n {children}\n
\n );\n};\n\nexport default DropdownWrapper;\n","export {\n default,\n DropdownWrapper,\n DropdownWrapperProps,\n} from \"./dropdownWrapper\";\n","import React, { FC, useContext, useState } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport useIsMobileDimension from \"../../hooks/useIsMobileDimension\";\nimport EmpowerAlertImage from \"@assets/images/empower_alert_image.png\";\nimport { VideoPlayer } from \"@app/components\";\nimport {\n ConfigContext,\n IntlContext,\n Language,\n NotificationContext,\n} from \"@app/provider\";\nimport Dialog from \"@natera/material/lib/dialog\";\nimport R from \"ramda\";\n\nimport Svg from \"@natera/material/lib/svg\";\nimport EmailSvg from \"@assets/svg/icons/email2.svg\";\nimport PhoneSvg from \"@assets/svg/icons/phone.svg\";\n\nimport \"./empowerAlertDialog.scss\";\n\nconst messages = defineMessages({\n empowerAlertPageTitle: {\n id: \"empowerAlertPageTitle\",\n defaultMessage: \"Hereditary Cancer Testing\",\n },\n empowerAlertPageHeader: {\n id: \"empowerAlertPageHeader\",\n defaultMessage: \"Understand Your Risk. Take Control of Your Health.\",\n },\n empowerAlertPageDescription: {\n id: \"empowerAlertPageDescription\",\n defaultMessage:\n \"{hereditaryCancerTesting} is an important tool to understand your risk for certain cancers and take steps toward proactive care. If you’ve been diagnosed with cancer, knowing whether you have a hereditary cancer-related gene mutation can help guide your treatment, inform surgical decisions, prevent future cancers, and even provide insights for your family members.\",\n },\n empowerAlertPageDescriptionLinkText: {\n id: \"empowerAlertPageDescriptionLinkText\",\n defaultMessage: \"Hereditary cancer testing\",\n },\n empowerAlertPageHereditaryCancerVideoText: {\n id: \"empowerAlertPageHereditaryCancerVideoText\",\n defaultMessage: \"Getting Started with the Empower Hereditary Cancer Test\",\n },\n empowerAlertPageEligibilityHeader: {\n id: \"empowerAlertPageEligibilityHeader\",\n defaultMessage: \"Am I eligible?\",\n },\n empowerAlertPageEligibilityInfo: {\n id: \"empowerAlertPageEligibilityInfo\",\n defaultMessage:\n \"Based on your personal and family history provided to Natera, you meet national criteria for hereditary cancer testing. The general criteria for hereditary cancer testing include:\",\n },\n empowerAlertPageEligibilityInfoItem1: {\n id: \"empowerAlertPageEligibilityInfoItem1\",\n defaultMessage: \"Being diagnosed with breast cancer at age 65 or younger.\",\n },\n empowerAlertPageEligibilityInfoItem2: {\n id: \"empowerAlertPageEligibilityInfoItem2\",\n defaultMessage:\n \"Being diagnosed with colorectal, ovarian, endometrial, uterine, or pancreatic cancer at any age.\",\n },\n empowerAlertPageNextStepsHeader: {\n id: \"empowerAlertPageNextStepsHeader\",\n defaultMessage: \"What Are the Next Steps?\",\n },\n empowerAlertPageNextStepsImageAltText: {\n id: \"empowerAlertPageNextStepsImageAltText\",\n defaultMessage: \"Next steps image\",\n },\n empowerAlertPageNextStepsItem1: {\n id: \"empowerAlertPageNextStepsItem1\",\n defaultMessage:\n \"Talk to your healthcare provider about whether hereditary cancer testing is right for you.\",\n },\n empowerAlertPageNextStepsItem2: {\n id: \"empowerAlertPageNextStepsItem2\",\n defaultMessage:\n \"Ask your healthcare provider to request an Empower test with your next Signatera test.\",\n },\n empowerAlertPageNextStepsItem3: {\n id: \"empowerAlertPageNextStepsItem3\",\n defaultMessage:\n \"Once approved, you’ll receive a simple testing kit to collect your sample, which will be analyzed in our lab.\",\n },\n empowerAlertPageCancerTestingHeader: {\n id: \"empowerAlertPageCancerTestingHeader\",\n defaultMessage: \"Why Consider Hereditary Cancer Testing?\",\n },\n empowerAlertPageCancerTestingItem1: {\n id: \"empowerAlertPageCancerTestingItem1\",\n defaultMessage:\n \"Personalized Treatment Options: Certain treatments, like PARP inhibitors or specific chemotherapies, work better for individuals with hereditary mutations.\",\n },\n empowerAlertPageCancerTestingItem2: {\n id: \"empowerAlertPageCancerTestingItem2\",\n defaultMessage:\n \"Proactive Care for You and Your Family: Understanding your genetic risk can help guide screening and preventive strategies for you and your loved ones.\",\n },\n empowerAlertPageCancerTestingItem3: {\n id: \"empowerAlertPageCancerTestingItem3\",\n defaultMessage:\n \"Surgical Guidance: Genetic insights can inform decisions about surgery, such as risk-reducing procedures.\",\n },\n empowerAlertPageCancerTestingItem4: {\n id: \"empowerAlertPageCancerTestingItem4\",\n defaultMessage:\n \"Prevent Future Cancers: Certain hereditary cancer-related gene mutations can increase the risk for other cancers. Knowing early can empower you to take action for earlier screening and prevention.\",\n },\n empowerAlertPageHowItWorksHeader: {\n id: \"empowerAlertPageHowItWorksHeader\",\n defaultMessage: \"How Empower Works\",\n },\n empowerAlertPageHowItWorksDescription: {\n id: \"empowerAlertPageHowItWorksDescription\",\n defaultMessage:\n \"Natera’s Empower™ hereditary cancer testing is designed to provide clear answers you can act on, with:\",\n },\n empowerAlertPageHowItWorksItems1: {\n id: \"empowerAlertPageHowItWorksItems1\",\n defaultMessage:\n \"Convenient Testing: Provide a single blood or saliva sample, and Natera works with your clinic to deliver it to our lab for quick and thorough testing.\",\n },\n empowerAlertPageHowItWorksItems2: {\n id: \"empowerAlertPageHowItWorksItems2\",\n defaultMessage:\n \"Concise Reporting: Easy-to-understand results that align with the latest medical guidelines.\",\n },\n empowerAlertPageHowItWorksItems3: {\n id: \"empowerAlertPageHowItWorksItems3\",\n defaultMessage:\n \"Comprehensive Support: Access to Natera’s board-certified genetic counselors for pre- and post-test information.\",\n },\n empowerAlertPageHowItWorksItems4: {\n id: \"empowerAlertPageHowItWorksItems4\",\n defaultMessage:\n \"Affordability: In-network coverage with many insurance plans and robust billing support programs.\",\n },\n empowerAlertPageTestimonialsHeader: {\n id: \"empowerAlertPageTestimonialsHeader\",\n defaultMessage: \"Testimonials\",\n },\n empowerAlertPageTestimonialsFirstVideoTitle: {\n id: \"empowerAlertPageTestimonialsFirstVideoTitle\",\n defaultMessage: \"Alicia’s Story\",\n },\n empowerAlertPageTestimonialsFirstVideoText: {\n id: \"empowerAlertPageTestimonialsFirstVideoText\",\n defaultMessage:\n \"Hear from Alicia about how her Lynch Syndrome diagnosis put a name to her family’s cancer history and helped find her cancer early.\",\n },\n empowerAlertPageHelpHeader: {\n id: \"empowerAlertPageHelpHeader\",\n defaultMessage: \"We’re here to help!\",\n },\n empowerAlertPageHelpDescription: {\n id: \"empowerAlertPageHelpDescription\",\n defaultMessage:\n \"For more information, contact us to speak with our Patient Coordinator team\",\n },\n empowerAlertPageHelpPhone: {\n id: \"empowerAlertPageHelpPhone\",\n defaultMessage: \"650.446.4657\",\n },\n});\n\ninterface EmpowerAlertDialogProps {\n onCloseDialog: () => void;\n}\n\nconst EmpowerAlertDialog: FC = ({ onCloseDialog }) => {\n const intl = useIntl();\n const isMobile = useIsMobileDimension();\n const { currentLanguage } = React.useContext(IntlContext);\n const { config } = React.useContext(ConfigContext);\n const { clear } = useContext(NotificationContext);\n\n const [isClosing, setIsClosing] = useState(false);\n const [firstVideoUrl, setFirstVideoUrl] = useState(\"\");\n\n const HEREDITARY_CANCER_VIDEO_LINK =\n config.links.EMPOWER_HEREDITARY_CANCER_VIDEO_LINK[\n currentLanguage === Language.EN ? \"EN\" : \"ES\"\n ] || \"\";\n\n const TESTIMONIALS_VIDEO = {\n firstStory: \"https://natera.wistia.com/medias/1qrg3qvucb\",\n };\n\n React.useEffect(() => {\n const loadVideoUrls = async () => {\n const firstUrl = R.last(TESTIMONIALS_VIDEO.firstStory.split(\"/\")) ?? \"\";\n if (firstUrl) {\n setFirstVideoUrl(firstUrl);\n }\n };\n loadVideoUrls();\n }, []);\n\n React.useEffect(() => {\n if (isMobile) {\n document\n .querySelector(\".empower-alert-dialog.mobile\")\n ?.classList.add(\"animate-up\");\n }\n }, [isMobile]);\n\n const handleClose = () => {\n setIsClosing(true);\n setTimeout(() => {\n clear();\n onCloseDialog();\n }, 600);\n };\n\n return (\n \n );\n};\n\nexport default EmpowerAlertDialog;\n","export { default } from \"./empowerAlertDialog\";\n","import React, { FC, useContext, useState } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport \"./empowerAlertPopUp.scss\";\nimport useIsMobileDimension from \"../../hooks/useIsMobileDimension\";\nimport { HEAP_EVENTS } from \"@app/provider/types\";\nimport { NotificationContext, UserContext } from \"@app/provider\";\nimport Dialog from \"@natera/material/lib/dialog\";\nimport Button from \"@natera/material/lib/button\";\nimport ResponceImage from \"@assets/images/renewalPatientResponce.png\";\n\nconst messages = defineMessages({\n empowerAlertPopUpTitle: {\n id: \"empowerAlertPopUpTitle\",\n defaultMessage:\n \"Are you interested in learning more about hereditary cancer testing?\",\n },\n empowerAlertPopUpAgreeButton: {\n id: \"empowerAlertPopUpAgreeButton\",\n defaultMessage: \"Yes, I’d like to know if testing is right for me\",\n },\n empowerAlertPopUpDisagreeButton: {\n id: \"empowerAlertPopUpDisagreeButton\",\n defaultMessage:\n \"No, I am not interested in learning more about hereditary cancer testing\",\n },\n empowerAlertPopUpGratitude: {\n id: \"empowerAlertPopUpGratitude\",\n defaultMessage: \"Thanks for your response\",\n },\n});\n\ninterface EmpowerAlertPopUpProps {\n onCloseDialog: () => void;\n limsId?: number;\n orderUid?: string;\n}\n\nconst EmpowerAlertPopUp: FC = ({\n onCloseDialog,\n limsId,\n}) => {\n const intl = useIntl();\n const isMobile = useIsMobileDimension();\n const { uppUser } = useContext(UserContext);\n const { clear } = useContext(NotificationContext);\n\n const [activeDialog, setActiveDialog] = useState<\"first\" | \"second\" | null>(\n \"first\"\n );\n const [closingDialog, setClosingDialog] = useState<\"first\" | \"second\" | null>(\n null\n );\n const animationDuration = 600;\n\n React.useEffect(() => {\n if (isMobile && activeDialog) {\n const element = document.querySelector(`.popUp-dialog.mobile`);\n if (element) {\n element.classList.add(\"animate-up\");\n }\n }\n }, [isMobile, activeDialog]);\n\n const handleCloseFirstDialog = () => {\n setClosingDialog(\"first\");\n setTimeout(() => {\n setActiveDialog(\"second\");\n setClosingDialog(null);\n }, animationDuration);\n };\n\n const handleCloseSecondDialog = () => {\n setClosingDialog(\"second\");\n setTimeout(() => {\n clear();\n onCloseDialog();\n }, animationDuration);\n };\n\n const handleAgree = () => {\n heap.track(HEAP_EVENTS.upp_empower_risk_yes_interested, {\n identity: uppUser?.patientUID,\n lims_clinic_id: limsId,\n });\n handleCloseFirstDialog();\n };\n\n const handleDisagree = () => {\n heap.track(HEAP_EVENTS.upp_empower_risk_not_interested, {\n identity: uppUser?.patientUID,\n lims_clinic_id: limsId,\n });\n handleCloseFirstDialog();\n };\n\n return (\n <>\n {activeDialog === \"first\" && (\n \n )}\n\n {activeDialog === \"second\" && (\n \n )}\n >\n );\n};\n\nexport default EmpowerAlertPopUp;\n","export { default } from \"./empowerAlertPopUp\";\n","import React, { useEffect } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport {\n ErrorProvider,\n MfaSetupContext,\n ProfileContext,\n UserContext,\n} from \"@app/provider\";\nimport { Factor } from \"@app/service/user\";\nimport { useErrorController } from \"@natera/platform/lib/hooks\";\nimport { Button } from \"@natera/form\";\nimport { Switch } from \"@natera/material/lib/switch\";\nimport { Link } from \"@natera/navigation\";\nimport SpinnerView from \"@app/components/spinnerView\";\nimport VerifyCodeForm from \"@app/components/verifyCodeForm\";\nimport { Profile } from \"@app/provider/profile\";\nimport { routes } from \"@app/routing\";\nimport { Svg } from \"@natera/material/lib/svg\";\nimport InfoIcon from \"@assets/svg/icons/info.svg\";\nimport FactorList from \"@app/components/factorList/factorList\";\nimport { HeapEventLocation } from \"@app/provider/types\";\nimport \"./factorList.scss\";\n\nconst messages = defineMessages({\n factorListTitle: {\n id: \"factorListTitle\",\n defaultMessage: \"Two - Factor Authentication\",\n },\n factorListSwitcher: {\n id: \"factorListSwitcher\",\n defaultMessage: \"Turn on two - factor authentication\",\n },\n factorListDescription: {\n id: \"factorListDescription\",\n defaultMessage:\n \"If you turn on two - factor authentication, each time you log in you'll verify your identify with: \",\n },\n factorListSetUp: {\n id: \"factorListSetUp\",\n defaultMessage: \"Set Up\",\n },\n factorListUpdate: {\n id: \"factorListUpdate\",\n defaultMessage: \"Update\",\n },\n factorListCancel: {\n id: \"factorListCancel\",\n defaultMessage: \"Cancel\",\n },\n factorListSkip: {\n id: \"factorListSkip\",\n defaultMessage: \"Skip\",\n },\n factorListPassword: {\n id: \"factorListPassword\",\n defaultMessage: \"Your password\",\n },\n factorListCodeSent: {\n id: \"factorListCodeSent\",\n defaultMessage: \"A code sent to a device, like your phone\",\n },\n factorListIncorrectActivationCode: {\n id: \"factorListIncorrectActivationCode\",\n defaultMessage: \"Incorrect code.\",\n },\n factorListInfo: {\n id: \"factorListInfo\",\n defaultMessage: \"You can update your phone number or email\",\n },\n factorListInfoLink: {\n id: \"factorListInfoLink\",\n defaultMessage: \"here\",\n },\n});\n\ninterface Props {\n profile?: Profile;\n isFirstSetup?: boolean;\n isConfirmation?: boolean;\n phone?: string;\n}\n\nconst FactorContainer: React.FunctionComponent = ({\n profile,\n isConfirmation,\n phone,\n}) => {\n const intl = useIntl();\n const { loadProfile, isLoading } = React.useContext(UserContext);\n\n const [isActive, setIsActive] = React.useState(false);\n const [isForcedViaPhone, setIsForcedViaPhone] = React.useState(false);\n const [selectedFactor, setSelectedFactor] = React.useState();\n const errorController = useErrorController();\n\n const { getProfileIsLoading } = React.useContext(ProfileContext);\n\n const {\n isLoading: isFactorLoading,\n enrolledFactor,\n areFactorsActive,\n isFirstSetup,\n factorsObject,\n handleSkip,\n activateUserFactor,\n loadFactorList,\n resendUserFactorCode,\n handleFactorSetup,\n resetActivatedFactor,\n } = React.useContext(MfaSetupContext);\n\n useEffect(() => {\n setIsActive(areFactorsActive);\n if (areFactorsActive) {\n loadProfile();\n }\n }, [areFactorsActive]);\n\n useEffect(() => {\n loadFactorList();\n if (isFirstSetup && !isConfirmation) {\n setIsForcedViaPhone(true);\n setIsActive(true);\n } else {\n resetActivatedFactor();\n }\n return () => resetActivatedFactor();\n }, []);\n\n const setupFactor: React.FormEventHandler = async (e) => {\n e.preventDefault();\n handleFactorSetup(selectedFactor, isActive);\n };\n\n const handleCode = async (code: string) => {\n try {\n const heapEventLocation = isFirstSetup\n ? HeapEventLocation.accountCreation\n : HeapEventLocation.patientProfile;\n await activateUserFactor(code, heapEventLocation);\n } catch (error) {\n errorController.setValidationError(\n \"code\",\n intl.formatMessage(messages.factorListIncorrectActivationCode)\n );\n }\n };\n\n const handleSwitchClick = () => {\n setIsActive(!isActive);\n setSelectedFactor(undefined);\n };\n\n const skipBtnText = isFirstSetup\n ? messages.factorListSkip\n : messages.factorListCancel;\n\n const isSubmitActive = !!selectedFactor || (!isActive && areFactorsActive);\n\n return (\n <>\n \n {enrolledFactor ? (\n \n \n \n ) : (\n \n {!isFirstSetup && (\n
{intl.formatMessage(messages.factorListTitle)}
\n )}\n
\n
\n
{intl.formatMessage(messages.factorListSwitcher)}
\n
\n
{intl.formatMessage(messages.factorListDescription)}
\n
\n - {intl.formatMessage(messages.factorListPassword)}
\n - {intl.formatMessage(messages.factorListCodeSent)}
\n
\n
\n
\n
\n
\n\n
\n
\n )}\n >\n );\n};\n\nexport default FactorContainer;\n","import React, { FC } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Dialog } from \"@natera/platform/lib/components/dialog\";\nimport { Button } from \"@natera/form\";\nimport \"./factorList.scss\";\n\nconst messages = defineMessages({\n factorDisableMessageTitle: {\n id: \"factorDisableMessageTitle\",\n defaultMessage:\n \"Are you sure you want to turn off two - factor authentication?\",\n },\n factorDisableMessage: {\n id: \"factorDisableMessage\",\n defaultMessage:\n \"Please confirm you want to turn off two - factor authentication.\",\n },\n factorDisableCancelButton: {\n id: \"factorDisableCancelButton\",\n defaultMessage: \"Cancel\",\n },\n factorDisableSubmitButton: {\n id: \"factorDisableSubmitButton\",\n defaultMessage: \"Turn Off\",\n },\n});\n\ninterface FactorDisableDialogProps {\n onClose: () => void;\n onSubmit: () => void;\n}\n\nconst FactorDisableModal: FC = ({\n onClose,\n onSubmit,\n}) => {\n const intl = useIntl();\n\n return (\n \n );\n};\n\nexport default FactorDisableModal;\n","import React from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Factor, FACTORS_TO_SHOW } from \"@app/service/user\";\nimport { RadioGroup, RadioButton } from \"@natera/form\";\nimport { Profile } from \"@app/provider/profile\";\nimport { maskPhone } from \"@app/utils\";\nimport { FactorsObject } from \"@app/provider/mfaSetup\";\nimport \"./factorList.scss\";\n\nconst messages = defineMessages({\n factorListSmsTitle: {\n id: \"factorListSmsTitle\",\n defaultMessage: \"Text Message\",\n },\n factorListSmsDescription: {\n id: \"factorListSmsDescription\",\n defaultMessage:\n \"You will receive the security code via text message. Text or data rates may apply.\",\n },\n factorListEmailTitle: {\n id: \"factorListEmailTitle\",\n defaultMessage: \"Email\",\n },\n factorListEmailDescription: {\n id: \"factorListEmailDescription\",\n defaultMessage: \"You will receive the security code via email.\",\n },\n factorListCallTitle: {\n id: \"factorListCallTitle\",\n defaultMessage: \"Phone Call\",\n },\n factorListCallDescription: {\n id: \"factorListCallDescription\",\n defaultMessage: \"You will receive a phone call to {phone}\",\n },\n});\n\ninterface FactorList {\n [key: string]: {\n title: { id: string; defaultMessage: string };\n description: { id: string; defaultMessage: string };\n };\n}\n\nexport const FACTOR_LIST: FactorList = {\n call: {\n title: messages.factorListCallTitle,\n description: messages.factorListCallDescription,\n },\n email: {\n title: messages.factorListEmailTitle,\n description: messages.factorListEmailDescription,\n },\n sms: {\n title: messages.factorListSmsTitle,\n description: messages.factorListSmsDescription,\n },\n};\n\ninterface Props {\n profile?: Profile;\n factorsObject: FactorsObject;\n isForcedViaPhone: boolean;\n setSelectedFactor: (prop: Factor | undefined) => void;\n phone?: string;\n}\n\nconst FactorList: React.FunctionComponent = ({\n profile,\n factorsObject,\n isForcedViaPhone,\n setSelectedFactor,\n phone,\n}) => {\n const intl = useIntl();\n const userPhone = profile?.phone ? profile.phone : phone;\n\n const handleFactorSelect = (factorType: FACTORS_TO_SHOW) => {\n setSelectedFactor(factorsObject[factorType]);\n };\n\n const renderItem = (factorType: FACTORS_TO_SHOW) => {\n if (isForcedViaPhone && factorType === FACTORS_TO_SHOW.email) return null;\n\n const factorText = factorType in FACTOR_LIST && FACTOR_LIST[factorType];\n\n if (!factorText) return null;\n\n return (\n \n \n {intl.formatMessage(factorText.title)}\n
\n \n {intl.formatMessage(factorText.description, {\n phone: maskPhone(userPhone),\n })}\n
\n >\n }\n value={factorType}\n />\n );\n };\n\n const renderFactors = () => {\n if (Object.values(factorsObject).length > 0) {\n return Object.keys(factorsObject).map((factorType: FACTORS_TO_SHOW) =>\n renderItem(factorType)\n );\n }\n };\n\n return (\n \n \n {renderFactors()}\n \n
\n );\n};\n\nexport default FactorList;\n","import React, { FC, useContext } from \"react\";\nimport { useLocation, useNavigate } from \"react-router-dom\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { FACTORS_TO_SHOW } from \"@app/service/user\";\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { Button } from \"@natera/form\";\nimport { Svg } from \"@natera/material/lib/svg\";\nimport DoneIcon from \"@assets/svg/icons/done.svg\";\nimport { routes } from \"@app/routing\";\nimport { UserContext } from \"@app/provider\";\n\nimport \"./factorList.scss\";\n\nconst messages = defineMessages({\n factorSuccessMessageTitle: {\n id: \"factorSuccessMessageTitle\",\n defaultMessage: \"verified\",\n },\n factorSuccessMessageTitleEmail: {\n id: \"factorSuccessMessageTitleEmail\",\n defaultMessage: \"Email address\",\n },\n factorSuccessMessageTitleSms: {\n id: \"factorSuccessMessageTitleSms\",\n defaultMessage: \"Phone number\",\n },\n factorSuccessMessageText: {\n id: \"factorSuccessMessageText\",\n defaultMessage: \"Two - factor authentication is now active.\",\n },\n factorSuccessMessageSubmit: {\n id: \"factorSuccessMessageSubmit\",\n defaultMessage: \"Go to My Dashboard\",\n },\n});\n\ninterface FactorSuccessModalProps extends React.HTMLAttributes {\n type: FACTORS_TO_SHOW;\n onClose: () => void;\n}\n\nconst FactorSuccessModal: FC = (props) => {\n const intl = useIntl();\n const navigate = useNavigate();\n const location = useLocation();\n\n const { type, onClose } = props;\n\n const { loadProfile } = useContext(UserContext);\n\n const getTitle = () => {\n switch (type) {\n case FACTORS_TO_SHOW.email:\n return intl.formatMessage(messages.factorSuccessMessageTitleEmail);\n case FACTORS_TO_SHOW.call:\n case FACTORS_TO_SHOW.sms:\n default:\n return intl.formatMessage(messages.factorSuccessMessageTitleSms);\n }\n };\n\n const handleClose = async () => {\n await loadProfile();\n onClose();\n navigate(routes.home + location.search, { replace: true });\n };\n\n return (\n \n );\n};\n\nexport default FactorSuccessModal;\n","export { default } from \"./factorContainer\";\nexport { default as FactorSuccessModal } from \"./factorSuccessModal\";\nexport { default as FactorDisableModal } from \"./factorDisableModal\";\n","import React, { FC, useContext, useState } from \"react\";\nimport { StepperContext } from \"@natera/stepper\";\nimport StepperHeaderProgress from \"@app/components/stepperHeaderProgress\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Button, RadioButton, RadioGroup } from \"@natera/form\";\nimport { StepperContent } from \"@app/components/ui/layout/stepperContent\";\nimport { HEAP_EVENTS } from \"@app/provider/types\";\nimport { getTestNameForHeap } from \"@app/utils\";\nimport { OrderContext } from \"@app/provider/order\";\nimport { Steps } from \"@app/pages/private/simpleOrder\";\nimport {\n FetalSexStepResolve,\n SimpleOrderStepperContext,\n} from \"@app/provider/simpleOrder/SimpleOrderStepperProvider\";\nimport \"./fetalSexInResults.scss\";\n\nconst messages = defineMessages({\n fetalSexInResultsTitle: {\n id: \"fetalSexInResultsTitle\",\n defaultMessage: \"Fetal Sex In Results Selection\",\n },\n fetalSexInResultsSubTitle: {\n id: \"fetalSexInResultsSubTitle\",\n defaultMessage: \"Would you like to see your results with fetal sex?\",\n },\n fetalSexInResultsText: {\n id: \"fetalSexInResultsText\",\n defaultMessage:\n \"Please select whether you would like to include the fetal sex of your baby in your results.\",\n },\n fetalSexInResultsInclude: {\n id: \"fetalSexInResultsInclude\",\n defaultMessage: \"Yes, include fetal sex in my results\",\n },\n fetalSexInResultsNotInclude: {\n id: \"fetalSexInResultsNotInclude\",\n defaultMessage: \"No, do not include fetal sex in my results\",\n },\n fetalSexInResultsNext: {\n id: \"fetalSexInResultsNext\",\n defaultMessage: \"Next\",\n },\n fetalSexInResultsBack: {\n id: \"fetalSexInResultsBack\",\n defaultMessage: \"Back\",\n },\n});\n\nexport enum FetalSexSelection {\n INCLUDE = \"INCLUDE\",\n DO_NOT_INCLUDE = \"DO_NOT_INCLUDE\",\n}\nconst FetalSex: FC = () => {\n const intl = useIntl();\n const { getCurrentStep, getData, goBack, resolve } = React.useContext(\n StepperContext\n );\n const { getStepData, resolveStep } = useContext(SimpleOrderStepperContext);\n\n const currentStepId = getCurrentStep()?.stepId;\n const stepData = currentStepId && getData(currentStepId);\n\n const simpleOrderStepData = getStepData(\n Steps.FETAL_SEX\n ) as FetalSexStepResolve;\n\n const initialReportGenderValue =\n stepData?.reportGender ?? simpleOrderStepData?.reportGender;\n\n const [reportGender, setReportGender] = React.useState(\n initialReportGenderValue\n );\n const [nextButtonIsDisabled, setNextButtonIsDisabled] = useState(\n !initialReportGenderValue\n );\n\n const { orderData } = React.useContext(OrderContext);\n const orderUidPublic = orderData?.orderUidPublic;\n const limsId = orderData?.clinic?.limsId;\n\n const handleSelectionChange = (includeFetalSex: FetalSexSelection) => {\n setNextButtonIsDisabled(false);\n setReportGender(includeFetalSex);\n };\n const handleSubmit = () => {\n resolveStep({ stepId: Steps.FETAL_SEX, stepData: { reportGender } });\n resolve({\n reportGender,\n });\n heap.track(HEAP_EVENTS.upp_simpleorder_fetalsex, {\n tests_ordered: getTestNameForHeap(orderData),\n lims_clinic_id: limsId,\n public_order_uid: orderUidPublic,\n includefetalsex:\n reportGender === FetalSexSelection.INCLUDE ? \"yes\" : \"no\",\n });\n };\n\n const handleBack = () => {\n goBack();\n };\n\n return (\n <>\n \n \n \n \n \n {intl.formatMessage(messages.fetalSexInResultsInclude)}\n
\n }\n value={FetalSexSelection.INCLUDE}\n />\n \n {intl.formatMessage(messages.fetalSexInResultsNotInclude)}\n \n }\n value={FetalSexSelection.DO_NOT_INCLUDE}\n />\n \n \n \n \n \n \n
\n >\n );\n};\n\nexport default FetalSex;\n","export { default } from \"./fetalSexInResults\";\n","import React from \"react\";\nimport FinancialAidIcon from \"@assets/svg/financial-aid.svg\";\nimport { Svg } from \"@natera/material/lib/svg\";\nimport DollarIcon from \"@assets/svg/icons/dollar.svg\";\nimport { Button } from \"@natera/form\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { useDialog } from \"@natera/platform/lib/hooks\";\nimport { CompassionateCareDialog } from \"@app/components\";\n\nimport \"./financialAidCard.scss\";\nimport { HEAP_EVENTS } from \"@app/provider/types\";\nimport { getCardTypeForHeap } from \"../secondaryActionCard/secondaryActionCardParams\";\nimport { SecondaryActionCardType } from \"@app/provider/testData/types\";\n\nconst messages = defineMessages({\n financialAidCardLearnMore: {\n id: \"financialAidCardLearnMore\",\n defaultMessage: \"Learn More\",\n },\n});\n\ntype Props = {\n title: string;\n description: string;\n note?: string;\n showIcon?: boolean;\n showDialog?: boolean;\n limsClinicId?: number;\n};\n\nconst FinancialAidCard: React.FC = ({\n title,\n description,\n note,\n showIcon,\n showDialog,\n limsClinicId,\n}) => {\n const intl = useIntl();\n const compassionateCareDialog = useDialog(CompassionateCareDialog);\n\n const compassionateCareAction = () => {\n compassionateCareDialog.open({\n onCloseDialog: () => compassionateCareDialog.close(),\n });\n heap.track(HEAP_EVENTS.upp_secondarycard_click, {\n card_type: getCardTypeForHeap(SecondaryActionCardType.COMPASSIONATE_CARE),\n lims_clinic_id: limsClinicId,\n });\n };\n\n return (\n <>\n {showDialog && compassionateCareDialog.getDialog()}\n \n {showIcon && (\n
\n )}\n
\n \n
\n
\n
{title}\n
\n {description}\n
\n {note && (\n
{note}
\n )}\n {showDialog && (\n
\n \n
\n )}\n
\n
\n >\n );\n};\n\nexport default FinancialAidCard;\n","export { default } from \"./financialAidCard\";\n","import React, { FC } from \"react\";\nimport { useIntl, defineMessages } from \"react-intl\";\n\nimport \"./flowHeader.scss\";\n\nconst messages = defineMessages({\n flowHeaderTitle: {\n id: \"flowHeaderTitle\",\n defaultMessage: \"Natera’s Patient Portal\",\n },\n});\n\nconst FlowHeader: FC = () => {\n const intl = useIntl();\n\n return (\n \n \n {intl.formatMessage(messages.flowHeaderTitle)}\n
\n \n );\n};\n\nexport default FlowHeader;\n","export { default } from \"./flowHeader\";\n","import React, { FC } from \"react\";\nimport { useIntl } from \"react-intl\";\nimport { useErrorController } from \"@natera/platform/lib/hooks\";\nimport { validateZipCode } from \"@app/utils\";\nimport { messages } from \"./messages\";\nimport { Form } from \"@natera/form\";\nimport { Address } from \"@app/provider/profile\";\nimport {\n StreetAddressField,\n ApartmentUnitField,\n CityField,\n StateField,\n ZipCodeField,\n} from \"@app/components/forms/addressForm/formElements\";\n\ninterface Props {\n address?: Address;\n onSubmit: (address: Partial) => void;\n actions: React.ReactNode;\n}\n\nconst AddressForm: FC = ({ address, onSubmit, actions }) => {\n const intl = useIntl();\n\n const {\n clearErrors,\n getValidationError,\n setValidationError,\n } = useErrorController();\n\n const streetAddress = address?.street1 || \"\";\n const apartmentUnit = address?.street2 || \"\";\n\n const handleSubmit: React.FormEventHandler = (event) => {\n event.preventDefault();\n clearErrors();\n\n const formData = new FormData(event.currentTarget);\n\n const streetAddress = formData.get(\"streetAddress\")?.toString();\n const apartmentUnit = formData.get(\"apartmentUnit\")?.toString();\n const city = formData.get(\"city\")?.toString();\n const state = formData.get(\"state\")?.toString();\n const zipCode = formData.get(\"zipCode\")?.toString();\n\n const addressForm = [\n { title: \"streetAddress\", value: streetAddress && streetAddress.trim() },\n { title: \"city\", value: city && city.trim() },\n { title: \"state\", value: state },\n ];\n\n for (const field of addressForm) {\n if (!field.value) {\n setValidationError(\n field.title,\n intl.formatMessage(messages.addressFormRequired)\n );\n return;\n }\n }\n\n if (!zipCode || !validateZipCode(zipCode)) {\n setValidationError(\n \"zipCode\",\n intl.formatMessage(messages.addressFormInvalidZipCode)\n );\n return;\n }\n\n const newAddress: Partial = {\n city,\n state,\n street1: streetAddress,\n street2: apartmentUnit,\n zipCode,\n };\n if (address) {\n newAddress.uid = address.uid;\n }\n onSubmit(newAddress);\n };\n\n return (\n \n );\n};\n\nexport default AddressForm;\n","import React, { useContext } from \"react\";\nimport { useIntl } from \"react-intl\";\nimport { HeapPHIDecorator } from \"@app/components/analytics\";\nimport { messages } from \"../messages\";\nimport { Textfield } from \"@natera/form\";\nimport { GetValidationError } from \"@natera/platform/lib/hooks/useError\";\nimport { ConfigContext } from \"@app/provider\";\nimport { FormField } from \"@app/components\";\n\nconst ApartmentUnitField: React.FC<{\n getValidationError: GetValidationError;\n apartmentUnit: string;\n}> = ({ getValidationError, apartmentUnit }) => {\n const intl = useIntl();\n const { config } = useContext(ConfigContext);\n\n return (\n \n \n \n \n \n );\n};\n\nexport { ApartmentUnitField };\n","import React, { useContext } from \"react\";\nimport { useIntl } from \"react-intl\";\nimport { HeapPHIDecorator } from \"@app/components/analytics\";\nimport { messages } from \"../messages\";\nimport { Textfield } from \"@natera/form\";\nimport { GetValidationError } from \"@natera/platform/lib/hooks/useError\";\nimport { ConfigContext } from \"@app/provider\";\nimport { FormField } from \"@app/components\";\n\nconst CityField: React.FC<{\n getValidationError: GetValidationError;\n defaultValue?: string;\n}> = ({ getValidationError, defaultValue }) => {\n const intl = useIntl();\n const { config } = useContext(ConfigContext);\n\n return (\n \n \n \n \n \n );\n};\n\nexport { CityField };\n","export { StreetAddressField } from \"./streetAddressField\";\nexport { ApartmentUnitField } from \"./apartmentUnitField\";\nexport { CityField } from \"./cityField\";\nexport { StateField } from \"./stateField\";\nexport { ZipCodeField } from \"./zipCodeField\";\n","import React, { useState } from \"react\";\nimport { useIntl } from \"react-intl\";\nimport { HeapPHIDecorator } from \"@app/components/analytics\";\nimport STATES from \"@etc/states.json\";\nimport { messages } from \"../messages\";\nimport { Option, Select } from \"@natera/form\";\nimport { GetValidationError } from \"@natera/platform/lib/hooks/useError\";\nimport { FormField } from \"@app/components\";\n\nconst StateField: React.FC<{\n getValidationError: GetValidationError;\n defaultValue?: string;\n}> = ({ getValidationError, defaultValue }) => {\n const intl = useIntl();\n const [selectedState, setSelectedState] = useState(\n defaultValue\n );\n\n const handleValueChange = (value: string) => {\n setSelectedState(value);\n };\n\n return (\n \n \n \n \n \n );\n};\n\nexport { StateField };\n","import React, { useContext } from \"react\";\nimport { useIntl } from \"react-intl\";\nimport { HeapPHIDecorator } from \"@app/components/analytics\";\nimport { messages } from \"../messages\";\nimport { Textfield } from \"@natera/form\";\nimport { GetValidationError } from \"@natera/platform/lib/hooks/useError\";\nimport { ConfigContext } from \"@app/provider\";\nimport { FormField } from \"@app/components\";\n\nconst StreetAddressField: React.FC<{\n getValidationError: GetValidationError;\n streetAddress: string;\n}> = ({ getValidationError, streetAddress }) => {\n const intl = useIntl();\n const { config } = useContext(ConfigContext);\n\n return (\n \n \n \n \n \n );\n};\n\nexport { StreetAddressField };\n","import React from \"react\";\nimport { useIntl } from \"react-intl\";\nimport { HeapPHIDecorator } from \"@app/components/analytics\";\nimport { messages } from \"../messages\";\nimport { Textfield } from \"@natera/form\";\nimport Tooltip from \"@natera/material/lib/tooltip\";\nimport { GetValidationError } from \"@natera/platform/lib/hooks/useError\";\nimport { FormField } from \"@app/components\";\n\nconst ZipCodeField: React.FC<{\n getValidationError: GetValidationError;\n defaultValue?: string;\n}> = ({ getValidationError, defaultValue }) => {\n const intl = useIntl();\n\n return (\n \n \n \n \n \n \n
\n \n \n );\n};\n\nexport { ZipCodeField };\n","export { default as AddressForm } from \"./addressForm\";\n","import { defineMessages } from \"react-intl\";\n\nexport const messages = defineMessages({\n addressFormStreetAddress: {\n id: \"addressFormStreetAddress\",\n defaultMessage: \"Street Address\",\n },\n addressFormStreetAddressPlaceholder: {\n id: \"addressFormStreetAddressPlaceholder\",\n defaultMessage: \"Enter Street Address\",\n },\n addressFormApartmentUnit: {\n id: \"addressFormApartmentUnit\",\n defaultMessage: \"Apartment/Unit\",\n },\n addressFormApartmentUnitPlaceholder: {\n id: \"addressFormApartmentUnitPlaceholder\",\n defaultMessage: \"Enter Apartment or Unit Number\",\n },\n addressFormCity: {\n id: \"addressFormCity\",\n defaultMessage: \"City\",\n },\n addressFormCityPlaceholder: {\n id: \"addressFormCityPlaceholder\",\n defaultMessage: \"Enter City\",\n },\n addressFormState: {\n id: \"addressFormState\",\n defaultMessage: \"State\",\n },\n addressFormStatePlaceholder: {\n id: \"addressFormStatePlaceholder\",\n defaultMessage: \"Select State\",\n },\n addressFormZipCode: {\n id: \"addressFormZipCode\",\n defaultMessage: \"Zip Code\",\n },\n addressFormZipCodePlaceholder: {\n id: \"addressFormZipCodePlaceholder\",\n defaultMessage: \"Enter Your Zip Code\",\n },\n addressFormInvalidZipCode: {\n id: \"addressFormInvalidZipCode\",\n defaultMessage: \"Please enter a valid zip code.\",\n },\n addressFormRequired: {\n id: \"addressFormRequired\",\n defaultMessage: \"Please fill in this field.\",\n },\n addressFormZipTooltip: {\n id: \"addressFormZipTooltip\",\n defaultMessage:\n \"Required format: 5-digit number, or 9-digit number with a dash after the 5th digit XXXXX or XXXXX-XXXX\",\n },\n});\n","import React from \"react\";\nimport { Button, Form, RadioButton, RadioGroup } from \"@natera/form\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport * as R from \"ramda\";\n\nimport {\n ChannelType,\n ChannelValue,\n Communication,\n} from \"@app/provider/profile/types\";\n\nconst messages = defineMessages({\n updateCommunicationFormHowReceiveUpdates: {\n id: \"updateCommunicationFormHowReceiveUpdates\",\n defaultMessage:\n \"Tell us how you'd like to receive important updates about your test, including your results.\",\n },\n updateCommunicationFormEmail: {\n id: \"updateCommunicationFormEmail\",\n defaultMessage: \"Email\",\n },\n updateCommunicationFormSms: {\n id: \"updateCommunicationFormSms\",\n defaultMessage: \"SMS\",\n },\n updateCommunicationFormEmailOptInTitle: {\n id: \"updateCommunicationFormEmailOptInTitle\",\n defaultMessage: \"Opt-in to receive Email communications\",\n },\n updateCommunicationFormSmsOptInTitle: {\n id: \"updateCommunicationFormSmsOptInTitle\",\n defaultMessage: \"Opt-in to receive SMS communications\",\n },\n updateCommunicationFormEmailOptInDescription: {\n id: \"updateCommunicationFormEmailOptInDescription\",\n defaultMessage:\n \"By selecting email, I understand and agree I may be contacted by email for treatment options, billing/collection matters, and health-related products, service or studies; I may opt out at any time.\",\n },\n updateCommunicationFormSmsOptInDescription: {\n id: \"updateCommunicationFormSmsOptInDescription\",\n defaultMessage:\n \"By selecting SMS, I understand and agree I may be contacted by text message, telephone dialing systems, or computer assisted technology for treatment options, billing/collection matters, and health-related products, service or studies; I may opt out at any time.\",\n },\n updateCommunicationFormEmailOptOutTitle: {\n id: \"updateCommunicationFormEmailOptOutTitle\",\n defaultMessage: \"Opt-out from Email communications\",\n },\n updateCommunicationFormSmsOptOutTitle: {\n id: \"updateCommunicationFormSmsOptOutTitle\",\n defaultMessage: \"Opt-out from SMS communications\",\n },\n updateCommunicationFormEmailOptOutDescription: {\n id: \"updateCommunicationFormEmailOptOutDescription\",\n defaultMessage: \"You will not be contacted regarding test-related updates.\",\n },\n updateCommunicationFormSmsOptOutDescription: {\n id: \"updateCommunicationFormSmsOptOutDescription\",\n defaultMessage: \"You will not be contacted regarding test-related updates.\",\n },\n updateCommunicationFormUpdateButon: {\n id: \"updateCommunicationFormUpdateButon\",\n defaultMessage: \"Update\",\n },\n updateCommunicationFormCancelButton: {\n id: \"updateCommunicationFormCancelButton\",\n defaultMessage: \"Cancel\",\n },\n});\n\nexport type CommunicationsPreferencesFormProps = {\n communicationData?: Communication[];\n onSubmit: (communications: Communication[]) => void;\n onCancel?: () => void;\n showCancelButton?: boolean;\n descriptionMessage?: string;\n submitBtnMessage?: string;\n};\n\nconst CommunicationsPreferencesForm: React.FC = ({\n communicationData,\n onSubmit,\n onCancel,\n showCancelButton = true,\n descriptionMessage,\n submitBtnMessage,\n}) => {\n const intl = useIntl();\n\n const getInitialCommunication = (type: ChannelType) => {\n if (!communicationData) return undefined;\n return R.find(R.propEq(\"channelType\", type))(\n communicationData\n );\n };\n\n const getInititalEmail = () => {\n const emailCommunication = getInitialCommunication(ChannelType.EMAIL);\n return emailCommunication ? emailCommunication.value : ChannelValue.UNKNOWN;\n };\n\n const getInititalSms = () => {\n const smsCommunication = getInitialCommunication(ChannelType.SMS);\n return smsCommunication ? smsCommunication.value : ChannelValue.UNKNOWN;\n };\n\n const [communicationEmail, setCommunicationEmail] = React.useState<\n ChannelValue\n >(ChannelValue.UNKNOWN);\n\n const [communicationSms, setCommunicationSms] = React.useState(\n ChannelValue.UNKNOWN\n );\n\n React.useEffect(() => {\n setCommunicationEmail(getInititalEmail());\n setCommunicationSms(getInititalSms());\n }, [communicationData]);\n\n const handleEmailCommunicationSelect = (emailCommunication: ChannelValue) =>\n setCommunicationEmail(emailCommunication);\n\n const handleSmsCommunicationSelect = (smsCommunication: ChannelValue) =>\n setCommunicationSms(smsCommunication);\n\n const handleSubmit: React.FormEventHandler = (event) => {\n event.preventDefault();\n\n const formData = new FormData(event.currentTarget);\n\n const email = formData.get(\"emailCommunication\") as\n | ChannelValue\n | undefined;\n const sms = formData.get(\"smsCommunication\") as ChannelValue | undefined;\n\n const updatedCommunicationPreferences: Communication[] = [\n {\n channelType: ChannelType.EMAIL,\n value: email ? ChannelValue[email] : ChannelValue.UNKNOWN,\n },\n {\n channelType: ChannelType.SMS,\n value: sms ? ChannelValue[sms] : ChannelValue.UNKNOWN,\n },\n ];\n\n onSubmit(updatedCommunicationPreferences);\n };\n\n return (\n \n );\n};\n\nexport default CommunicationsPreferencesForm;\n","export {\n default as CommunicationsPreferencesForm,\n CommunicationsPreferencesFormProps,\n} from \"./communicationsPreferencesForm\";\n","export { AddressForm } from \"./addressForm\";\nexport { default as LoginForm } from \"./loginForm\";\nexport { default as SelectAddressForm } from \"./selectAddressForm\";\nexport { default as ZipSelectorForm, ZipSelector } from \"./zipSelectorForm\";\nexport { CommunicationsPreferencesForm } from \"./commsPrefForm\";\nexport { default as SelectInsuranceCompanyForm } from \"./selectInsuranceCompanyForm\";\nexport { default as ProvideGovernmentIssuedForm } from \"./provideGovernmentIssuedForm\";\nexport { default as InsuranceCostEstimationForm } from \"./insuranceCostEstimationForm\";\nexport { default as SetupProfileForm } from \"./setupProfileForm\";\n","export { default } from \"./insuranceCostEstimationForm\";\n","import { Grid, GridCell, GridRow } from \"@natera/material/lib/layout\";\nimport { Button, Form } from \"@natera/form\";\nimport React from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport {\n PaymentInfo,\n PaymentType,\n} from \"@app/pages/private/simpleOrder/paymentMethod/paymentMethod\";\nimport { InsuranceEstimationData } from \"./insuranceEstimationData\";\nimport { InsuranceEstimationInformation } from \"./insuranceEstimationInformation\";\nimport FinancialAidCard from \"@app/components/financialAidCard\";\n\nimport { HEAP_EVENTS } from \"@app/provider/types\";\nimport { getTestNameForHeap } from \"@app/utils\";\nimport { OrderContext } from \"@app/provider/order\";\n\nimport \"./insuranceCostEstimationForm.scss\";\n\nconst messages = defineMessages({\n insuranceCostEstimationFormButtonNext: {\n id: \"insuranceCostEstimationFormButtonNext\",\n defaultMessage: \"Next\",\n },\n insuranceCostEstimationFormButtonBack: {\n id: \"insuranceCostEstimationFormButtonBack\",\n defaultMessage: \"Back\",\n },\n insuranceCostEstimationFormCardTitle: {\n id: \"insuranceCostEstimationFormCardTitle\",\n defaultMessage: \"Financial access programs\",\n },\n insuranceCostEstimationFormCardDescription: {\n id: \"insuranceCostEstimationFormCardDescription\",\n defaultMessage:\n \"If you meet certain income criteria*, you could be eligible for a reduced patient responsibility rate.\",\n },\n insuranceCostEstimationFormCardNote: {\n id: \"insuranceCostEstimationFormCardNote\",\n defaultMessage: \"*Based on Federal poverty thresholds.\",\n },\n});\n\ntype Props = {\n paymentMethodData: PaymentInfo;\n onSubmit: (data: unknown) => void;\n goBack: () => void;\n};\n\nconst InsuranceCostEstimationForm: React.FC = ({\n paymentMethodData,\n onSubmit,\n goBack,\n}) => {\n const intl = useIntl();\n const { orderData } = React.useContext(OrderContext);\n const orderUidPublic = orderData?.orderUidPublic;\n const limsId = orderData?.clinic?.limsId;\n\n const handleSubmit: React.FormEventHandler = (event) => {\n event.preventDefault();\n onSubmit(paymentMethodData);\n\n heap.track(HEAP_EVENTS.upp_simpleorder_costestimate, {\n tests_ordered: getTestNameForHeap(orderData),\n lims_clinic_id: limsId,\n public_order_uid: orderUidPublic,\n });\n };\n\n const showFinancialAccessProgramsCard = () =>\n paymentMethodData.paymentMethod === PaymentType.COMMERCIAL ||\n (paymentMethodData.paymentMethod === PaymentType.MULTIPLE &&\n paymentMethodData.paymentMethodInfo.first.paymentMethod ===\n PaymentType.COMMERCIAL &&\n paymentMethodData.paymentMethodInfo.second.paymentMethod ===\n PaymentType.COMMERCIAL);\n\n return (\n \n );\n};\n\nexport default InsuranceCostEstimationForm;\n","export { default as InsuranceEstimationData } from \"./insuranceEstimationData\";\n","import React from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport {\n Commercial,\n Government,\n MultipleInsuranceData,\n PaymentInfo,\n PaymentType,\n} from \"@app/pages/private/simpleOrder/paymentMethod/paymentMethod\";\nimport { FormField } from \"@natera/form\";\n\nimport \"./insuranceEstimationData.scss\";\n\nconst messages = defineMessages({\n insuranceEstimationDataInsuranceCompanyLabel: {\n id: \"insuranceEstimationDataInsuranceCompanyLabel\",\n defaultMessage: \"Insurance company\",\n },\n insuranceEstimationDataGovernmentInsuranceLabel: {\n id: \"insuranceEstimationDataGovernmentInsuranceLabel\",\n defaultMessage: \"Government insurance\",\n },\n insuranceEstimationDataFirstInsuranceTypeLabel: {\n id: \"insuranceEstimationDataFirstInsuranceTypeLabel\",\n defaultMessage: \"First insurance type\",\n },\n insuranceEstimationDataSecondInsuranceTypeLabel: {\n id: \"insuranceEstimationDataSecondInsuranceTypeLabel\",\n defaultMessage: \"Second insurance type\",\n },\n insuranceEstimationDataMemberIdLabel: {\n id: \"insuranceEstimationDataMemberIdLabel\",\n defaultMessage: \"Government-issued Insurance Number\",\n },\n insuranceEstimationDataMemberIdLabelCommercial: {\n id: \"insuranceEstimationDataMemberIdLabelCommercial\",\n defaultMessage: \"Member ID\",\n },\n});\n\nexport type InsuranceEstimationDataProps = {\n paymentMethodData: PaymentInfo;\n isSecondInsurance?: boolean;\n};\n\nconst InsuranceEstimationData: React.FC = ({\n paymentMethodData,\n isSecondInsurance,\n}) => {\n const intl = useIntl();\n\n const getInsuranceLabel = () => {\n if (paymentMethodData.paymentMethod === PaymentType.COMMERCIAL) {\n return intl.formatMessage(\n messages.insuranceEstimationDataInsuranceCompanyLabel\n );\n }\n\n if (paymentMethodData.paymentMethod === PaymentType.GOVERNMENT_ISSUED) {\n return intl.formatMessage(\n messages.insuranceEstimationDataGovernmentInsuranceLabel\n );\n }\n\n if (paymentMethodData.paymentMethod === PaymentType.MULTIPLE) {\n return intl.formatMessage(\n isSecondInsurance\n ? messages.insuranceEstimationDataSecondInsuranceTypeLabel\n : messages.insuranceEstimationDataFirstInsuranceTypeLabel\n );\n }\n };\n\n const getInsuranceName = () => {\n if (paymentMethodData.paymentMethod === PaymentType.COMMERCIAL) {\n return paymentMethodData.paymentMethodInfo.companyName;\n }\n\n if (paymentMethodData.paymentMethod === PaymentType.GOVERNMENT_ISSUED) {\n return paymentMethodData.paymentMethodInfo.companyName;\n }\n\n if (paymentMethodData.paymentMethod === PaymentType.MULTIPLE) {\n const multipleStepData = (paymentMethodData as MultipleInsuranceData)\n .paymentMethodInfo;\n\n return isSecondInsurance\n ? multipleStepData.second.paymentMethodInfo.companyName\n : multipleStepData.first.paymentMethodInfo.companyName;\n }\n };\n\n const getMemberId = (data: Government | Commercial) => {\n return data.paymentMethod === PaymentType.COMMERCIAL\n ? data.paymentMethodInfo.memberId\n : data.paymentMethodInfo.insuranceNumber;\n };\n\n const getInsuranceMemberId = () => {\n if (paymentMethodData.paymentMethod === PaymentType.COMMERCIAL) {\n return getMemberId(paymentMethodData);\n }\n\n if (paymentMethodData.paymentMethod === PaymentType.GOVERNMENT_ISSUED) {\n return getMemberId(paymentMethodData);\n }\n\n if (paymentMethodData.paymentMethod === PaymentType.MULTIPLE) {\n const multipleStepData = (paymentMethodData as MultipleInsuranceData)\n .paymentMethodInfo;\n\n return isSecondInsurance\n ? getMemberId(multipleStepData.second)\n : getMemberId(multipleStepData.first);\n }\n };\n\n const getInsuranceLabelMemberId = () => {\n const isCommercialPaymentMethod =\n paymentMethodData.paymentMethod === PaymentType.COMMERCIAL;\n const isFirstPaymentCommercial =\n paymentMethodData.paymentMethod === PaymentType.MULTIPLE &&\n paymentMethodData.paymentMethodInfo.first.paymentMethod ===\n PaymentType.COMMERCIAL &&\n !isSecondInsurance;\n const isSecondPaymentCommercial =\n paymentMethodData.paymentMethod === PaymentType.MULTIPLE &&\n paymentMethodData.paymentMethodInfo.second.paymentMethod ===\n PaymentType.COMMERCIAL &&\n isSecondInsurance;\n\n if (\n isCommercialPaymentMethod ||\n isFirstPaymentCommercial ||\n isSecondPaymentCommercial\n ) {\n return intl.formatMessage(\n messages.insuranceEstimationDataMemberIdLabelCommercial\n );\n } else {\n return intl.formatMessage(messages.insuranceEstimationDataMemberIdLabel);\n }\n };\n\n return (\n \n \n {getInsuranceName()}\n \n \n {getInsuranceMemberId()}\n \n \n );\n};\n\nexport default InsuranceEstimationData;\n","export { default as InsuranceEstimationInformation } from \"./insuranceEstimationInformation\";\n","import React from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport {\n PaymentInfo,\n PaymentType,\n} from \"@app/pages/private/simpleOrder/paymentMethod/paymentMethod\";\n\nimport \"./insuranceEstimationInformation.scss\";\nimport { getCommercialInsurancePriceEstimation } from \"@app/utils\";\nimport { OrderContext } from \"@app/provider\";\n\nexport const messages = defineMessages({\n insuranceEstimationInformationPersonalizedEstimateTitle: {\n id: \"insuranceEstimationInformationPersonalizedEstimateTitle\",\n defaultMessage: \"Personalized estimate\",\n },\n insuranceEstimationInformationPersonalizedEstimateContent: {\n id: \"insuranceEstimationInformationPersonalizedEstimateContent\",\n defaultMessage:\n \"After Natera received your sample, we will generate a personalized estimate, based on your insurance information.\",\n },\n insuranceEstimationInformationOutOfPocketCostTitle: {\n id: \"insuranceEstimationInformationOutOfPocketCostTitle\",\n defaultMessage: \"Out-of-pocket cost\",\n },\n insuranceEstimationInformationOutOfPocketCostContent: {\n id: \"insuranceEstimationInformationOutOfPocketCostContent\",\n defaultMessage:\n \"Your out-of-pocket cost for this test depends on your insurance coverage and deductible. If you’ve met your deductible, what you pay will go towards that amount, after which insurance begins to contribute to your care. If your insurance plan denies the claim, you will be eligible for our cash price.\",\n },\n insuranceEstimationInformationPaymentOptionsTitle: {\n id: \"insuranceEstimationInformationPaymentOptionsTitle\",\n defaultMessage: \"Payment options\",\n },\n insuranceEstimationInformationPaymentOptionsContent: {\n id: \"insuranceEstimationInformationPaymentOptionsContent\",\n defaultMessage:\n \"If we estimate your cost to exceed {price}, we’ll attempt to contact you and you choose how you pay: insurance or cash\",\n },\n insuranceEstimationInformationNoOutOfPocketCostTitle: {\n id: \"insuranceEstimationInformationNoOutOfPocketCostTitle\",\n defaultMessage: \"No out-of-pocket cost\",\n },\n insuranceEstimationInformationGovernmentCostContent: {\n id: \"insuranceEstimationInformationGovernmentCostContent\",\n defaultMessage:\n \"Because you have indicated that you are covered by a government insurance plan, we are unable to estimate your out-of-pocket cost at this time. Please contact your insurance plan for your plan benefits.\",\n },\n});\n\ntype EstimationInformationType = {\n title?: string;\n content: string;\n note?: string;\n};\n\nexport type InsuranceEstimationInformationProps = {\n paymentMethodData: PaymentInfo;\n};\n\nconst InsuranceEstimationInformation: React.FC = ({\n paymentMethodData,\n}) => {\n const intl = useIntl();\n\n const { orderData } = React.useContext(OrderContext);\n\n const estimationInformation = {\n getPersonalizedEstimate: (): EstimationInformationType => ({\n title: intl.formatMessage(\n messages.insuranceEstimationInformationPersonalizedEstimateTitle\n ),\n content: intl.formatMessage(\n messages.insuranceEstimationInformationPersonalizedEstimateContent\n ),\n }),\n getOutOfPocketCost: (): EstimationInformationType => ({\n title: intl.formatMessage(\n messages.insuranceEstimationInformationOutOfPocketCostTitle\n ),\n content: intl.formatMessage(\n messages.insuranceEstimationInformationOutOfPocketCostContent\n ),\n }),\n getPaymentOptions: (): EstimationInformationType => ({\n title: intl.formatMessage(\n messages.insuranceEstimationInformationPaymentOptionsTitle\n ),\n content: intl.formatMessage(\n messages.insuranceEstimationInformationPaymentOptionsContent,\n {\n price: getCommercialInsurancePriceEstimation(orderData),\n }\n ),\n }),\n getNoOutOfPocketCost: (): EstimationInformationType => ({\n title: intl.formatMessage(\n messages.insuranceEstimationInformationNoOutOfPocketCostTitle\n ),\n content: intl.formatMessage(\n messages.insuranceEstimationInformationGovernmentCostContent\n ),\n }),\n };\n\n const getCommercialOrGovermentInformationItem = (\n info: EstimationInformationType\n ) => (\n \n \n {info.title && {info.title}}\n {info.content}\n {info.note && {info.note}}\n
\n \n );\n\n const renderInformationList = (\n informationList: EstimationInformationType[]\n ) => (\n \n {informationList.map((info) =>\n getCommercialOrGovermentInformationItem(info)\n )}\n
\n );\n\n const commercialInformationList = [\n estimationInformation.getPersonalizedEstimate(),\n estimationInformation.getOutOfPocketCost(),\n estimationInformation.getPaymentOptions(),\n ];\n\n const governmentInformationList = [\n estimationInformation.getNoOutOfPocketCost(),\n ];\n\n const renderInformation = () => {\n if (paymentMethodData.paymentMethod === PaymentType.COMMERCIAL) {\n return renderInformationList(commercialInformationList);\n }\n\n if (paymentMethodData.paymentMethod === PaymentType.GOVERNMENT_ISSUED) {\n return renderInformationList(governmentInformationList);\n }\n\n if (paymentMethodData.paymentMethod === PaymentType.MULTIPLE) {\n const firstInsurance = paymentMethodData.paymentMethodInfo.first;\n const secondInsurance = paymentMethodData.paymentMethodInfo.second;\n\n if (\n firstInsurance.paymentMethod === PaymentType.COMMERCIAL &&\n secondInsurance.paymentMethod === PaymentType.COMMERCIAL\n ) {\n return renderInformationList(commercialInformationList);\n } else {\n return renderInformationList(governmentInformationList);\n }\n }\n };\n\n return (\n \n {renderInformation()}\n \n );\n};\n\nexport default InsuranceEstimationInformation;\n","export { default } from \"./loginForm\";\n","import { HeapPHIDecorator } from \"@app/components/analytics\";\nimport React, { FC, ReactElement, useContext, useEffect, useMemo } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport {\n ClearErrors,\n ClearValidationError,\n SetValidationError,\n} from \"@natera/platform/lib/hooks/useError\";\nimport { Button, Form, Textfield } from \"@natera/form\";\nimport {\n ConfigContext,\n ErrorContext,\n NotificationContext,\n} from \"@app/provider\";\nimport { FormField, PasswordField } from \"@app/components\";\nimport { useNavigate, useLocation } from \"react-router-dom\";\nimport validateEmail from \"../../../utils/validateEmail\";\n\nimport \"./loginForm.scss\";\n\nconst messages = defineMessages({\n loginFormEmail: {\n id: \"loginFormEmail\",\n defaultMessage: \"Email Address\",\n },\n loginFormPassword: {\n id: \"loginFormPassword\",\n defaultMessage: \"Password\",\n },\n loginFormEmailInvalid: {\n id: \"loginFormEmailInvalid\",\n defaultMessage: \"Please enter a valid email address. (username@domain)\",\n },\n loginFormFieldEmpty: {\n id: \"loginFormFieldEmpty\",\n defaultMessage: \"Please fill in this field\",\n },\n loginFormContinueWithEmail: {\n id: \"loginFormContinueWithEmail\",\n defaultMessage: \"Continue with Email\",\n },\n loginFormEmailPlaceholder: {\n id: \"loginFormEmailPlaceholder\",\n defaultMessage: \"Enter Your Email Address\",\n },\n loginFormPasswordPlaceholder: {\n id: \"loginFormPasswordPlaceholder\",\n defaultMessage: \"Enter Your Password\",\n },\n});\n\ninterface LoginFormProps {\n setValidationError: SetValidationError;\n clearValidationError: ClearValidationError;\n clearErrors: ClearErrors;\n onSubmit: (props: { email: string; password: string }) => void;\n isLoading: boolean;\n prefilledEmail?: string;\n}\n\nconst LoginForm: FC = ({\n setValidationError,\n clearValidationError,\n clearErrors,\n onSubmit,\n isLoading,\n prefilledEmail,\n}) => {\n const intl = useIntl();\n const { getValidationError } = useContext(ErrorContext);\n const navigate = useNavigate();\n const { pathname, search } = useLocation();\n const { clear } = useContext(NotificationContext);\n const { config } = React.useContext(ConfigContext);\n\n const usePlusSignInEmailAddress =\n config.test.usePlusSignInEmailAddress.enabled;\n\n const searchParams = useMemo(() => new URLSearchParams(search), [search]);\n\n useEffect(() => {\n clearErrors();\n\n return () => {\n clearErrors();\n };\n }, []);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n clearErrors();\n if (searchParams.get(\"code\")) {\n clear();\n navigate(pathname, { replace: true });\n }\n\n const formData = new FormData(e.currentTarget);\n\n const email = formData.get(\"email\")?.toString();\n const password = formData.get(\"password\")?.toString();\n\n if (!email) {\n setValidationError(\n \"email\",\n intl.formatMessage(messages.loginFormFieldEmpty)\n );\n\n return;\n }\n\n if (!password) {\n setValidationError(\n \"password\",\n intl.formatMessage(messages.loginFormFieldEmpty)\n );\n\n return;\n }\n\n if (!validateEmail(email, usePlusSignInEmailAddress)) {\n setValidationError(\n \"email\",\n intl.formatMessage(messages.loginFormEmailInvalid)\n );\n\n return;\n }\n\n if (!isLoading) {\n onSubmit({ email, password });\n }\n };\n\n const handleEmailFocus = () => {\n clearValidationError(\"email\");\n };\n\n const handlePasswordFocus = () => {\n clearValidationError(\"password\");\n };\n\n const emailAddressFormFieldElement: ReactElement = (\n \n \n \n \n \n );\n\n const passwordFormFieldElement: ReactElement = (\n \n \n \n );\n\n return (\n \n );\n};\n\nexport default LoginForm;\n","export { default } from \"./provideGovernmentIssuedForm\";\n","import { Grid, GridCell, GridRow } from \"@natera/material/lib/layout\";\nimport { Button, Form, FormField, Textfield } from \"@natera/form\";\nimport React from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { useErrorController } from \"@natera/platform/lib/hooks\";\n\nconst messages = defineMessages({\n provideGovernmentIssuedFormEnterNumber: {\n id: \"provideGovernmentIssuedFormEnterNumber\",\n defaultMessage: \"Enter government-issued insurance number\",\n },\n provideGovernmentIssuedFormReEnterNumber: {\n id: \"provideGovernmentIssuedFormReEnterNumber\",\n defaultMessage: \"Re-enter government-issued insurance number\",\n },\n provideGovernmentIssuedFormPlaceholder: {\n id: \"provideGovernmentIssuedFormPlaceholder\",\n defaultMessage: \"Enter insurance number\",\n },\n provideGovernmentIssuedFormRequired: {\n id: \"provideGovernmentIssuedFormRequired\",\n defaultMessage: \"This information is required.\",\n },\n provideGovernmentIssuedFormMatch: {\n id: \"provideGovernmentIssuedFormMatch\",\n defaultMessage: \"Insurance numbers must match\",\n },\n provideGovernmentIssuedFormInvalid: {\n id: \"provideGovernmentIssuedFormInvalid\",\n defaultMessage: \"Please enter a valid insurance number\",\n },\n provideGovernmentIssuedFormButtonNext: {\n id: \"provideGovernmentIssuedFormButtonNext\",\n defaultMessage: \"Next\",\n },\n provideGovernmentIssuedFormButtonBack: {\n id: \"provideGovernmentIssuedFormButtonBack\",\n defaultMessage: \"Back\",\n },\n});\n\ntype Props = {\n defaultValue?: string;\n onSubmit: (insuranceNumber: string) => void;\n goBack: () => void;\n};\n\nconst ProvideGovernmentIssuedForm: React.FC = ({\n defaultValue,\n onSubmit,\n goBack,\n}) => {\n const intl = useIntl();\n const errorController = useErrorController();\n\n const handleSubmit: React.FormEventHandler = (event) => {\n event.preventDefault();\n errorController.clearErrors();\n\n const formData = new FormData(event.currentTarget);\n\n const insuranceNumber = formData.get(\"insuranceNumber\")?.toString();\n const reInsuranceNumber = formData.get(\"reInsuranceNumber\")?.toString();\n\n if (!insuranceNumber) {\n errorController.setValidationError(\n \"insuranceNumber\",\n intl.formatMessage(messages.provideGovernmentIssuedFormRequired)\n );\n\n return;\n }\n\n if (insuranceNumber || reInsuranceNumber) {\n const isInvalidInsuranceNumber =\n insuranceNumber && insuranceNumber !== insuranceNumber.trim();\n\n if (isInvalidInsuranceNumber) {\n errorController.setValidationError(\n \"insuranceNumber\",\n intl.formatMessage(messages.provideGovernmentIssuedFormInvalid)\n );\n }\n\n const isInvalidReInsuranceNumber =\n reInsuranceNumber && reInsuranceNumber !== reInsuranceNumber.trim();\n\n if (isInvalidReInsuranceNumber) {\n errorController.setValidationError(\n \"reInsuranceNumber\",\n intl.formatMessage(messages.provideGovernmentIssuedFormInvalid)\n );\n }\n\n if (isInvalidInsuranceNumber || isInvalidReInsuranceNumber) return;\n }\n\n if (!reInsuranceNumber || insuranceNumber !== reInsuranceNumber) {\n errorController.setValidationError(\n \"insuranceNumber\",\n intl.formatMessage(messages.provideGovernmentIssuedFormMatch)\n );\n\n errorController.setValidationError(\n \"reInsuranceNumber\",\n intl.formatMessage(messages.provideGovernmentIssuedFormMatch)\n );\n\n return;\n }\n\n onSubmit(insuranceNumber);\n };\n\n return (\n \n );\n};\n\nexport default ProvideGovernmentIssuedForm;\n","export { messages } from \"./messages\";\n","import { messages as setupProfileFormMessages } from \"@app/components/forms/setupProfileForm\";\nimport { messages as setupProfileReviewInfoMessages } from \"@app/components/setupProfileReviewInfo\";\n\nimport { defineMessages } from \"react-intl\";\n\nconst publicMpFormMessages = defineMessages({\n publicMpPersonalInfoPageBackButton: {\n id: \"publicMpPersonalInfoPageBackButton\",\n defaultMessage: \"Back\",\n },\n publicMpContactInfoFormEmailInvalid: {\n id: \"publicMpContactInfoFormEmailInvalid\",\n defaultMessage: \"Please enter a valid email address. (username@domain)\",\n },\n publicMpContactInfoFormEmailField: {\n id: \"publicMpContactInfoFormEmailField\",\n defaultMessage: \"Email Address\",\n },\n publicMpContactInfoFormEmailFormat: {\n id: \"publicMpContactInfoFormEmailFormat\",\n defaultMessage: \"email format (username@domain)\",\n },\n publicMpContactInfoFormEmailPlaceholder: {\n id: \"publicMpContactInfoFormEmailPlaceholder\",\n defaultMessage: \"Enter Your Email Address\",\n },\n publicMpContactInfoFormEmailUserExists: {\n id: \"publicMpContactInfoFormEmailUserExists\",\n defaultMessage: \"This email address is already in use.\",\n },\n});\n\nexport const messages = {\n ...setupProfileFormMessages,\n ...setupProfileReviewInfoMessages,\n ...publicMpFormMessages,\n};\n","import React, { FC, useEffect, useState } from \"react\";\nimport { useIntl } from \"react-intl\";\nimport Tooltip from \"@natera/material/lib/tooltip\";\nimport { Button, Form, Textfield } from \"@natera/form\";\nimport {\n ClearErrors,\n ClearValidationError,\n GetValidationError,\n SetValidationError,\n} from \"@natera/platform/lib/hooks/useError\";\nimport { usePhoneValidation } from \"@natera/platform/lib/hooks\";\nimport { FormField, PhoneField } from \"@app/components\";\nimport { getPhoneValidationErrorMessage, validateEmail } from \"@app/utils\";\nimport { ConfigContext, UserContext } from \"@app/provider\";\nimport { StepperContext } from \"@natera/stepper\";\nimport { ContactInfoData } from \"@app/pages/public/drawRequest/personalInformation/stepScreens/contactInfoScreen\";\nimport { messages } from \"@app/components/forms/publicMpForms\";\n\ninterface PublicMpContactInfoFormProps {\n contactInfoData?: ContactInfoData;\n isLoading?: boolean;\n onSubmit: (contactInfoData: ContactInfoData) => void;\n setValidationError: SetValidationError;\n getValidationError: GetValidationError;\n clearErrors: ClearErrors;\n clearValidationError: ClearValidationError;\n}\n\nconst PublicMpContactInfoForm: FC = ({\n contactInfoData,\n isLoading,\n onSubmit,\n setValidationError,\n getValidationError,\n clearErrors,\n clearValidationError,\n}) => {\n const intl = useIntl();\n\n const { config } = React.useContext(ConfigContext);\n\n const usePlusSignInEmailAddress =\n config.test.usePlusSignInEmailAddress.enabled;\n\n const {\n validatePhoneNumber: validateFromPS,\n isLoading: isLoadingPhoneValidation,\n } = React.useContext(UserContext);\n const phoneValidation = usePhoneValidation();\n\n const { goBack } = React.useContext(StepperContext);\n\n const [profileFormData, setProfileFormData] = useState();\n\n const getContactInfoFormData = (formData: FormData) => {\n const email = formData.get(\"email\")?.toString();\n const mobileNumber = formData.get(\"mobileNumber\")?.toString();\n\n return {\n email,\n mobileNumber,\n };\n };\n\n const validateProfileFormData = async (formData: FormData) => {\n const profileFormData = getContactInfoFormData(formData);\n\n const userForm = [\n { title: \"email\", value: profileFormData.email },\n { title: \"mobileNumber\", value: profileFormData.mobileNumber },\n ];\n\n for (const field of userForm) {\n if (!field.value) {\n return setValidationError(\n field.title,\n intl.formatMessage(messages.setupProfileFormRequired)\n );\n }\n }\n\n if (\n profileFormData.email &&\n !validateEmail(profileFormData.email, usePlusSignInEmailAddress)\n ) {\n setValidationError(\n \"email\",\n intl.formatMessage(messages.publicMpContactInfoFormEmailInvalid)\n );\n return;\n }\n\n if (profileFormData.mobileNumber) {\n const phoneValidationErrorMessage = await getPhoneValidationErrorMessage({\n isMandatory: true,\n mobileNumber: profileFormData.mobileNumber,\n intl,\n phoneValidation,\n validateFromPS,\n });\n\n if (phoneValidationErrorMessage) {\n setValidationError(\"mobileNumber\", phoneValidationErrorMessage);\n return;\n }\n }\n\n return profileFormData;\n };\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n clearErrors();\n\n const formData = new FormData(e.currentTarget);\n\n setProfileFormData(formData);\n\n const validatedProfileFormData = await validateProfileFormData(formData);\n\n if (validatedProfileFormData) {\n onSubmit({\n email: validatedProfileFormData.email,\n mobileNumber: validatedProfileFormData.mobileNumber,\n });\n }\n };\n\n useEffect(() => {\n if (profileFormData) {\n validateProfileFormData(profileFormData);\n }\n }, [intl.locale]);\n\n const handleEmailFieldChange: React.ChangeEventHandler = (\n e\n ) => {\n if (!e.currentTarget.value) {\n clearValidationError(\"email\");\n return;\n }\n };\n\n const handleBack = () => {\n goBack();\n };\n\n const loading = isLoading || isLoadingPhoneValidation;\n\n return (\n \n );\n};\n\nexport default PublicMpContactInfoForm;\n","export { default } from \"./publicMpDobForm\";\n","import { HeapPHIDecorator } from \"@app/components/analytics\";\nimport React, { FC, useEffect, useState } from \"react\";\nimport { useIntl } from \"react-intl\";\nimport { Button, DateInput, Form } from \"@natera/form\";\nimport {\n ClearErrors,\n GetValidationError,\n SetValidationError,\n} from \"@natera/platform/lib/hooks/useError\";\nimport { FormField } from \"@app/components\";\nimport { getFormattedDOB, isPatientMinor, weekDayFormatter } from \"@app/utils\";\nimport { DobData } from \"@app/pages/public/drawRequest/personalInformation/stepScreens/dobScreen\";\nimport { StepperContext } from \"@natera/stepper\";\nimport { messages } from \"@app/components/forms/publicMpForms\";\n\ninterface PublicMpDobFormProps {\n dobData?: DobData;\n isLoading?: boolean;\n onSubmit: (dobData: DobData) => void;\n setValidationError: SetValidationError;\n getValidationError: GetValidationError;\n clearErrors: ClearErrors;\n}\n\nconst PublicMpDobForm: FC = ({\n dobData,\n isLoading,\n onSubmit,\n setValidationError,\n getValidationError,\n clearErrors,\n}) => {\n const intl = useIntl();\n\n const { goBack } = React.useContext(StepperContext);\n\n const [profileFormData, setProfileFormData] = useState();\n\n const getDobFormData = (formData: FormData) => {\n const dateOfBirth = formData.get(\"dateOfBirth\")?.toString();\n\n return {\n dateOfBirth,\n };\n };\n\n const validateProfileFormData = async (formData: FormData) => {\n const profileFormData = getDobFormData(formData);\n\n const userForm = [\n { title: \"dateOfBirth\", value: profileFormData.dateOfBirth },\n ];\n\n for (const field of userForm) {\n if (!field.value) {\n return setValidationError(\n field.title,\n intl.formatMessage(messages.setupProfileFormRequired)\n );\n }\n }\n if (!profileFormData.dateOfBirth) {\n setValidationError(\n \"dateOfBirth\",\n intl.formatMessage(messages.setupProfileFormInvalidDateOfBirth)\n );\n\n return;\n }\n\n const dOB = new Date(getFormattedDOB(profileFormData.dateOfBirth));\n\n if (isPatientMinor(dOB)) {\n setValidationError(\n \"dateOfBirth\",\n intl.formatMessage(messages.setupProfileFormUnder18DateOfBirth)\n );\n\n return;\n }\n\n return profileFormData;\n };\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n clearErrors();\n\n const formData = new FormData(e.currentTarget);\n\n setProfileFormData(formData);\n\n const validatedProfileFormData = await validateProfileFormData(formData);\n\n if (validatedProfileFormData) {\n onSubmit({\n dateOfBirth: validatedProfileFormData.dateOfBirth,\n });\n }\n };\n\n useEffect(() => {\n if (profileFormData) {\n validateProfileFormData(profileFormData);\n }\n }, [intl.locale]);\n\n const handleBack = () => {\n goBack();\n };\n\n return (\n \n );\n};\n\nexport default PublicMpDobForm;\n","import { HeapPHIDecorator } from \"@app/components/analytics\";\nimport React, { FC, useEffect, useState } from \"react\";\nimport { useIntl } from \"react-intl\";\nimport { Button, Form, Textfield } from \"@natera/form\";\nimport {\n ClearErrors,\n GetValidationError,\n SetValidationError,\n} from \"@natera/platform/lib/hooks/useError\";\nimport { FormField } from \"@app/components\";\nimport { DrawRequestScreens } from \"@app/pages/public/drawRequest/drawRequest\";\nimport { PersonalInfoData } from \"@app/pages/public/drawRequest/personalInformation/stepScreens/nameScreen\";\nimport { messages } from \"@app/components/forms/publicMpForms\";\n\ninterface PublicMpPersonalInfoFormProps {\n personalInfoData?: PersonalInfoData;\n setScheduleScreen: React.Dispatch>;\n isLoading?: boolean;\n onSubmit: (profileData: PersonalInfoData) => void;\n setValidationError: SetValidationError;\n getValidationError: GetValidationError;\n clearErrors: ClearErrors;\n}\n\nconst PublicMpNameForm: FC = ({\n personalInfoData,\n setScheduleScreen,\n isLoading,\n onSubmit,\n setValidationError,\n getValidationError,\n clearErrors,\n}) => {\n const intl = useIntl();\n\n const [names, setNames] = useState({\n firstName: personalInfoData?.firstName ?? \"\",\n middleName: personalInfoData?.middleName ?? \"\",\n lastName: personalInfoData?.lastName ?? \"\",\n alternativeLastName: personalInfoData?.alternativeLastName ?? \"\",\n });\n\n const [profileFormData, setProfileFormData] = useState();\n\n const handleNamesChange: React.ChangeEventHandler = (e) =>\n setNames((prevState) => ({\n ...prevState,\n [e.target.name]: e.target.value,\n }));\n\n const handleNamesUpdate: React.ChangeEventHandler = (e) =>\n setNames((prevState) => ({\n ...prevState,\n [e.target.name]: e.target.value.trim(),\n }));\n\n const getProfileFormData = (formData: FormData) => {\n const firstName = formData.get(\"firstName\")?.toString().trim();\n const middleName = formData.get(\"middleName\")?.toString().trim();\n const lastName = formData.get(\"lastName\")?.toString().trim();\n const alternativeLastName = formData\n .get(\"alternativeLastName\")\n ?.toString()\n .trim();\n\n return {\n firstName,\n middleName,\n lastName,\n alternativeLastName,\n };\n };\n\n const validateProfileFormData = async (formData: FormData) => {\n const profileFormData = getProfileFormData(formData);\n\n const userForm = [\n { title: \"firstName\", value: profileFormData.firstName },\n { title: \"lastName\", value: profileFormData.lastName },\n ];\n\n for (const field of userForm) {\n if (!field.value) {\n return setValidationError(\n field.title,\n intl.formatMessage(messages.setupProfileFormRequired)\n );\n }\n }\n\n if (!profileFormData.firstName) {\n setValidationError(\n \"firstName\",\n intl.formatMessage(messages.setupProfileFormInvalidFirstName)\n );\n\n return;\n }\n\n if (!profileFormData.lastName) {\n setValidationError(\n \"lastName\",\n intl.formatMessage(messages.setupProfileFormInvalidLastName)\n );\n\n return;\n }\n\n return profileFormData;\n };\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n clearErrors();\n\n const formData = new FormData(e.currentTarget);\n\n setProfileFormData(formData);\n\n const validatedProfileFormData = await validateProfileFormData(formData);\n\n if (validatedProfileFormData) {\n onSubmit({\n firstName: validatedProfileFormData.firstName,\n middleName: validatedProfileFormData.middleName,\n lastName: validatedProfileFormData.lastName,\n alternativeLastName: validatedProfileFormData.alternativeLastName,\n });\n }\n };\n\n useEffect(() => {\n if (profileFormData) {\n validateProfileFormData(profileFormData);\n }\n }, [intl.locale]);\n\n const handleBack = () => {\n setScheduleScreen(DrawRequestScreens.WELCOME_SCREEN);\n };\n\n return (\n \n );\n};\n\nexport default PublicMpNameForm;\n","import { HeapPHIDecorator } from \"@app/components/analytics\";\nimport React, { FC, useEffect, useState } from \"react\";\nimport { useIntl } from \"react-intl\";\nimport Tooltip from \"@natera/material/lib/tooltip\";\nimport { Button, Form, Textfield } from \"@natera/form\";\nimport {\n ClearErrors,\n GetValidationError,\n SetValidationError,\n} from \"@natera/platform/lib/hooks/useError\";\nimport { FormField } from \"@app/components\";\nimport { validateZipCode } from \"@app/utils\";\nimport { StepperContext } from \"@natera/stepper\";\nimport { ZipCodeData } from \"@app/pages/public/drawRequest/personalInformation/stepScreens/zipCodeScreen\";\nimport { messages } from \"@app/components/forms/publicMpForms\";\n\ninterface PublicMpZipCodeFormProps {\n zipCodeData?: ZipCodeData;\n isLoading?: boolean;\n onSubmit: (zipCodeData: ZipCodeData) => void;\n setValidationError: SetValidationError;\n getValidationError: GetValidationError;\n clearErrors: ClearErrors;\n}\n\nconst PublicMpZipCodeForm: FC = ({\n zipCodeData,\n isLoading,\n onSubmit,\n setValidationError,\n getValidationError,\n clearErrors,\n}) => {\n const intl = useIntl();\n\n const { goBack } = React.useContext(StepperContext);\n\n const [profileFormData, setProfileFormData] = useState();\n\n const getZipCodeFormData = (formData: FormData) => {\n const zipCode = formData.get(\"zipCode\")?.toString();\n\n return {\n zipCode,\n };\n };\n\n const validateProfileFormData = async (formData: FormData) => {\n const profileFormData = getZipCodeFormData(formData);\n\n const userForm = [{ title: \"zipCode\", value: profileFormData.zipCode }];\n\n for (const field of userForm) {\n if (!field.value) {\n return setValidationError(\n field.title,\n intl.formatMessage(messages.setupProfileFormRequired)\n );\n }\n }\n if (!profileFormData.zipCode) {\n setValidationError(\n \"zipCode\",\n intl.formatMessage(messages.setupProfileFormRequired)\n );\n\n return;\n }\n\n if (profileFormData.zipCode && !validateZipCode(profileFormData.zipCode)) {\n setValidationError(\n \"zipCode\",\n intl.formatMessage(messages.setupProfileFormInvalidZipCode)\n );\n return;\n }\n\n return profileFormData;\n };\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n clearErrors();\n\n const formData = new FormData(e.currentTarget);\n\n setProfileFormData(formData);\n\n const validatedProfileFormData = await validateProfileFormData(formData);\n\n if (validatedProfileFormData) {\n onSubmit({\n zipCode: validatedProfileFormData.zipCode,\n });\n }\n };\n\n useEffect(() => {\n if (profileFormData) {\n validateProfileFormData(profileFormData);\n }\n }, [intl.locale]);\n\n const handleBack = () => {\n goBack();\n };\n\n return (\n \n );\n};\n\nexport default PublicMpZipCodeForm;\n","export { default } from \"./selectAddressForm\";\n","import React from \"react\";\nimport { Form, RadioButton, RadioGroup } from \"@natera/form\";\nimport { Address } from \"@app/provider/profile\";\nimport { FormField } from \"@app/components\";\nimport { useErrorController } from \"@natera/platform/lib/hooks\";\n\nimport { getAddressAsString } from \"@app/utils\";\n\nimport \"./selectAddressForm.scss\";\n\ntype Props = {\n addresses: Address[];\n onSubmit: (selectedAddress: Address) => void;\n actions: React.ReactNode;\n};\n\nconst SelectAddressForm: React.FC = ({\n addresses,\n onSubmit,\n actions,\n}) => {\n const [addressUid, setAddressUid] = React.useState(\n addresses[0]?.uid || \"\"\n );\n\n const { clearErrors, getValidationError } = useErrorController();\n\n const handleSelectAddress = (addressUid: string) => setAddressUid(addressUid);\n\n const handleSubmit: React.FormEventHandler = (event) => {\n event.preventDefault();\n clearErrors();\n\n const selectedAddress = addresses.find(\n (address) => address.uid === addressUid\n );\n\n if (!selectedAddress) {\n return;\n }\n\n onSubmit(selectedAddress);\n };\n\n return (\n \n );\n};\n\nexport default SelectAddressForm;\n","export { default } from \"./selectInsuranceCompanyForm\";\n","import { CompanySelector } from \"@app/components/companySelector\";\nimport { Button, Form } from \"@natera/form\";\nimport React from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { HEAP_EVENTS } from \"@app/provider/types\";\nimport { getTestNameForHeap } from \"@app/utils\";\nimport { OrderContext } from \"@app/provider/order\";\nimport { Payor } from \"@app/provider/payor\";\n\nconst messages = defineMessages({\n selectInsuranceCompanyFormButtonNext: {\n id: \"selectInsuranceCompanyFormButtonNext\",\n defaultMessage: \"Next\",\n },\n selectInsuranceCompanyFormButtonBack: {\n id: \"selectInsuranceCompanyFormButtonBack\",\n defaultMessage: \"Back\",\n },\n});\n\ntype Props = {\n selectedCompany?: Payor;\n companies: Payor[];\n onSelect: (company: Payor) => void;\n onSubmit: (company: Payor) => void;\n goBack: () => void;\n isFirstMultipleStep?: boolean;\n isSecondMultipleStep?: boolean;\n};\n\nconst SelectInsuranceCompanyForm: React.FC = ({\n selectedCompany,\n companies,\n onSelect,\n onSubmit,\n goBack,\n isFirstMultipleStep,\n isSecondMultipleStep,\n}) => {\n const intl = useIntl();\n const { orderData } = React.useContext(OrderContext);\n const orderUidPublic = orderData?.orderUidPublic;\n const limsId = orderData?.clinic?.limsId;\n\n const handleSubmit: React.FormEventHandler = (event) => {\n event.preventDefault();\n\n if (!selectedCompany) {\n return;\n }\n\n onSubmit(selectedCompany);\n heap.track(\n isFirstMultipleStep\n ? HEAP_EVENTS.upp_simpleorder_firstinsurance\n : isSecondMultipleStep\n ? HEAP_EVENTS.upp_simpleorder_secondinsurance\n : HEAP_EVENTS.upp_simpleorder_insurance,\n {\n tests_ordered: getTestNameForHeap(orderData),\n lims_clinic_id: limsId,\n public_order_uid: orderUidPublic,\n insurance: selectedCompany.displayName,\n }\n );\n };\n\n return (\n \n );\n};\n\nexport default SelectInsuranceCompanyForm;\n","export { default, messages } from \"./setupProfileForm\";\n","import { HeapPHIDecorator } from \"@app/components/analytics\";\nimport React, { FC, useEffect, useState } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport Tooltip from \"@natera/material/lib/tooltip\";\nimport { Button, DateInput, Form, Textfield } from \"@natera/form\";\nimport {\n ClearErrors,\n GetValidationError,\n SetValidationError,\n} from \"@natera/platform/lib/hooks/useError\";\nimport { usePhoneValidation } from \"@natera/platform/lib/hooks\";\nimport { FormField, PhoneField } from \"@app/components\";\nimport {\n getFormattedDOB,\n getPhoneValidationErrorMessage,\n isPatientMinor,\n validateZipCode,\n weekDayFormatter,\n} from \"@app/utils\";\nimport { SetupProfileData } from \"@app/provider/profile/types\";\nimport { UserContext } from \"@app/provider\";\n\nexport const messages = defineMessages({\n setupProfileFormFirstName: {\n id: \"setupProfileFormFirstName\",\n defaultMessage: \"First Name\",\n },\n setupProfileFormMiddleName: {\n id: \"setupProfileFormMiddleName\",\n defaultMessage: \"Middle Name / Initial\",\n },\n setupProfileFormLastName: {\n id: \"setupProfileFormLastName\",\n defaultMessage: \"Last Name\",\n },\n setupProfileFormAlternativeLastName: {\n id: \"setupProfileFormAlternativeLastName\",\n defaultMessage: \"Alternate Last Name (Optional)\",\n },\n setupProfileFormDateOfBirth: {\n id: \"setupProfileFormDateOfBirth\",\n defaultMessage: \"Date of Birth\",\n },\n setupProfileFormMobileNumber: {\n id: \"setupProfileFormMobileNumber\",\n defaultMessage: \"Mobile Number\",\n },\n setupProfileFormZipCode: {\n id: \"setupProfileFormZipCode\",\n defaultMessage: \"Zip Code\",\n },\n setupProfileFormFirstNamePlaceholder: {\n id: \"setupProfileFormFirstNamePlaceholder\",\n defaultMessage: \"Enter Your First Name\",\n },\n setupProfileFormMiddleNamePlaceholder: {\n id: \"setupProfileFormMiddleNamePlaceholder\",\n defaultMessage: \"Enter Your Middle Name\",\n },\n setupProfileFormLastNamePlaceholder: {\n id: \"setupProfileFormLastNamePlaceholder\",\n defaultMessage: \"Enter Your Last Name\",\n },\n setupProfileFormAlternativeLastNamePlaceholder: {\n id: \"setupProfileFormAlternativeLastNamePlaceholder\",\n defaultMessage: \"Enter Your Alternate Last Name\",\n },\n setupProfileFormDateOfBirthPlaceholder: {\n id: \"setupProfileFormDateOfBirthPlaceholder\",\n defaultMessage: \"MM/DD/YYYY\",\n },\n setupProfileFormZipCodePlaceholder: {\n id: \"setupProfileFormZipCodePlaceholder\",\n defaultMessage: \"Enter Your Zip Code\",\n },\n setupProfileFormNext: {\n id: \"setupProfileFormNext\",\n defaultMessage: \"Next\",\n },\n setupProfileFormInvalidFirstName: {\n id: \"setupProfileFormInvalidFirstName\",\n defaultMessage: \"Invalid First Name\",\n },\n setupProfileFormInvalidLastName: {\n id: \"setupProfileFormInvalidLastName\",\n defaultMessage: \"Invalid Last Name\",\n },\n setupProfileFormInvalidDateOfBirth: {\n id: \"setupProfileFormInvalidDateOfBirth\",\n defaultMessage: \"Invalid Date of Birth\",\n },\n setupProfileFormUnder18DateOfBirth: {\n id: \"setupProfileFormUnder18DateOfBirth\",\n defaultMessage:\n \"The patient portal does not currently have test information for patients under 18 years old. Please reach out to your provider, or contact support@natera.com, for information on tests for patients under 18.\",\n },\n setupProfileFormInvalidPhoneNumber: {\n id: \"setupProfileFormInvalidPhoneNumber\",\n defaultMessage: \"Please enter a valid phone number.\",\n },\n setupProfileFormUSPhoneNumber: {\n id: \"setupProfileFormUSPhoneNumber\",\n defaultMessage: \"You must enter a US based number to create an account\",\n },\n setupProfileFormInvalidZipCode: {\n id: \"setupProfileFormInvalidZipCode\",\n defaultMessage: \"Please enter a valid zip code.\",\n },\n setupProfileFormZipTooltip: {\n id: \"setupProfileFormZipTooltip\",\n defaultMessage:\n \"Required format: 5-digit number, or 9-digit number with a dash after the 5th digit XXXXX or XXXXX-XXXX\",\n },\n setupProfileFormRequired: {\n id: \"setupProfileFormRequired\",\n defaultMessage: \"This information is required.\",\n },\n dateOfBirthPlaceholder: {\n id: \"dateOfBirthPlaceholder\",\n defaultMessage: \"MM/DD/YYYY\",\n },\n});\n\ninterface SetupProfileFormProps {\n initialProfileData?: SetupProfileData;\n isLoading?: boolean;\n onSubmit: (profileData: SetupProfileData) => void;\n setValidationError: SetValidationError;\n getValidationError: GetValidationError;\n clearErrors: ClearErrors;\n}\n\nconst SetupProfileForm: FC = ({\n initialProfileData,\n isLoading,\n onSubmit,\n setValidationError,\n getValidationError,\n clearErrors,\n}) => {\n const intl = useIntl();\n\n const { validatePhoneNumber: validateFromPS } = React.useContext(UserContext);\n const phoneValidation = usePhoneValidation();\n\n const [names, setNames] = useState({\n firstName: initialProfileData?.firstName ?? \"\",\n middleName: initialProfileData?.middleName ?? \"\",\n lastName: initialProfileData?.lastName ?? \"\",\n alternativeLastName: initialProfileData?.alternativeLastName ?? \"\",\n });\n\n const [profileFormData, setProfileFormData] = useState();\n\n const handleNamesChange: React.ChangeEventHandler = (e) =>\n setNames((prevState) => ({\n ...prevState,\n [e.target.name]: e.target.value,\n }));\n\n const handleNamesUpdate: React.ChangeEventHandler = (e) =>\n setNames((prevState) => ({\n ...prevState,\n [e.target.name]: e.target.value.trim(),\n }));\n\n const getZipCodeDefaultValue = () =>\n initialProfileData?.addresses?.length\n ? initialProfileData.addresses[0].zipCode\n : \"\";\n\n const getProfileFormData = (formData: FormData) => {\n const firstName = formData.get(\"firstName\")?.toString().trim();\n const middleName = formData.get(\"middleName\")?.toString().trim();\n const lastName = formData.get(\"lastName\")?.toString().trim();\n const alternativeLastName = formData\n .get(\"alternativeLastName\")\n ?.toString()\n .trim();\n const dateOfBirth = formData.get(\"dateOfBirth\")?.toString();\n const mobileNumber = formData.get(\"mobileNumber\")?.toString();\n const zipCode = formData.get(\"zipCode\")?.toString();\n\n return {\n firstName,\n middleName,\n lastName,\n alternativeLastName,\n dateOfBirth,\n mobileNumber,\n zipCode,\n };\n };\n\n const validateProfileFormData = async (formData: FormData) => {\n const profileFormData = getProfileFormData(formData);\n\n const userForm = [\n { title: \"firstName\", value: profileFormData.firstName },\n { title: \"lastName\", value: profileFormData.lastName },\n { title: \"dateOfBirth\", value: profileFormData.dateOfBirth },\n { title: \"mobileNumber\", value: profileFormData.mobileNumber },\n { title: \"zipCode\", value: profileFormData.zipCode },\n ];\n\n for (const field of userForm) {\n if (!field.value) {\n return setValidationError(\n field.title,\n intl.formatMessage(messages.setupProfileFormRequired)\n );\n }\n }\n\n if (!profileFormData.firstName) {\n setValidationError(\n \"firstName\",\n intl.formatMessage(messages.setupProfileFormInvalidFirstName)\n );\n\n return;\n }\n\n if (!profileFormData.lastName) {\n setValidationError(\n \"lastName\",\n intl.formatMessage(messages.setupProfileFormInvalidLastName)\n );\n\n return;\n }\n\n if (!profileFormData.dateOfBirth) {\n setValidationError(\n \"dateOfBirth\",\n intl.formatMessage(messages.setupProfileFormInvalidDateOfBirth)\n );\n\n return;\n }\n\n if (!profileFormData.zipCode) {\n setValidationError(\n \"zipCode\",\n intl.formatMessage(messages.setupProfileFormRequired)\n );\n\n return;\n }\n\n const dOB = new Date(getFormattedDOB(profileFormData.dateOfBirth));\n\n if (isPatientMinor(dOB)) {\n setValidationError(\n \"dateOfBirth\",\n intl.formatMessage(messages.setupProfileFormUnder18DateOfBirth)\n );\n\n return;\n }\n\n if (profileFormData.mobileNumber) {\n const phoneValidationErrorMessage = await getPhoneValidationErrorMessage({\n isMandatory: true,\n mobileNumber: profileFormData.mobileNumber,\n intl,\n phoneValidation,\n validateFromPS,\n });\n\n if (phoneValidationErrorMessage) {\n setValidationError(\"mobileNumber\", phoneValidationErrorMessage);\n return;\n }\n }\n\n if (profileFormData.zipCode && !validateZipCode(profileFormData.zipCode)) {\n setValidationError(\n \"zipCode\",\n intl.formatMessage(messages.setupProfileFormInvalidZipCode)\n );\n return;\n }\n\n return profileFormData;\n };\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n clearErrors();\n\n const formData = new FormData(e.currentTarget);\n\n setProfileFormData(formData);\n\n const validatedProfileFormData = await validateProfileFormData(formData);\n\n if (validatedProfileFormData) {\n onSubmit({\n firstName: validatedProfileFormData.firstName,\n middleName: validatedProfileFormData.middleName,\n lastName: validatedProfileFormData.lastName,\n alternativeLastName: validatedProfileFormData.alternativeLastName,\n dateOfBirth: validatedProfileFormData.dateOfBirth,\n phone: validatedProfileFormData.mobileNumber,\n addresses: [{ zipCode: validatedProfileFormData.zipCode! }],\n });\n }\n };\n\n useEffect(() => {\n if (profileFormData) {\n validateProfileFormData(profileFormData);\n }\n }, [intl.locale]);\n\n return (\n \n );\n};\n\nexport default SetupProfileForm;\n","import React, { useContext } from \"react\";\nimport R from \"ramda\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Button, Form } from \"@natera/form\";\nimport { DateRange, Timeslots } from \"@natera/mobile-phlebotomy/lib\";\nimport {\n TimezoneSelector,\n timezoneValidationName,\n} from \"@app/components/ui/inputs/timezoneSelector\";\nimport { ErrorProvider, SpecificDatesContext } from \"@app/provider\";\nimport { getDisabledSlots, getLastSunday, getTimeZones } from \"@app/utils\";\nimport TimeslotsWarning from \"../../sampleDraw/mobilePhlebotomy/timeslots/timeslotsWarning\";\nimport { useErrorController } from \"@natera/platform/lib/hooks\";\n\nimport \"@natera/mobile-phlebotomy/lib/theme/main.scss\";\nimport {\n renderChipTime,\n renderSelectedSlot,\n setRemoveTimeslotAriaLabel,\n} from \"@app/utils/timeslotsUtils\";\n\nimport \"./timeslotsForm.scss\";\n\nconst DAYS_AVAILABLE_FROM_GAP = 5;\nconst DAYS_AVAILABLE_TO_GAP = 15;\n\nconst messages = defineMessages({\n mobilePhlebotomyTimeslotsBack: {\n id: \"mobilePhlebotomyTimeslotsBack\",\n defaultMessage: \"Back\",\n },\n mobilePhlebotomyTimeslotsValidationMessage: {\n id: \"mobilePhlebotomyTimeslotsValidationMessage\",\n defaultMessage: \"This information is required.\",\n },\n mobilePhlebotomyTimeslotsPlaceholder: {\n id: \"mobilePhlebotomy.timeslots.placeholder\",\n defaultMessage: \"Time slot #{number}\",\n },\n mobilePhlebotomyTimeslotsTooltip: {\n id: \"mobilePhlebotomy.timeslots.timeslotTooltip\",\n defaultMessage: \"You have selected maximum amount of timeslots\",\n },\n});\n\nexport type TimeslotsFormData = {\n timeSlots: { [x: string]: string };\n timeZone: string;\n};\n\ntype Props = {\n handleConfirm: (data: TimeslotsFormData) => void;\n handleBack: () => void;\n confirmButtonLabel: string;\n isLoading?: boolean;\n isModify?: boolean;\n};\n\nconst browserTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;\nconst now = new Date();\nconst today = new Date(now.setUTCHours(0, 0, 0, 0));\n\nconst availableFrom = new Date(today);\navailableFrom.setDate(availableFrom.getDate() + DAYS_AVAILABLE_FROM_GAP);\n\nconst availableTo = new Date(today);\navailableTo.setDate(availableTo.getDate() + DAYS_AVAILABLE_TO_GAP);\n\nconst availableFromUTCDate = new Date(\n new Date(availableFrom).setUTCHours(0, 0, 0, 0)\n);\nconst startWeek =\n availableFromUTCDate.getUTCDay() === 0\n ? availableFromUTCDate\n : getLastSunday(new Date(availableFrom));\nconst endWeek = getLastSunday(new Date(availableTo));\n\nconst TimeslotsForm: React.FC = ({\n handleConfirm,\n handleBack,\n confirmButtonLabel,\n isLoading,\n}) => {\n const intl = useIntl();\n const [selectedSlots, setSelectedSlots] = React.useState([]);\n\n const selectedTimeZone = R.find(R.propEq(\"browserValue\", browserTimeZone))(\n getTimeZones(intl)\n );\n const { specificDates } = useContext(SpecificDatesContext);\n\n const disabledSlots = getDisabledSlots(new Date(availableTo), specificDates);\n\n const [timeZone, setTimeZone] = React.useState(\n selectedTimeZone?.browserValue\n );\n const [showNotification, setShowNotification] = React.useState(\n false\n );\n const errorController = useErrorController();\n\n const selectedSlotsHandler = (value: DateRange[]) => {\n setSelectedSlots(value);\n };\n\n React.useEffect(() => {\n const chipsContainer = document.querySelector(\n \".mdc-evolution-chip-set__chips\"\n );\n if (!chipsContainer) return;\n\n const removeRoleAttribute = () => {\n document.querySelectorAll('span[role=\"gridcell\"]').forEach((span) => {\n span.removeAttribute(\"role\");\n });\n };\n\n const observer = new MutationObserver(() => {\n removeRoleAttribute();\n });\n\n observer.observe(chipsContainer, { childList: true, subtree: true });\n\n return () => observer.disconnect();\n }, []);\n\n const onConfirm: React.FormEventHandler = (event) => {\n event.preventDefault();\n setShowNotification(false);\n errorController.clearValidationError(timezoneValidationName);\n\n const minNumberOfSelectedSlots = 3;\n\n if (!timeZone) {\n errorController.setValidationError(\n timezoneValidationName,\n intl.formatMessage(messages.mobilePhlebotomyTimeslotsValidationMessage)\n );\n\n return;\n }\n\n if (selectedSlots.length < minNumberOfSelectedSlots) {\n setShowNotification(true);\n }\n\n if (timeZone && selectedSlots.length >= minNumberOfSelectedSlots) {\n const formattedTimeSlots = R.mergeAll(\n selectedSlots.map((timeSlot, index) => ({\n [`start${index + 1}`]: timeSlot[\"start\"].toISOString(),\n [`end${index + 1}`]: timeSlot[\"end\"].toISOString(),\n }))\n );\n\n handleConfirm({\n timeSlots: formattedTimeSlots,\n timeZone: timeZone,\n });\n }\n };\n\n const handleTimezoneSelect = (timezone: string) => {\n errorController.clearValidationError(timezoneValidationName);\n setTimeZone(timezone);\n };\n\n const setRemoveTimeslotAriaLabelForm = (slot: DateRange) => {\n return setRemoveTimeslotAriaLabel(slot, intl);\n };\n\n return (\n \n );\n};\n\nexport default TimeslotsForm;\n","export { default } from \"./zipSelectorForm\";\nexport { ZipSelector } from \"./zipSelectorForm\";\n","import React from \"react\";\nimport { Form } from \"@natera/form\";\nimport { FormField } from \"@app/components\";\nimport { useErrorController } from \"@natera/platform/lib/hooks\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { isValidZip } from \"@app/utils\";\nimport Tooltip from \"@natera/material/lib/tooltip\";\nimport { HeapPHIDecorator } from \"@app/components/analytics\";\nimport { Textfield } from \"@natera/material/lib/textfield\";\nimport { IntlMessage } from \"@app/provider/types\";\n\nimport \"./zipSelectorForm.scss\";\n\nconst messages: IntlMessage = defineMessages({\n labCollectionZipSelectorPlaceholder: {\n id: \"labCollectionZipSelectorPlaceholder\",\n defaultMessage: \"Enter Your Zip Code\",\n },\n labCollectionZipSelectorTooltip: {\n id: \"labCollectionZipSelectorTooltip\",\n defaultMessage:\n \"Required format: 5-digit number, or 9-digit number with a dash after the 5th digit XXXXX or XXXXX-XXXX\",\n },\n labCollectionZipSelectorZipCodeLabel: {\n id: \"labCollectionZipSelectorZipCodeLabel\",\n defaultMessage: \"Zip Code\",\n },\n labCollectionZipSelectorInvalidZipCode: {\n id: \"labCollectionZipSelectorInvalidZipCode\",\n defaultMessage: \"Please enter a valid zip code\",\n },\n labCollectionZipSelectorNoLabs: {\n id: \"labCollectionZipSelectorNoLabs\",\n defaultMessage: \"No labs found in the specified location.\",\n },\n labCollectionZipSelectorRequired: {\n id: \"labCollectionZipSelectorRequired\",\n defaultMessage: \"This information is required.\",\n },\n});\n\nexport enum ZipValidationErrors {\n INVALID_ZIP_CODE = \"INVALID_ZIP_CODE\",\n NO_LAB = \"NO_LAB\",\n EMPTY = \"EMPTY\",\n}\n\nconst errorMessagesMapper: Record<\n ZipValidationErrors,\n keyof typeof messages\n> = {\n [ZipValidationErrors.INVALID_ZIP_CODE]:\n \"labCollectionZipSelectorInvalidZipCode\",\n [ZipValidationErrors.NO_LAB]: \"labCollectionZipSelectorNoLabs\",\n [ZipValidationErrors.EMPTY]: \"labCollectionZipSelectorRequired\",\n};\n\ntype Props = {\n onSubmit: (zipCode: string) => void;\n actions: React.ReactNode;\n zipValidationErrorKey: ZipValidationErrors | null;\n setZipValidationErrorKey: React.Dispatch<\n React.SetStateAction\n >;\n};\n\nconst ZipSelectorForm: React.FC = ({\n onSubmit,\n actions,\n zipValidationErrorKey,\n setZipValidationErrorKey,\n}) => {\n const intl = useIntl();\n const [zipCode, setZipCode] = React.useState(\"\");\n\n const onChange: React.ChangeEventHandler = (event) => {\n setZipValidationErrorKey(null);\n setZipCode(event.target.value);\n };\n\n const handleSubmit: React.FormEventHandler = (event) => {\n event.preventDefault();\n\n setZipValidationErrorKey(null);\n\n if (isValidZip(zipCode)) {\n onSubmit(zipCode);\n } else {\n zipCode.length === 0\n ? setZipValidationErrorKey(ZipValidationErrors.EMPTY)\n : setZipValidationErrorKey(ZipValidationErrors.INVALID_ZIP_CODE);\n }\n };\n\n return (\n \n );\n};\n\ntype ZipSelectorProps = {\n zipCode?: string;\n onChange: React.ChangeEventHandler;\n zipValidationErrorKey?: ZipValidationErrors | null;\n label?: string;\n};\n\nexport const ZipSelector: React.FC = ({\n zipCode,\n onChange,\n zipValidationErrorKey,\n label,\n}) => {\n const errorController = useErrorController();\n const intl = useIntl();\n\n React.useEffect(() => {\n if (zipValidationErrorKey) {\n const messageDescriptor =\n messages[errorMessagesMapper[zipValidationErrorKey]];\n\n errorController.setValidationError(\n \"zip\",\n intl.formatMessage(messageDescriptor)\n );\n } else {\n errorController.clearValidationError(\"zip\");\n }\n }, [intl.locale, zipValidationErrorKey]);\n\n return (\n \n \n \n \n \n \n
\n \n \n );\n};\n\nexport default ZipSelectorForm;\n","import React, { FC, useContext } from \"react\";\nimport classNames from \"classnames\";\nimport { Link } from \"@natera/navigation\";\nimport { IconButton } from \"@natera/material/lib/button\";\nimport Svg from \"@natera/material/lib/svg\";\nimport { UppAuthContext } from \"@app/provider\";\nimport LanguageSelector from \"@app/components/languageSelector\";\nimport Logo from \"@assets/svg/natera-portal-logo.svg\";\nimport MenuSvg from \"@assets/svg/icons/menu.svg\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nimport \"./header.scss\";\n\nconst messages = defineMessages({\n mainMenuButton: {\n id: \"mainMenuButton\",\n defaultMessage: \"Main menu\",\n },\n mainMenuNateraHomeLogo: {\n id: \"mainMenuNateraHomeLogo\",\n defaultMessage: \"Natera home\",\n },\n});\n\ninterface HeaderProps {\n isWidthLimited?: boolean;\n isBurgerVisible?: boolean;\n toggleMenu?: () => void;\n}\n\nconst Header: FC = ({\n isWidthLimited,\n isBurgerVisible,\n toggleMenu,\n}) => {\n const { profile } = useContext(UppAuthContext);\n const intl = useIntl();\n\n return (\n \n );\n};\n\nexport default Header;\n","export { default } from \"./header\";\n","import React, { FC } from \"react\";\nimport Svg from \"@natera/material/lib/svg\";\nimport CloseIcon from \"@assets/svg/icons/close.svg\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nimport \"./highlightWrapper.scss\";\n\nconst messages = defineMessages({\n highlightedTooltipTitle: {\n id: \"highlightedTooltipTitle\",\n defaultMessage: \"Use the same login method\",\n },\n});\n\nexport type TooltipPosition = \"bottom\" | \"top\";\n\nexport interface CustomTooltipProps {\n onClose: () => void;\n topPosition: number;\n description: string;\n updateSize: (size: number) => void;\n tooltipPosition: TooltipPosition;\n}\n\nexport const CustomTooltip: FC = ({\n onClose,\n topPosition,\n description,\n updateSize,\n tooltipPosition,\n}) => {\n const intl = useIntl();\n\n const tooltipRef = React.useRef(null);\n\n React.useEffect(() => {\n if (tooltipRef.current) {\n const { height } = tooltipRef.current.getBoundingClientRect();\n updateSize(height + 8); // 8 - delta\n }\n }, [updateSize]);\n\n return (\n \n
\n
\n \n
\n
\n
\n {intl.formatMessage(messages.highlightedTooltipTitle)}\n
\n
{description}
\n
\n
\n
\n
\n );\n};\n","import React, { FC } from \"react\";\nimport classNames from \"classnames\";\nimport { CustomTooltip, TooltipPosition } from \"./customTooltip\";\n\nimport \"./highlightWrapper.scss\";\n\ntype TypeOfElem = \"button\" | \"form\";\n\nexport interface HighlightWrapperProps {\n isHighlighted: boolean;\n highlightedElem: TypeOfElem;\n tooltipDescription: string;\n tooltipPosition: TooltipPosition;\n}\n\nconst HighlightWrapper: FC = ({\n children,\n highlightedElem,\n isHighlighted,\n tooltipDescription,\n tooltipPosition,\n}) => {\n const childRef = React.useRef(null);\n\n const [isActive, setIsActive] = React.useState(isHighlighted);\n const [tooltipMargin, setTooltipMargin] = React.useState(0);\n const [tooltipHeight, setTooltipHeight] = React.useState(0);\n\n const handleClose = () => {\n setIsActive(false);\n };\n\n const updateTooltipSize = (size: number) => {\n setTooltipHeight(size);\n };\n\n React.useEffect(() => {\n if (childRef.current) {\n const rect = childRef.current.getBoundingClientRect();\n tooltipPosition === \"top\"\n ? setTooltipMargin(rect.top + window.scrollY - tooltipHeight)\n : setTooltipMargin(rect.bottom + window.scrollY + 8);\n }\n }, [children]);\n\n return (\n \n
\n \n
\n
\n\n
\n {children}\n
\n
\n );\n};\n\nexport default HighlightWrapper;\n","import { ServiceContext, UppAuthContext } from \"@app/provider\";\nimport Queue from \"yocto-queue\";\n\nimport React, { useContext, useEffect, useState, useCallback } from \"react\";\nimport { useDialog } from \"@natera/platform/lib/hooks\";\nimport IdleDialog from \"./idleDialog\";\nimport { useTimers, useEventListeners } from \"@app/hooks\";\ninterface IdleWrapperProps {\n timeoutDelay?: number;\n openedDialogDelay?: number;\n}\n\nconst IdleWrapperComponent: React.FC = ({\n timeoutDelay = 1000 * 60 * 28,\n openedDialogDelay = 1000 * 60 * 2,\n}) => {\n const queue = new Queue();\n\n const { logout } = useContext(UppAuthContext);\n const { sessionService } = useContext(ServiceContext);\n\n const [openedDialog, setOpenedDialog] = useState(false);\n\n const dialog = useDialog(IdleDialog);\n\n const [loading, setLoading] = useState(false);\n\n const handleOpenDialog = () => {\n setOpenedDialog(true);\n dialog.open({\n handleCloseDialog,\n handleLogout,\n loading,\n openedDialogDelay,\n });\n };\n\n const handleCloseDialog = () => {\n setOpenedDialog(false);\n dialog.close();\n addListeners();\n resetTimers();\n };\n\n const handleLogout = () => {\n setLoading(true);\n logout();\n };\n\n const renewToken = async () => {\n const estimate = await sessionService.getToken().then((token) => {\n if (!token) {\n return;\n }\n return token?.expiresAt;\n });\n\n if (!estimate) {\n logout();\n }\n\n if (estimate) {\n const timeDifference =\n new Date(estimate).getTime() - new Date().getTime();\n const delaySum = timeoutDelay + openedDialogDelay;\n delaySum < timeDifference && sessionService.renewToken();\n }\n queue.clear();\n };\n\n const { setTimer: addTimers, clearTimer: removeTimers } = useTimers(\n handleOpenDialog,\n timeoutDelay\n );\n\n const resetTimers = useCallback(() => {\n removeTimers();\n\n queue.enqueue(\"Renew token\");\n if (queue.size === 1) {\n renewToken();\n }\n\n addTimers();\n }, []);\n\n const { addListeners, removeListeners } = useEventListeners(\n resetTimers,\n [\"mousemove\", \"mousedown\", \"keydown\", \"touchstart\", \"nevaLogEvent\"],\n window,\n { passive: true }\n );\n\n useEffect(() => {\n if (openedDialog) {\n removeListeners();\n removeTimers();\n }\n }, [openedDialog]);\n\n return <>{dialog.getDialog()}>;\n};\n\nexport default IdleWrapperComponent;\n","import Button from \"@natera/material/lib/button\";\nimport Dialog from \"@natera/material/lib/dialog\";\nimport React, { useCallback } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { useTimers, useEventListeners } from \"@app/hooks\";\nimport \"./idle.scss\";\n\nconst messages = defineMessages({\n idleDialogStillThere: {\n id: \"idleDialogStillThere\",\n defaultMessage: \"Are you still there?\",\n },\n idleDialogSessionOut: {\n id: \"idleDialogSessionOut\",\n defaultMessage:\n \"Your session will time out soon. Do you wish to stay logged in?\",\n },\n idleDialogLogOut: {\n id: \"idleDialogLogOut\",\n defaultMessage: \"Log out\",\n },\n idleDialogStay: {\n id: \"idleDialogStay\",\n defaultMessage: \"Stay\",\n },\n});\n\ninterface IdleDialogI {\n loading: boolean;\n handleLogout: () => void;\n handleCloseDialog: () => void;\n openedDialogDelay: number;\n}\n\nconst IdleDialog: React.FC = ({\n loading,\n handleLogout,\n handleCloseDialog,\n openedDialogDelay,\n}) => {\n const intl = useIntl();\n const { setTimer: addTimers, clearTimer: removeTimers } = useTimers(\n handleLogout,\n openedDialogDelay\n );\n\n const resetTimers = useCallback(() => {\n removeTimers();\n addTimers();\n }, []);\n\n useEventListeners(\n resetTimers,\n [\"mousemove\", \"mousedown\", \"keydown\", \"touchstart\", \"nevaLogEvent\"],\n window,\n { passive: true }\n );\n\n return (\n \n );\n};\n\nexport default IdleDialog;\n","export { default } from \"./idle\";\n","export { default as Header } from \"./header\";\nexport { default as Navigation } from \"./navigation\";\nexport { default as Progress } from \"./progress\";\nexport { default as Notification } from \"./notification\";\nexport { default as CommonErrorNotification } from \"./commonErrorNotification\";\nexport { default as PasswordNotice, usePasswordPolicy } from \"./passwordNotice\";\nexport { default as SpinnerView } from \"./spinnerView\";\nexport { default as TestCard } from \"./testCard\";\nexport { default as PasswordField } from \"./ui/inputs/passwordField\";\nexport { default as SignInWithAuthenticationProviders } from \"./signInWithAuthenticationProviders\";\nexport { default as AcknowledgmentsDialog } from \"./acknowledgmentsDialog\";\nexport { default as DropdownWrapper } from \"./dropdownWrapper\";\nexport { default as SecondaryActionCard } from \"./secondaryActionCard\";\nexport { default as CompassionateCareDialog } from \"./compassionateCareDialog\";\nexport { default as BlueHeader } from \"./ui/layout/blueHeader\";\nexport { default as DetailInformationButton } from \"./detailInformationButton\";\nexport { default as InformationCard } from \"./informationCard\";\nexport { default as KitDetailsSection } from \"./kitDetailsSection\";\nexport { default as TestInformationCard } from \"./testInformationCard\";\nexport { default as CaPnsSupplementalDialog } from \"./viewResultDialogs/caPnsSupplementalDialog\";\nexport { default as BaseModalDialog } from \"./baseModalDialog\";\nexport { default as AppointmentDetails } from \"./appointmentDetails\";\nexport { default as MyResultsSection } from \"./myResultsSection\";\nexport { default as InfoCard } from \"./infoCard\";\nexport { default as InfoCardField } from \"./infoCardField\";\nexport { PhoneField, UpdatePhoneForm } from \"./updatePhone\";\nexport { default as Pagination } from \"./pagination\";\nexport { default as DateRange } from \"./dateRange\";\nexport { default as CommonAddressForm } from \"./commonAddressForm\";\nexport { default as CommonFormActionsView } from \"./commonFormActionsView\";\nexport { default as CommonFormActions } from \"./commonFormActions\";\nexport { default as UpdatePersonalInformationForm } from \"./updatePersonalInformationForm\";\nexport { default as UpdateCommunicationForm } from \"./updateCommunicationForm\";\nexport { default as ProviderType } from \"./providerType\";\nexport { default as LinkHeap } from \"./linkHeap\";\nexport { default as VerificationPhoneModal } from \"./verificationPhoneModal\";\nexport { default as VideoPlayer } from \"./videoPlayer\";\nexport { default as FormField } from \"./ui/inputs/formField\";\nexport { default as PartnerInfo } from \"./partnerInfo\";\nexport { default as FetalSex } from \"./fetalSexInResults\";\nexport { default as FlowHeader } from \"./flowHeader\";\nexport { default as MultipleInsurancesSelector } from \"./ui/inputs/multipleInsurancesSelector\";\nexport {\n CancelAppointmentDialog,\n CancelAppointmentDialogFail,\n CancelAppointmentDialogSuccess,\n CancelSimpleOrderTestDialogFail,\n} from \"./dialogs\";\nexport { default as FinancialAidCard } from \"./financialAidCard\";\nexport { default as LanguageSelector } from \"./languageSelector\";\nexport { default as SetupProfileReviewInfo } from \"./setupProfileReviewInfo\";\nexport { default as BillingUpdatesCard } from \"./billingUpdatesCard\";\nexport { default as BillingUpdatesPageNotificationCard } from \"./billingUpdatesPageNotificationCard\";\nexport { default as SentEmailAfterUnlockView } from \"./sentEmailAfterUnlockView\";\n","export { default } from \"./infoCard\";\n","import React, { FC, ReactNode } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { LinkButton } from \"@natera/form\";\nimport classNames from \"classnames\";\nimport { Link } from \"@natera/navigation\";\n\nimport \"./infoCard.scss\";\n\nconst messages = defineMessages({\n infoCardEditButtonText: {\n id: \"infoCardEditButtonText\",\n defaultMessage: \"Edit\",\n },\n});\n\ninterface Props {\n titleText?: string;\n titleEditButtonLinkRoute?: string;\n notification?: ReactNode;\n className?: string;\n}\n\nconst InfoCard: FC = ({\n titleText,\n titleEditButtonLinkRoute,\n notification,\n className,\n children,\n}) => {\n const intl = useIntl();\n\n return (\n \n {notification ? (\n
{notification}
\n ) : null}\n {titleText && (\n
\n
{titleText}
\n {titleEditButtonLinkRoute && (\n }\n outlined\n >\n {intl.formatMessage(messages.infoCardEditButtonText)}\n \n )}\n \n )}\n {children &&
{children}
}\n
\n );\n};\n\nexport default InfoCard;\n","export { default } from \"./infoCardField\";\n","import React, { FC, ReactNode } from \"react\";\nimport { DisplayField } from \"@natera/form\";\nimport { FormField } from \"@app/components\";\nimport \"./infoCardField.scss\";\n\ninterface Props {\n label: ReactNode | string;\n value?: ReactNode | string;\n}\n\nconst InfoCardField: FC = ({ label, value, ...props }) => {\n return (\n \n \n {value}
\n >\n }\n />\n \n );\n};\n\nexport default InfoCardField;\n","export { default } from \"./informationCard\";\n","import React, { FC, ReactNode } from \"react\";\nimport Svg from \"@natera/material/lib/svg\";\nimport \"./informationCard.scss\";\n\nexport interface InformationCardProps {\n headerIcon?: string;\n headerText?: string;\n content?: ReactNode;\n}\n\nconst InformationCard: FC = ({\n headerIcon,\n headerText,\n content,\n}) => {\n return (\n \n {headerIcon && headerText && (\n
\n )}\n
{content}
\n
\n );\n};\n\nexport default InformationCard;\n","export { default } from \"./kitDetailsSection\";\n","import React, { FC, useContext } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { ConfigContext } from \"@app/provider\";\nimport { openNewWindow } from \"@app/utils\";\nimport { Button } from \"@natera/form\";\nimport { Utils } from \"@natera/material/lib/date\";\n\nimport Svg from \"@natera/material/lib/svg\";\nimport Box from \"@assets/svg/icons/box.svg\";\nimport \"./kitDetailsSection.scss\";\n\nexport interface KitDetailsProps {\n trackingNumber: string;\n kitShippedDate: string;\n}\n\nconst messages = defineMessages({\n kitDetailsTitle: {\n id: \"kitDetailsTitle\",\n defaultMessage: \"Kit Details\",\n },\n kitDetailsShipped: {\n id: \"kitDetailsShipped\",\n defaultMessage: \"Shipped on {date}\",\n },\n kitDetailsTrack: {\n id: \"kitDetailsTrack\",\n defaultMessage: \"Track Shipment\",\n },\n kitTrackingNotAvailable: {\n id: \"kitTrackingNotAvailable\",\n defaultMessage:\n \"We're sorry. Kit tracking information is not available at the moment.\",\n },\n});\n\nconst KitDetailsSection: FC = ({\n trackingNumber,\n kitShippedDate,\n}) => {\n const intl = useIntl();\n const { config } = useContext(ConfigContext);\n const shippedDate = Utils.getUSLocaleDate(new Date(kitShippedDate));\n\n const trackKitStatus = () => {\n openNewWindow(`${config.links.TRACKING}${trackingNumber}`);\n };\n\n return (\n \n
\n
\n
\n
\n {intl.formatMessage(messages.kitDetailsTitle)}\n \n
\n {intl.formatMessage(messages.kitDetailsShipped, {\n date: shippedDate,\n })}\n
\n
\n
\n
\n
\n );\n};\n\nexport default KitDetailsSection;\n","export { default } from \"./languageSelector\";\n","import React, { FC, useContext, useRef } from \"react\";\nimport { useLocation } from \"react-router-dom\";\nimport {\n IntlContext,\n Language,\n UppAuthContext,\n UserContext,\n} from \"@app/provider\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { routes } from \"@app/routing\";\nimport { MaterialOption, MaterialSelect } from \"@natera/material/lib/select\";\nimport DownArrow from \"@assets/svg/icons/down-arrow.svg\";\nimport \"./languageSelector.scss\";\n\nconst messages = defineMessages({\n languageSelectorMenuAriaLabel: {\n id: \"languageSelectorMenuAriaLabel\",\n defaultMessage: \"Select language\",\n },\n languageSelectorMenuItemEnglishAriaLabel: {\n id: \"languageSelectorMenuItemEnglishAriaLabel\",\n defaultMessage: \"English\",\n },\n languageSelectorMenuItemSpanishAriaLabel: {\n id: \"languageSelectorMenuItemSpanishAriaLabel\",\n defaultMessage: \"Spanish\",\n },\n});\n\nconst LanguageSelector: FC = () => {\n const intl = useIntl();\n const location = useLocation();\n\n const { updateUser, updateUserLanguageNonAuth } = useContext(UserContext);\n const { profile } = useContext(UppAuthContext);\n const { changeLanguage, currentLanguage } = useContext(IntlContext);\n const { signUpEmail } = useContext(UppAuthContext);\n const selectRef = useRef(null);\n const isMPGuestPage = location.pathname === routes.scheduleBloodDraw;\n const isOnActivationPage = location.pathname === routes.activation;\n\n const [isExpanded, setIsExpanded] = React.useState(false);\n\n const handleFocus = () => setIsExpanded(true);\n const handleBlur = () => setIsExpanded(false);\n\n React.useEffect(() => {\n const selectElement = document.querySelector(\".mdc-select__anchor\");\n if (selectElement) {\n selectElement.removeAttribute(\"aria-haspopup\");\n }\n }, []);\n\n const switchLanguage = (code: Language) => () => {\n if (!isMPGuestPage) {\n if (isOnActivationPage) {\n updateUserLanguageNonAuth({ email: signUpEmail, language: code });\n } else if (profile) {\n updateUser({\n language: code,\n });\n }\n }\n changeLanguage(code);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n setIsExpanded(false);\n selectRef.current?.blur();\n }\n };\n\n const getItemLabel = (code: Language) => {\n return code === Language.EN\n ? intl.formatMessage(messages.languageSelectorMenuItemEnglishAriaLabel)\n : intl.formatMessage(messages.languageSelectorMenuItemSpanishAriaLabel);\n };\n\n const nextLanguage =\n currentLanguage === Language.EN ? Language.ES : Language.EN;\n\n return (\n {\n if (value && value !== currentLanguage) {\n switchLanguage(value as Language)();\n }\n }}\n role=\"combobox\"\n aria-expanded={isExpanded}\n aria-controls=\"language-dropdown-list\"\n onFocus={handleFocus}\n onBlur={handleBlur}\n >\n \n {nextLanguage.toUpperCase()}\n \n \n );\n};\n\nexport default LanguageSelector;\n","export { default } from \"./linkHeap\";\n","import React, { FC } from \"react\";\nimport { Link, LinkProps } from \"@natera/navigation\";\n\nexport type HeapEventProps = { [key: string]: unknown };\n\ninterface LinkHeapProps extends LinkProps {\n heapEventName?: string;\n heapEventProps?: HeapEventProps;\n}\n\nconst LinkHeap: FC = ({\n heapEventName,\n heapEventProps,\n onClick,\n children,\n ...props\n}) => {\n const clickHandler: React.MouseEventHandler = (e) => {\n // Assure that the click handler is called before heap tracking - in case heap fails.\n // Keep in mind, that the timing of heap.track may be wrong. Perhaps we should\n // capture the timestamp before calling onClick, and then send that as a Heap parameter\n // (if that capability exists)\n onClick && onClick(e);\n heapEventName && heap.track(heapEventName, heapEventProps);\n };\n\n return (\n \n {children}\n \n );\n};\n\nexport default LinkHeap;\n","export { default } from \"./myResultCard\";\n","import React, { FC } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { InfoCard } from \"@natera/patient\";\nimport { TestResultDocument } from \"@app/provider/testResult\";\nimport { convertDate } from \"@app/utils\";\nimport { Button } from \"@natera/form\";\n\nimport ContactIcon from \"@assets/svg/icons/contact.svg\";\n\nimport \"./myResultCard.scss\";\n\nconst messages = defineMessages({\n myResultCardTitle: {\n id: \"myResultCardTitle\",\n defaultMessage: \"My Result\",\n },\n myResultCardView: {\n id: \"myResultCardView\",\n defaultMessage: \"View\",\n },\n});\n\ninterface MyResultCardProps {\n doc: TestResultDocument;\n openResultPdf: (documentUid: string) => Promise;\n}\n\nconst MyResultCard: FC = ({ doc, openResultPdf }) => {\n const intl = useIntl();\n\n const releasedDate = doc.releasedToPatientDate ?? doc.releasedToProviderDate;\n const cardDate = releasedDate ? convertDate(releasedDate) : undefined;\n\n return (\n <>\n {doc.document && (\n <>\n \n
{\n openResultPdf(doc.document?.uid ?? \"\");\n }}\n outlined\n >\n {intl.formatMessage(messages.myResultCardView)}\n \n }\n >\n \n
\n {intl.formatMessage(messages.myResultCardTitle)}\n
\n
{cardDate}
\n
\n \n
\n >\n )}\n >\n );\n};\n\nexport default MyResultCard;\n","export { default } from \"./myResultsSection\";\n","import React, { FC, useContext } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Button } from \"@natera/form\";\nimport Svg from \"@natera/material/lib/svg\";\nimport Results from \"@assets/svg/icons/results.svg\";\nimport { ParsedTestCard, TestCardStatus } from \"@app/provider/testData/types\";\nimport { ViewResultContext } from \"@app/provider\";\nimport { getResultReleasedAtMessage } from \"@app/utils/getResultReleasedAtMessage\";\nimport \"./myResultsSection.scss\";\n\nconst messages = defineMessages({\n myResultsTitle: {\n id: \"myResultsTitle\",\n defaultMessage: \"My Results\",\n },\n myResultsReceived: {\n id: \"myResultsReceived\",\n defaultMessage: \"Received\",\n },\n myResultsReceivedOn: {\n id: \"myResultsReceivedOn\",\n defaultMessage: \"Received on {date}\",\n },\n myResultsView: {\n id: \"myResultsView\",\n defaultMessage: \"View Your Results\",\n },\n});\n\ninterface MyResultsProps {\n testCard: ParsedTestCard;\n}\n\nconst MyResultsSection: FC = ({ testCard }) => {\n const intl = useIntl();\n const { openResultPage, openTestResultDetailsPage } = useContext(\n ViewResultContext\n );\n\n const resultReleasedAt = getResultReleasedAtMessage(\n testCard,\n intl,\n messages.myResultsReceivedOn,\n messages.myResultsReceived\n );\n\n const viewResults = () =>\n testCard.status === TestCardStatus.RESULT_READY\n ? openResultPage(testCard)\n : openTestResultDetailsPage(testCard);\n\n return (\n \n
\n
\n
\n
\n {intl.formatMessage(messages.myResultsTitle)}\n \n
{resultReleasedAt}
\n
\n
\n
\n
\n );\n};\n\nexport default MyResultsSection;\n","export { default } from \"./navigation\";\n","export { default } from \"./navItem\";\n","import React, { FC, useCallback, useEffect, useState } from \"react\";\nimport { useLocation } from \"react-router-dom\";\nimport Svg from \"@natera/material/lib/svg\";\nimport { LinkHeap } from \"@app/components\";\nimport { routes, profileRoutes } from \"@app/routing\";\nimport classNames from \"classnames\";\nimport { HeapEventProps } from \"@app/components/linkHeap/linkHeap\";\nimport \"./navItem.scss\";\n\ninterface NavItemProps extends React.HTMLAttributes {\n to: string | { pathname: string };\n icon?: string;\n target?: string;\n rel?: string;\n activePrefix?: string;\n isMobileMenu?: boolean;\n heapEventName?: string;\n heapEventProps?: HeapEventProps;\n}\n\nconst NavItem: FC = ({\n className,\n children,\n activePrefix,\n to,\n icon,\n target,\n rel,\n isMobileMenu,\n heapEventName,\n heapEventProps,\n ...props\n}) => {\n const location = useLocation();\n const [profileLinkIsClickable, setProfileLinkIsClickable] = useState(\n true\n );\n\n const isProfilePages = () => {\n return (\n to === routes.profile &&\n Object.values(profileRoutes).includes(location.pathname)\n );\n };\n\n useEffect(() => {\n const linkIsClickable = isProfilePages() && isActive() && !isMobileMenu;\n setProfileLinkIsClickable(!linkIsClickable);\n }, [location.pathname, isMobileMenu]);\n\n const isActive = useCallback(\n () =>\n location.pathname.startsWith(activePrefix || String(to)) ||\n isProfilePages(),\n [location]\n );\n\n return (\n \n \n <>\n \n {icon && }\n \n\n {children}\n >\n \n \n );\n};\n\nexport default NavItem;\n","import React, { FC } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nimport Button from \"@natera/material/lib/button\";\nimport { routes } from \"@app/routing\";\nimport { ResultCodes } from \"@app/service/resultCodes\";\nimport HomeSvg from \"@assets/svg/icons/home.svg\";\nimport BillingSvg from \"@assets/svg/icons/billing.svg\";\nimport AccountSvg from \"@assets/svg/icons/account.svg\";\nimport PhoneSvg from \"@assets/svg/icons/phone.svg\";\nimport HistorySvg from \"@assets/svg/icons/history.svg\";\nimport ScheduleSvg from \"@assets/svg/icons/schedule.svg\";\nimport ExitSvg from \"@assets/svg/icons/exit.svg\";\nimport NavItem from \"./navItem\";\nimport { Link, useNavigate } from \"react-router-dom\";\nimport Logo from \"@assets/svg/natera-portal-logo.svg\";\nimport Svg from \"@natera/material/lib/svg\";\nimport { ConfigContext } from \"@app/provider\";\nimport { HeapEventLocation, HEAP_EVENTS } from \"@app/provider/types\";\nimport classNames from \"classnames\";\nimport \"./navigation.scss\";\n\nconst messages = defineMessages({\n navigationHome: {\n id: \"navigationHome\",\n defaultMessage: \"Home\",\n },\n navigationBillingCenter: {\n id: \"navigationBillingCenter\",\n defaultMessage: \"Billing Center\",\n },\n navigationMyAccount: {\n id: \"navigationMyAccount\",\n defaultMessage: \"My Account\",\n },\n navigationTestHistory: {\n id: \"navigationTestHistory\",\n defaultMessage: \"Test History\",\n },\n navigationSheduleGis: {\n id: \"navigationSheduleGis\",\n defaultMessage: \"Schedule a Genetic Information Session\",\n },\n navigationPayMyBill: {\n id: \"navigationPayMyBill\",\n defaultMessage: \"Pay My Bill\",\n },\n navigationContactUs: {\n id: \"navigationContactUs\",\n defaultMessage: \"Contact Us\",\n },\n navigationSignOut: {\n id: \"navigationSignOut\",\n defaultMessage: \"Log Out\",\n },\n navigationNateraHomeLogo: {\n id: \"navigationNateraHomeLogo\",\n defaultMessage: \"Natera home\",\n },\n});\n\ninterface Props {\n isMenuOpen: boolean;\n toggleMenu: () => void;\n}\n\nconst Navigation: FC = ({ isMenuOpen, toggleMenu }) => {\n const navigate = useNavigate();\n const intl = useIntl();\n const { config } = React.useContext(ConfigContext);\n\n const navigationMainItems = () => (\n <>\n \n {intl.formatMessage(messages.navigationHome)}\n \n\n \n {intl.formatMessage(messages.navigationBillingCenter)}\n \n\n \n {intl.formatMessage(messages.navigationMyAccount)}\n \n >\n );\n\n const handleLogout = () => {\n navigate(`${routes.logOut}?code=${ResultCodes.SIGN_OUT}`);\n };\n\n return (\n <>\n \n \n >\n );\n};\n\nexport default Navigation;\n","export { default, NotificationProps } from \"./notification\";\n","import React, { RefObject, useMemo, forwardRef } from \"react\";\nimport classNames from \"classnames\";\n\nimport { Svg } from \"@natera/material/lib/svg\";\nimport InfoIcon from \"@assets/svg/icons/info.svg\";\nimport WarningIcon from \"@assets/svg/icons/warning.svg\";\nimport ErrorIcon from \"@assets/svg/icons/error.svg\";\nimport SuccessIcon from \"@assets/svg/icons/success.svg\";\nimport \"./notification.scss\";\n\nexport type NotificationType =\n | \"info\"\n | \"warning\"\n | \"error\"\n | \"note\"\n | \"success\";\n\nexport interface NotificationProps\n extends React.HTMLAttributes {\n className?: string;\n icon?: string;\n type?: NotificationType;\n ref?: RefObject;\n titleElem?: React.ReactNode;\n actions?: React.ReactNode;\n}\n\nconst Notification = forwardRef(\n ({ className, icon, titleElem, actions, type, children, ...props }, ref) => {\n const iconElement = useMemo(() => {\n if (icon) {\n return ;\n }\n\n switch (type) {\n case \"info\":\n return ;\n case \"warning\":\n return ;\n case \"error\":\n return ;\n case \"success\":\n return ;\n default:\n return ;\n }\n }, [icon, type]);\n\n return (\n \n {iconElement}\n \n {titleElem &&
{titleElem}
}\n {children}\n {actions &&
{actions}
}\n
\n \n );\n }\n);\n\nNotification.displayName = \"Notification\";\n\nexport default Notification;\n","import React, { FC, useContext } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { Button } from \"@natera/form\";\nimport useIsMobileDimension from \"../../hooks/useIsMobileDimension\";\nimport { ConfigContext } from \"@app/provider\";\n\nimport \"./organHealthSchedulingDialog.scss\";\n\nconst messages = defineMessages({\n ohSchedulingDialogTitle: {\n id: \"ohSchedulingDialogTitle\",\n defaultMessage: \"Scheduling\",\n },\n ohSchedulingDialogContent: {\n id: \"ohSchedulingDialogContent\",\n defaultMessage: \"Please call {phone} to schedule your draw\",\n },\n ohSchedulingDialogCallButton: {\n id: \"ohSchedulingDialogCallButton\",\n defaultMessage: \"Call now\",\n },\n ohSchedulingDialogCopyButton: {\n id: \"ohSchedulingDialogCopyButton\",\n defaultMessage: \"Copy number\",\n },\n});\n\nconst OrganHealthSchedulingDialog: FC<{ onCloseDialog: () => void }> = ({\n onCloseDialog,\n}) => {\n const intl = useIntl();\n const { config } = useContext(ConfigContext);\n\n const PHONE_NUMBER = config.phones.ORGAN_HEALTH_DRAW_REQUEST_SCHEDULING;\n\n const isMobile = useIsMobileDimension();\n\n const copyNumber = async () => {\n await navigator.clipboard.writeText(PHONE_NUMBER);\n };\n\n return (\n \n );\n};\n\nexport default OrganHealthSchedulingDialog;\n","export { default } from \"./pagination\";\n","import React, { FC, useEffect, useState } from \"react\";\nimport PaginationArrowIcon from \"@assets/svg/icons/pagination-arrow.svg\";\nimport Button from \"@natera/material/lib/button\";\nimport \"./pagination.scss\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nconst messages = defineMessages({\n previousPageButton: {\n id: \"previousPageButton\",\n defaultMessage: \"Previous page\",\n },\n nextPageButton: {\n id: \"nextPageButton\",\n defaultMessage: \"Next page\",\n },\n});\n\ninterface Props {\n handlePage: (page: number, from?: Date, to?: Date) => void;\n currentPage: number;\n total: number;\n pagesToShow?: number;\n rangeDate?: { from?: Date; to?: Date };\n}\n\nconst PAGES_TO_SHOW = 3;\n\nconst Pagination: FC = ({\n handlePage,\n total,\n currentPage,\n pagesToShow = PAGES_TO_SHOW,\n rangeDate,\n}) => {\n const [middleElement, setMiddleElement] = useState(1);\n const intl = useIntl();\n\n useEffect(() => {\n if (currentPage === 0 && middleElement !== 1) {\n setMiddleElement(1);\n }\n }, [currentPage, total]);\n\n const handlePageClick = (e: React.MouseEvent) => {\n const pageNum = e.currentTarget.getAttribute(\"data-page\");\n const targetPage = Number(pageNum);\n handlePage(targetPage, rangeDate?.from, rangeDate?.to);\n if (targetPage > 0 && targetPage < total - 1) {\n setMiddleElement(targetPage);\n }\n };\n const handleNextClick = () => {\n handlePage(currentPage + 1, rangeDate?.from, rangeDate?.to);\n if (currentPage === middleElement + 1 && middleElement < total - 1) {\n setMiddleElement(middleElement + 1);\n }\n };\n const handlePrevClick = () => {\n handlePage(currentPage - 1, rangeDate?.from, rangeDate?.to);\n if (currentPage === middleElement - 1 && middleElement > 0) {\n setMiddleElement(middleElement - 1);\n }\n };\n\n if (!total || total < 2) return null;\n\n const renderPageNums = () => {\n const nums = [];\n for (let i = 0; i < pagesToShow && i < total; i++) {\n const currentElement = i + middleElement - 1;\n nums.push(\n \n );\n }\n return nums;\n };\n\n return (\n \n
\n
{renderPageNums()}
\n
\n
\n );\n};\n\nexport default Pagination;\n","export { default } from \"./partnerInfo\";\n","import React, { FC } from \"react\";\nimport { StepperContext } from \"@natera/stepper\";\nimport PartnerInfoForm from \"@app/components/partnerInfo/partnerInfoForm\";\nimport StepperHeaderProgress from \"@app/components/stepperHeaderProgress\";\nimport { PartnerInfoData } from \"@app/provider/order\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Notification } from \"@app/components\";\n\nimport \"./partnerInfo.scss\";\nimport {\n PartnerInfoStepResolve,\n SimpleOrderStepperContext,\n} from \"@app/provider/simpleOrder/SimpleOrderStepperProvider\";\nimport { Steps } from \"@app/pages/private/simpleOrder\";\n\nconst messages = defineMessages({\n partnerInfoTitle: {\n id: \"partnerInfoTitle\",\n defaultMessage: \"Partner Information\",\n },\n partnerInfoNotification: {\n id: \"partnerInfoNotification\",\n defaultMessage:\n \"Providing partner information is highly recommended as it will allow Natera to coordinate partner testing if requested by your medical provider.\",\n },\n});\n\ninterface PartnerInfoProps {\n initValue?: PartnerInfoStepResolve;\n resolve: (value: PartnerInfoStepResolve) => void;\n}\n\nconst PartnerInfo: FC = ({ resolve, initValue }) => {\n const intl = useIntl();\n const { goBack } = React.useContext(StepperContext);\n const { getSubStepData } = React.useContext(SimpleOrderStepperContext);\n\n const subStepsData = getSubStepData(\n Steps.PARTNER_INFO\n ) as PartnerInfoStepResolve;\n\n const handleSubmit = async (partner: PartnerInfoData) => {\n resolve({\n ...subStepsData,\n partner,\n });\n };\n\n const handleBack = () => {\n goBack();\n };\n\n return (\n <>\n \n {intl.formatMessage(messages.partnerInfoNotification)}\n \n \n \n
\n
\n
\n {intl.formatMessage(messages.partnerInfoTitle)}\n
\n \n
\n
\n
\n >\n );\n};\n\nexport default PartnerInfo;\n","export { default } from \"./partnerInfoForm\";\n","import React, { FC } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { PartnerInfoData } from \"@app/provider/order\";\nimport { Button, DateInput, Form, FormField, Textfield } from \"@natera/form\";\nimport { HeapPHIDecorator } from \"@app/components/analytics\";\nimport {\n useDialog,\n useErrorController,\n usePhoneValidation,\n} from \"@natera/platform/lib/hooks\";\nimport { isPatientMinor, validateEmail, weekDayFormatter } from \"@app/utils\";\nimport { PhoneField } from \"@app/components\";\nimport PartnerInfoProvidingDialog from \"@app/components/partnerInfo/partnerInfoProvidingDialog\";\nimport CalendarIcon from \"@assets/svg/icons/calendar.svg\";\nimport Tooltip from \"@natera/material/lib/tooltip\";\nimport { getPhoneValidationErrorMessage } from \"@app/utils/getPhoneValidationErrorMessage\";\nimport { ConfigContext, UserContext } from \"@app/provider\";\nimport Svg from \"@natera/material/lib/svg\";\n\nconst messages = defineMessages({\n partnerInfoNext: {\n id: \"partnerInfoNext\",\n defaultMessage: \"Next\",\n },\n partnerInfoBack: {\n id: \"partnerInfoBack\",\n defaultMessage: \"Back\",\n },\n partnerInfoFormFirstName: {\n id: \"partnerInfoFormFirstName\",\n defaultMessage: \"First Name\",\n },\n setupPartnerInfoFormFirstNamePlaceholder: {\n id: \"setupPartnerInfoFormFirstNamePlaceholder\",\n defaultMessage: \"Enter Your Partner’s First Name\",\n },\n partnerInfoFormMiddleName: {\n id: \"partnerInfoFormMiddleName\",\n defaultMessage: \"Middle Name\",\n },\n setupPartnerInfoFormMiddleNamePlaceholder: {\n id: \"setupPartnerInfoFormMiddleNamePlaceholder\",\n defaultMessage: \"Enter Your Partner’s Middle Name\",\n },\n partnerInfoFormLastName: {\n id: \"partnerInfoFormLastName\",\n defaultMessage: \"Last Name\",\n },\n setupPartnerInfoFormLastNamePlaceholder: {\n id: \"setupPartnerInfoFormLastNamePlaceholder\",\n defaultMessage: \"Enter Your Partner’s Last Name\",\n },\n partnerInfoFormDOB: {\n id: \"partnerInfoFormDOB\",\n defaultMessage: \"Date of Birth\",\n },\n setupPartnerInfoFormDOBPlaceholder: {\n id: \"setupPartnerInfoFormDOBPlaceholder\",\n defaultMessage: \"MM/DD/YYYY\",\n },\n partnerInfoFormEmail: {\n id: \"partnerInfoFormEmail\",\n defaultMessage: \"Email\",\n },\n setupPartnerInfoFormEmaiPlaceholder: {\n id: \"setupPartnerInfoFormEmaiPlaceholder\",\n defaultMessage: \"Enter Your Partner’s Email\",\n },\n partnerInfoFormUnder18DateOfBirth: {\n id: \"partnerInfoFormUnder18DateOfBirth\",\n defaultMessage: \"Your partner must be 18 years old or older\",\n },\n partnerInfoFormInvalidName: {\n id: \"partnerInfoFormInvalidName\",\n defaultMessage: \"Please enter a valid name\",\n },\n partnerInfoFormInvalidLastName: {\n id: \"partnerInfoFormInvalidLastName\",\n defaultMessage: \"Please enter a valid last name\",\n },\n partnerInfoFormInvalidEmail: {\n id: \"partnerInfoFormInvalidEmail\",\n defaultMessage: \"Please enter a valid email address. (username@domain)\",\n },\n partnerInfoFormEmailFormat: {\n id: \"partnerInfoFormEmailFormat\",\n defaultMessage: \"email format (username@domain)\",\n },\n});\n\nexport interface PartnerInfoFormProps {\n initialPartnerInfo?: PartnerInfoData;\n onSubmit: (partner: PartnerInfoData) => Promise;\n onBack: () => void;\n}\n\nconst PartnerInfoForm: FC = ({\n initialPartnerInfo,\n onSubmit,\n onBack,\n}) => {\n const intl = useIntl();\n const { config } = React.useContext(ConfigContext);\n const usePlusSignInEmailAddress =\n config.test.usePlusSignInEmailAddress.enabled;\n\n const errorController = useErrorController();\n const phoneValidation = usePhoneValidation();\n const { validatePhoneNumber: validateFromPS } = React.useContext(UserContext);\n const partnerInfoProvidingDialog = useDialog(PartnerInfoProvidingDialog);\n\n const containsInvalidNameFields = (\n firstName: string | undefined,\n middleName: string | undefined,\n lastName: string | undefined\n ) => {\n if (firstName && firstName !== firstName.trim()) {\n errorController.setValidationError(\n \"firstName\",\n intl.formatMessage(messages.partnerInfoFormInvalidName)\n );\n return true;\n }\n\n if (middleName && middleName !== middleName.trim()) {\n errorController.setValidationError(\n \"middleName\",\n intl.formatMessage(messages.partnerInfoFormInvalidName)\n );\n return true;\n }\n\n if (lastName && lastName !== lastName.trim()) {\n errorController.setValidationError(\n \"lastName\",\n intl.formatMessage(messages.partnerInfoFormInvalidLastName)\n );\n return true;\n }\n\n return false;\n };\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n errorController.clearErrors();\n\n const formData = new FormData(e.currentTarget);\n\n const firstName = formData.get(\"firstName\")?.toString();\n const middleName = formData.get(\"middleName\")?.toString();\n const lastName = formData.get(\"lastName\")?.toString();\n const dateOfBirth = formData.get(\"dateOfBirth\")?.toString().trim();\n const mobileNumber = formData.get(\"mobileNumber\")?.toString().trim();\n const email = formData.get(\"email\")?.toString().trim();\n\n const requiredFields = [firstName, lastName, dateOfBirth, mobileNumber];\n\n const submitData = () =>\n onSubmit({\n firstName,\n middleName,\n lastName,\n dateOfBirth,\n email,\n phone: mobileNumber,\n });\n\n if (containsInvalidNameFields(firstName, middleName, lastName)) {\n return;\n }\n\n if (dateOfBirth && isPatientMinor(new Date(dateOfBirth))) {\n errorController.setValidationError(\n \"dateOfBirth\",\n intl.formatMessage(messages.partnerInfoFormUnder18DateOfBirth)\n );\n\n return;\n }\n\n if (mobileNumber) {\n const phoneValidationErrorMessage = await getPhoneValidationErrorMessage({\n isMandatory: false,\n mobileNumber,\n intl,\n phoneValidation,\n validateFromPS,\n });\n\n if (phoneValidationErrorMessage) {\n errorController.setValidationError(\n \"mobileNumber\",\n phoneValidationErrorMessage\n );\n return;\n }\n }\n\n if (email && !validateEmail(email, usePlusSignInEmailAddress)) {\n errorController.setValidationError(\n \"email\",\n intl.formatMessage(messages.partnerInfoFormInvalidEmail)\n );\n return;\n }\n\n for (const field of requiredFields) {\n if (!field) {\n partnerInfoProvidingDialog.open({\n onClose: () => partnerInfoProvidingDialog.close(),\n onContinue: submitData,\n });\n return;\n }\n }\n\n submitData();\n };\n\n const DateIconTriggerButton = () => {\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n const dateInput = document.querySelector(\"#date\");\n dateInput?.focus();\n dateInput?.click();\n }\n };\n\n return (\n \n );\n };\n\n return (\n <>\n {partnerInfoProvidingDialog.getDialog()}\n \n >\n );\n};\n\nexport default PartnerInfoForm;\n","export { default } from \"./partnerInfoProvidingDialog\";\n","import React, { FC } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { Button } from \"@natera/form\";\nimport \"./partnerInfoProvidingDialog.scss\";\n\nconst messages = defineMessages({\n partnerInfoDialogTitle: {\n id: \"partnerInfoDialogTitle\",\n defaultMessage: \"Why is it important to provide partner information?\",\n },\n partnerInfoDialogContentProviding: {\n id: \"partnerInfoDialogContentProviding\",\n defaultMessage:\n \"Providing partner information is highly recommended as it will allow Natera to coordinate partner testing if requested by your medical provider.\",\n },\n partnerInfoDialogContentPleaseFillOut: {\n id: \"partnerInfoDialogContentPleaseFillOut\",\n defaultMessage: \"Please fill out the following information:\",\n },\n partnerInfoDialogContentFirsName: {\n id: \"partnerInfoDialogContentFirsName\",\n defaultMessage: \"Your partner's first name\",\n },\n partnerInfoDialogContenLastName: {\n id: \"partnerInfoDialogContenLastName\",\n defaultMessage: \"Your partner's last name\",\n },\n partnerInfoDialogContentDOB: {\n id: \"partnerInfoDialogContentDOB\",\n defaultMessage: \"Your partner's date of birth\",\n },\n partnerInfoDialogContentPhoneNumber: {\n id: \"partnerInfoDialogContentPhoneNumber\",\n defaultMessage: \"Your partner's phone number\",\n },\n partnerInfoDialogContinueBtn: {\n id: \"partnerInfoDialogContinueBtn\",\n defaultMessage: \"Continue Without Providing Partner Details\",\n },\n partnerInfoDialogBackBtn: {\n id: \"partnerInfoDialogBackBtn\",\n defaultMessage: \"Back To Enter Partner Details\",\n },\n});\n\ninterface PartnerInfoProvidingDialogProps {\n onClose: () => void;\n onContinue: () => Promise;\n}\n\nconst PartnerInfoProvidingDialog: FC = ({\n onClose,\n onContinue,\n}) => {\n const intl = useIntl();\n\n return (\n \n
\n
\n );\n};\n\nexport default PartnerInfoProvidingDialog;\n","export { default } from \"./passwordNotice\";\nexport { usePasswordPolicy } from \"./usePasswordPolicy\";\n","import * as React from \"react\";\nimport classNames from \"classnames\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nimport { PasswordComplexityKeys } from \"@app/provider/passwordPolicy\";\nimport { Notification } from \"@app/components\";\nimport Svg from \"@natera/material/lib/svg\";\n\nimport CheckmarkIcon from \"@assets/svg/icons/checkmark.svg\";\nimport PointIcon from \"@assets/svg/icons/point.svg\";\nimport LockIcon from \"@assets/svg/icons/lock.svg\";\nimport \"./passwordNotice.scss\";\n\nconst messages = defineMessages({\n passwordNoticeTitle: {\n id: \"passwordNoticeTitle\",\n defaultMessage: \"Password must include:\",\n },\n passwordRuleNumbers: {\n id: \"passwordRuleNumbers\",\n defaultMessage: \"must contain numbers\",\n },\n passwordRuleUppercase: {\n id: \"passwordRuleUppercase\",\n defaultMessage: \"must contain uppercase letters\",\n },\n passwordRuleLowercase: {\n id: \"passwordRuleLowercase\",\n defaultMessage: \"must contain lowercase letters\",\n },\n passwordRuleSymbol: {\n id: \"passwordRuleSymbol\",\n defaultMessage: \"must have at lest one @#$ symbol\",\n },\n passwordRuleLength: {\n id: \"passwordRuleLength\",\n defaultMessage: \"must be greater than {length} characters\",\n },\n passwordRuleExcludeUsername: {\n id: \"passwordRuleExcludeUsername\",\n defaultMessage: \"must exclude user name\",\n },\n});\n\ninterface PasswordPolicyComplexityValidationStateRule {\n isValid: boolean;\n value: number | boolean;\n}\n\nexport type PasswordPolicyComplexityValidationState = Record<\n PasswordComplexityKeys,\n PasswordPolicyComplexityValidationStateRule | undefined\n>;\n\ninterface PasswordNoticeProps {\n className?: string;\n ref?: React.RefObject;\n passwordPolicyComplexity: PasswordPolicyComplexityValidationState;\n}\n\nconst PasswordNotice = React.forwardRef(\n ({ className, passwordPolicyComplexity, ...props }, ref) => {\n const intl = useIntl();\n\n const renderRule = (\n title: string,\n isValid?: boolean\n ): React.ReactElement => (\n \n {\" \"}\n {title}\n \n );\n\n const renderRules = () => {\n const keys = Object.keys(\n passwordPolicyComplexity\n ) as PasswordComplexityKeys[];\n\n const rules: React.ReactElement[] = [];\n\n for (const key of keys) {\n switch (key) {\n case \"minLength\": {\n if (passwordPolicyComplexity[key]?.value) {\n rules.push(\n renderRule(\n intl.formatMessage(messages.passwordRuleLength, {\n length: passwordPolicyComplexity[key]?.value,\n }),\n passwordPolicyComplexity[key]?.isValid\n )\n );\n }\n break;\n }\n case \"minLowerCase\": {\n if (passwordPolicyComplexity[key] !== undefined) {\n rules.push(\n renderRule(\n intl.formatMessage(messages.passwordRuleLowercase),\n passwordPolicyComplexity[key]?.isValid\n )\n );\n }\n break;\n }\n case \"minUpperCase\": {\n if (passwordPolicyComplexity[key] !== undefined) {\n rules.push(\n renderRule(\n intl.formatMessage(messages.passwordRuleUppercase),\n passwordPolicyComplexity[key]?.isValid\n )\n );\n }\n break;\n }\n case \"minNumber\": {\n if (passwordPolicyComplexity[key] !== undefined) {\n rules.push(\n renderRule(\n intl.formatMessage(messages.passwordRuleNumbers),\n passwordPolicyComplexity[key]?.isValid\n )\n );\n }\n break;\n }\n case \"minSymbol\": {\n if (passwordPolicyComplexity[key] !== undefined) {\n rules.push(\n renderRule(\n intl.formatMessage(messages.passwordRuleSymbol),\n passwordPolicyComplexity[key]?.isValid\n )\n );\n }\n break;\n }\n case \"excludeUsername\": {\n if (passwordPolicyComplexity[key] !== undefined) {\n rules.push(\n renderRule(\n intl.formatMessage(messages.passwordRuleExcludeUsername),\n passwordPolicyComplexity[key]?.isValid\n )\n );\n }\n break;\n }\n }\n }\n\n return rules;\n };\n\n return (\n \n \n
\n
\n {intl.formatMessage(messages.passwordNoticeTitle)}\n
\n
\n
\n
\n
\n \n );\n }\n);\n\nPasswordNotice.displayName = \"PasswordNotice\";\n\nexport default PasswordNotice;\n","import { useContext, useEffect, useState } from \"react\";\nimport { PasswordComplexityKeys } from \"@app/provider/passwordPolicy\";\nimport { Language, PasswordPolicyContext } from \"@app/provider\";\n\nexport interface PasswordPolicyComplexityValidationStateRule {\n isValid: boolean;\n value: number | boolean;\n}\n\nexport type PasswordPolicyComplexityValidationState = Record<\n PasswordComplexityKeys,\n PasswordPolicyComplexityValidationStateRule | undefined\n>;\n\ntype UsePasswordPolicy = (props: {\n password: string;\n email: string;\n currentLanguage?: Language;\n}) => {\n passwordPolicyComplexity: PasswordPolicyComplexityValidationState;\n invalidPasswordRequirement: string | undefined;\n};\n\nexport const usePasswordPolicy: UsePasswordPolicy = ({\n password,\n email,\n currentLanguage,\n}) => {\n const [\n passwordPolicyComplexityValidationState,\n setPasswordPolicyComplexityValidationState,\n ] = useState(\n {} as PasswordPolicyComplexityValidationState\n );\n\n const [invalidPasswordRequirement, setInvalidPasswordRequirement] = useState<\n string\n >();\n\n const { passwordPolicy, getPasswordPolicy } = useContext(\n PasswordPolicyContext\n );\n\n useEffect(() => {\n getPasswordPolicy();\n }, []);\n\n useEffect(() => {\n if (passwordPolicy) {\n const complexity = passwordPolicy.complexity;\n\n if (complexity) {\n setPasswordPolicyComplexityValidationState(\n Object.keys(complexity).reduce(\n (acc, key: PasswordComplexityKeys) =>\n complexity[key]\n ? {\n ...acc,\n [key]: {\n isValid: false,\n value: complexity[key],\n },\n }\n : acc,\n {} as PasswordPolicyComplexityValidationState\n )\n );\n }\n }\n }, [passwordPolicy]);\n\n useEffect(() => {\n const {\n excludeUsername,\n minLength,\n minLowerCase,\n minNumber,\n minSymbol,\n minUpperCase,\n } = passwordPolicyComplexityValidationState;\n\n if (minLength?.value && minLength.value > 0) {\n if (password.length >= minLength.value) {\n setPasswordPolicyComplexityValidationState(\n (oldPasswordPolicyComplexity) =>\n ({\n ...oldPasswordPolicyComplexity,\n minLength: {\n ...oldPasswordPolicyComplexity.minLength,\n isValid: true,\n },\n } as PasswordPolicyComplexityValidationState)\n );\n }\n if (password.length < minLength.value) {\n setPasswordPolicyComplexityValidationState(\n (oldPasswordPolicyComplexity) =>\n ({\n ...oldPasswordPolicyComplexity,\n ...{\n minLength: {\n ...oldPasswordPolicyComplexity.minLength,\n isValid: false,\n },\n },\n } as PasswordPolicyComplexityValidationState)\n );\n }\n }\n\n if (minUpperCase?.value && minUpperCase.value > 0) {\n const upperCaseLettersCount = password?.match(/[A-Z]/g)?.length;\n\n if (\n upperCaseLettersCount &&\n upperCaseLettersCount >= minUpperCase.value\n ) {\n setPasswordPolicyComplexityValidationState(\n (oldPasswordPolicyComplexity) =>\n ({\n ...oldPasswordPolicyComplexity,\n minUpperCase: {\n ...oldPasswordPolicyComplexity.minUpperCase,\n isValid: true,\n },\n } as PasswordPolicyComplexityValidationState)\n );\n }\n if (\n !upperCaseLettersCount ||\n upperCaseLettersCount < minUpperCase.value\n ) {\n setPasswordPolicyComplexityValidationState(\n (oldPasswordPolicyComplexity) =>\n ({\n ...oldPasswordPolicyComplexity,\n ...{\n minUpperCase: {\n ...oldPasswordPolicyComplexity.minUpperCase,\n isValid: false,\n },\n },\n } as PasswordPolicyComplexityValidationState)\n );\n }\n }\n\n if (minLowerCase?.value && minLowerCase.value > 0) {\n const lowerCaseLettersCount = password?.match(/[a-z]/g)?.length;\n\n if (\n lowerCaseLettersCount &&\n lowerCaseLettersCount >= minLowerCase.value\n ) {\n setPasswordPolicyComplexityValidationState(\n (oldPasswordPolicyComplexity) =>\n ({\n ...oldPasswordPolicyComplexity,\n minLowerCase: {\n ...oldPasswordPolicyComplexity.minLowerCase,\n isValid: true,\n },\n } as PasswordPolicyComplexityValidationState)\n );\n }\n if (\n !lowerCaseLettersCount ||\n lowerCaseLettersCount < minLowerCase.value\n ) {\n setPasswordPolicyComplexityValidationState(\n (oldPasswordPolicyComplexity) =>\n ({\n ...oldPasswordPolicyComplexity,\n ...{\n minLowerCase: {\n ...oldPasswordPolicyComplexity.minLowerCase,\n isValid: false,\n },\n },\n } as PasswordPolicyComplexityValidationState)\n );\n }\n }\n\n if (minNumber?.value && minNumber.value > 0) {\n const numbersCount = password?.match(/[0-9]/g)?.length;\n\n if (numbersCount && numbersCount >= minNumber.value) {\n setPasswordPolicyComplexityValidationState(\n (oldPasswordPolicyComplexity) =>\n ({\n ...oldPasswordPolicyComplexity,\n minNumber: {\n ...oldPasswordPolicyComplexity.minNumber,\n isValid: true,\n },\n } as PasswordPolicyComplexityValidationState)\n );\n }\n if (!numbersCount || numbersCount < minNumber.value) {\n setPasswordPolicyComplexityValidationState(\n (oldPasswordPolicyComplexity) =>\n ({\n ...oldPasswordPolicyComplexity,\n ...{\n minNumber: {\n ...oldPasswordPolicyComplexity.minNumber,\n isValid: false,\n },\n },\n } as PasswordPolicyComplexityValidationState)\n );\n }\n }\n\n if (excludeUsername) {\n const includesUsername = password?.includes(email);\n\n if (includesUsername) {\n setPasswordPolicyComplexityValidationState(\n (oldPasswordPolicyComplexity) =>\n ({\n ...oldPasswordPolicyComplexity,\n excludeUsername: {\n ...oldPasswordPolicyComplexity.excludeUsername,\n isValid: false,\n },\n } as PasswordPolicyComplexityValidationState)\n );\n }\n if (!includesUsername) {\n setPasswordPolicyComplexityValidationState(\n (oldPasswordPolicyComplexity) =>\n ({\n ...oldPasswordPolicyComplexity,\n ...{\n excludeUsername: {\n ...oldPasswordPolicyComplexity.excludeUsername,\n isValid: true,\n },\n },\n } as PasswordPolicyComplexityValidationState)\n );\n }\n }\n\n if (minSymbol?.value && minSymbol.value > 0) {\n const symbolsCount = password?.match(/[@#$]/g)?.length;\n\n if (symbolsCount && symbolsCount >= minSymbol.value) {\n setPasswordPolicyComplexityValidationState(\n (oldPasswordPolicyComplexity) =>\n ({\n ...oldPasswordPolicyComplexity,\n minSymbol: {\n ...oldPasswordPolicyComplexity.minSymbol,\n isValid: true,\n },\n } as PasswordPolicyComplexityValidationState)\n );\n }\n if (!symbolsCount || symbolsCount < minSymbol.value) {\n setPasswordPolicyComplexityValidationState(\n (oldPasswordPolicyComplexity) =>\n ({\n ...oldPasswordPolicyComplexity,\n ...{\n minSymbol: {\n ...oldPasswordPolicyComplexity.minSymbol,\n isValid: false,\n },\n },\n } as PasswordPolicyComplexityValidationState)\n );\n }\n }\n }, [password, email, currentLanguage]);\n\n useEffect(() => {\n setInvalidPasswordRequirement(\n Object.keys(passwordPolicyComplexityValidationState).find(\n (key: PasswordComplexityKeys) =>\n !passwordPolicyComplexityValidationState[key]?.isValid\n )\n );\n }, [passwordPolicyComplexityValidationState]);\n\n return {\n passwordPolicyComplexity: passwordPolicyComplexityValidationState,\n invalidPasswordRequirement,\n };\n};\n\nexport default usePasswordPolicy;\n","export { default } from \"./patientAcknowledgmentDialog\";\n","import React, { FC } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { Button } from \"@natera/form\";\nimport { SimpleOrderContext } from \"@app/provider\";\n\nimport \"./patientAcknowledgmentDialog.scss\";\n\nconst messages = defineMessages({\n patientAcknowledgmentDialogTitle: {\n id: \"patientAcknowledgmentDialogTitle\",\n defaultMessage: \"Are you sure you want to cancel your test?\",\n },\n patientAcknowledgmentDialogContinueCancellingButton: {\n id: \"patientAcknowledgmentDialogContinueCancellingButton\",\n defaultMessage: \"Continue With Cancelling Test\",\n },\n patientAcknowledgmentDialogBackToPatientAcknowledgment: {\n id: \"patientAcknowledgmentDialogBackToPatientAcknowledgment\",\n defaultMessage: \"Back To Completing Test\",\n },\n});\n\nconst PatientAcknowledgmentDialog: FC<{\n onContinueCancelling: () => void;\n onClose: () => void;\n}> = ({ onContinueCancelling, onClose }) => {\n const intl = useIntl();\n\n const { cancelSimpleOrderIsLoading } = React.useContext(SimpleOrderContext);\n\n return (\n \n
\n }\n onClose={onClose}\n >\n <>>\n \n \n );\n};\n\nexport default PatientAcknowledgmentDialog;\n","import { PaymentType } from \"@app/pages/private/simpleOrder/paymentMethod/paymentMethod\";\nimport { IntlShape, defineMessages } from \"react-intl\";\n\nconst messages = defineMessages({\n paymentMethodSelectionLabelCommercial: {\n id: \"paymentMethodSelectionLabelCommercial\",\n defaultMessage: \"I have a commercial health insurance\",\n },\n paymentMethodSelectionLabelGovernment: {\n id: \"paymentMethodSelectionLabelGovernment\",\n defaultMessage: \"I have Medicaid or government issued insurance\",\n },\n paymentMethodSelectionLabelMultiple: {\n id: \"paymentMethodSelectionLabelMultiple\",\n defaultMessage: \"I have more than one form of health insurance\",\n },\n paymentMethodSelectionLabelDontHave: {\n id: \"paymentMethodSelectionLabelDontHave\",\n defaultMessage: \"I don't have health insurance\",\n },\n paymentMethodSelectionLabelDontWantToBill: {\n id: \"paymentMethodSelectionLabelDontWantToBill\",\n defaultMessage: \"I don't want to bill my insurance\",\n },\n});\n\nexport const getPaymentMethodLabel = (\n type: PaymentType,\n intl: IntlShape\n): string => {\n const getLabel = {\n [PaymentType.COMMERCIAL]: intl.formatMessage(\n messages.paymentMethodSelectionLabelCommercial\n ),\n [PaymentType.GOVERNMENT_ISSUED]: intl.formatMessage(\n messages.paymentMethodSelectionLabelGovernment\n ),\n [PaymentType.MULTIPLE]: intl.formatMessage(\n messages.paymentMethodSelectionLabelMultiple\n ),\n [PaymentType.DO_NOT_HAVE]: intl.formatMessage(\n messages.paymentMethodSelectionLabelDontHave\n ),\n [PaymentType.SELF_PAY]: intl.formatMessage(\n messages.paymentMethodSelectionLabelDontWantToBill\n ),\n };\n\n return getLabel[type];\n};\n","export { default as PaymentMethodSelector } from \"./paymentMethod\";\nexport { getPaymentMethodLabel } from \"./getPaymentMethodLabel\";\n","import { PaymentType } from \"@app/pages/private/simpleOrder/paymentMethod/paymentMethod\";\nimport { RadioButton, RadioGroup } from \"@natera/form\";\nimport React from \"react\";\nimport { useIntl } from \"react-intl\";\nimport { getPaymentMethodLabel } from \"./getPaymentMethodLabel\";\nimport classNames from \"classnames\";\n\nimport \"./paymentMethod.scss\";\n\ntype Props = {\n value?: PaymentType;\n onChange: (value: PaymentType) => void;\n};\n\nconst PaymentMethod: React.FC = ({ value, onChange }) => {\n const intl = useIntl();\n\n const paymentTypes = Object.values(PaymentType);\n\n return (\n \n {paymentTypes.map((paymentType, index) => (\n \n ))}\n \n );\n};\n\nexport default PaymentMethod;\n","export { default } from \"./payorsTypeAhead\";\n","import React from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { PayorContext } from \"@app/provider\";\nimport { Payor } from \"@app/provider/payor\";\nimport { TypeAhead, TypeAheadOption } from \"@natera/form\";\nimport { ErrorController } from \"@natera/platform/lib/hooks\";\n\nimport \"./payorsTypeAhead.scss\";\n\nconst messages = defineMessages({\n payorsTypeAheadPlaceholder: {\n id: \"payorsTypeAheadPlaceholder\",\n defaultMessage: \"Enter insurance company\",\n },\n});\n\nconst SEARCHING_DELAY_TIME = 600;\nconst PAYORS_LIMIT = 100;\n\nexport const payorFieldId = \"payorFieldId\";\n\nexport interface PayorsTypeAheadProps {\n selectedPayor?: Payor;\n onSelect: (item?: Payor) => void;\n errorController?: ErrorController;\n}\n\nconst PayorsTypeAhead: React.FC = ({\n selectedPayor,\n onSelect,\n errorController,\n}) => {\n const intl = useIntl();\n const { getPayors } = React.useContext(PayorContext);\n\n React.useEffect(() => {\n const checkAndRemoveAriaHidden = () => {\n const menuSurface = document.querySelector(\".payors-type-ahead__menu\");\n if (menuSurface) {\n const payorsList = menuSurface.querySelector(\".mdc-deprecated-list\");\n if (payorsList && payorsList.hasAttribute(\"aria-hidden\")) {\n payorsList.removeAttribute(\"aria-hidden\");\n }\n }\n };\n const observer = new MutationObserver(() => {\n checkAndRemoveAriaHidden();\n });\n\n observer.observe(document.body, { childList: true, subtree: true });\n return () => observer.disconnect();\n }, []);\n\n const handlePayorSearch = React.useCallback(\n (value: string) => getPayors(value.trim(), PAYORS_LIMIT),\n [getPayors]\n );\n\n const handleSelect = (item?: Payor) => {\n errorController && errorController.clearValidationError(payorFieldId);\n onSelect(item);\n };\n\n const displayPayorValue = (option: Payor) => option.displayName;\n\n return (\n \n {(options: Payor[]) =>\n options.map((option) => (\n \n {option.displayName}\n \n ))\n }\n \n );\n};\n\nexport default PayorsTypeAhead;\n","export { default as PdfView } from \"./pdfView\";\nexport { default as StaticPdfViewer } from \"./staticPdfViewer\";\n","import React from \"react\";\nimport Svg from \"@natera/material/lib/svg\";\nimport { Document, Page, pdfjs } from \"react-pdf\";\nimport { Button } from \"@natera/form\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nimport { ServiceContext, IntlContext } from \"@app/provider\";\nimport { TestDetailsContext } from \"@app/provider/testData\";\n\nimport CloudError from \"@assets/svg/icons/cloud-error.svg\";\nimport { TestStatus } from \"@app/provider/testData/types\";\nimport \"./pdf.scss\";\nimport { HEAP_EVENTS } from \"@app/provider/types\";\nimport { ScrollContext } from \"@natera/platform/lib/components/scrollbar\";\nimport { capitalizeFirstLetter } from \"@app/utils\";\nimport { businessUnitMapper } from \"@app/utils/businessUnitMapper\";\n\n// https://github.com/wojtekmaj/react-pdf/issues/97\npdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;\n\nconst messages = defineMessages({\n pdfResultsDocument: {\n id: \"pdfResultsDocument\",\n defaultMessage: \"Result Details\",\n },\n pdfYourResults: {\n id: \"pdfyourResults\",\n defaultMessage: \"Your Results\",\n },\n pdfDownload: {\n id: \"pdfDownload\",\n defaultMessage: \"Download\",\n },\n pdfLoadError: {\n id: \"pdfLoadError\",\n defaultMessage: \"Sorry, we cannot retrieve results right now.\",\n },\n pdfSubLoadError: {\n id: \"pdfSubLoadError\",\n defaultMessage: \"Please try again later.\",\n },\n pdfCloseResults: {\n id: \"pdfCloseResults\",\n defaultMessage: \"Close results\",\n },\n pdfDefaultAriaLabel: {\n id: \"pdfDefaultAriaLabel\",\n defaultMessage: \"Document\",\n },\n pdfPage: {\n id: \"pdfPage\",\n defaultMessage: \"Page\",\n },\n});\n\nenum Occurrence {\n firstTime = \"first_time\",\n repeat = \"repeat\",\n}\n\ntype onDocumentLoadSuccess = (pdf: pdfjs.PDFDocumentProxy) => Promise;\ntype onPageLoadSuccess = (pdf: pdfjs.PDFPageProxy) => Promise;\ntype addAttributesToCanvas = (pageNumber: number) => void;\n\ntype Props = {\n url: string;\n downloadUrl: string;\n fileName: string;\n pageAriaLabel?: string;\n};\n\nconst PdfView: React.FC = ({\n url,\n downloadUrl,\n fileName,\n pageAriaLabel,\n}) => {\n const intl = useIntl();\n const { currentLanguage } = React.useContext(IntlContext);\n const { sessionService, fileService } = React.useContext(ServiceContext);\n const { getTestDetails } = React.useContext(TestDetailsContext);\n const [token, setToken] = React.useState(\"\");\n const [isError, setError] = React.useState(false);\n const [numPages, setNumPages] = React.useState(null);\n const [pdfWidth, setPdfWidth] = React.useState();\n\n const refPdfContainer = React.useRef(null);\n\n const testDetails = getTestDetails();\n\n React.useEffect(() => {\n setError(false);\n sessionService\n .getToken()\n .then((authToken) => {\n if (authToken) {\n setToken(authToken.accessToken);\n }\n })\n .catch(() => setError(true));\n }, [url]);\n\n React.useEffect(() => {\n if (isError && testDetails) {\n heap.track(HEAP_EVENTS.upp_viewresultpdf_failure, {\n test_name: capitalizeFirstLetter(testDetails.testType),\n lims_clinic_id: testDetails.clinic?.limsId,\n public_order_uid: testDetails.orderUidPublic,\n occurrence:\n testDetails.viewStatus === TestStatus.VIEWED\n ? Occurrence.repeat\n : Occurrence.firstTime,\n business_unit: businessUnitMapper(testDetails.businessUnit),\n lims_document_id: testDetails.documentReferenceId,\n });\n }\n }, [isError, testDetails]);\n\n const file = React.useMemo(\n () => ({\n url,\n httpHeaders: {\n Authorization: `Bearer ${token ? token : \"\"}`,\n },\n }),\n [url, token]\n );\n\n const onDownload = async () => {\n const result = await fileService.getFile(downloadUrl);\n fileService.download(result, fileName);\n };\n\n const onDocumentLoadSuccess: onDocumentLoadSuccess = async ({\n numPages: nextNumPages,\n }) => {\n setError(false);\n setNumPages(nextNumPages);\n\n if (testDetails) {\n heap.track(HEAP_EVENTS.upp_viewresultpdf_success, {\n test_name: capitalizeFirstLetter(testDetails.testType),\n lims_clinic_id: testDetails.clinic?.limsId,\n public_order_uid: testDetails.orderUidPublic,\n occurrence:\n testDetails.viewStatus === TestStatus.VIEWED\n ? Occurrence.repeat\n : Occurrence.firstTime,\n business_unit: businessUnitMapper(testDetails.businessUnit),\n lims_document_id: testDetails.documentReferenceId,\n });\n }\n };\n\n const onPageLoadSuccess: onPageLoadSuccess = async (page) => {\n const containerWidth = refPdfContainer.current?.clientWidth;\n\n if (!containerWidth) {\n return;\n }\n\n setPdfWidth(containerWidth);\n };\n\n const addAttributesToCanvas: addAttributesToCanvas = (pageNumber) => {\n const canvasElement = document.querySelector(\n `.react-pdf__Page[data-page-number=\"${pageNumber}\"] canvas`\n );\n if (canvasElement) {\n canvasElement.setAttribute(\"role\", \"img\");\n canvasElement.setAttribute(\n \"aria-label\",\n `${\n pageAriaLabel || intl.formatMessage(messages.pdfDefaultAriaLabel)\n }. ${intl.formatMessage(messages.pdfPage)} ${pageNumber}`\n );\n canvasElement.setAttribute(\"tabindex\", \"0\");\n }\n };\n\n React.useEffect(() => {\n // We could use onRenderSuccess instead, but for some reason it makes changing of language to slow.\n const interval = setInterval(() => {\n const renderedCanvas = document.querySelectorAll(\n \".react-pdf__Page canvas\"\n ).length;\n\n if (renderedCanvas === numPages && numPages > 0) {\n for (let page = 1; page <= numPages; page++) {\n addAttributesToCanvas(page);\n }\n clearInterval(interval);\n }\n }, 300);\n\n return () => clearInterval(interval);\n }, [numPages, currentLanguage]);\n\n const onError = () => {\n setError(true);\n };\n\n return (\n \n \n {!isError && (\n
\n \n
\n )}\n
\n \n {!isError && (\n \n
\n {Array.from(new Array(numPages), (el, index) => (\n \n ))}\n \n
\n )}\n {isError && (\n \n
\n \n
\n
\n {intl.formatMessage(messages.pdfLoadError)}\n
\n
\n {intl.formatMessage(messages.pdfSubLoadError)}\n
\n
\n )}\n \n {!isError && (\n \n )}\n
\n \n \n );\n};\n\nexport default PdfView;\n","import React from \"react\";\nimport Svg from \"@natera/material/lib/svg\";\nimport { Document, Page, pdfjs } from \"react-pdf\";\nimport { Button } from \"@natera/form\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nimport { ConfigContext, ServiceContext } from \"@app/provider\";\nimport { TestDetailsContext } from \"@app/provider/testData\";\n\nimport CloudError from \"@assets/svg/icons/cloud-error.svg\";\nimport \"./pdf.scss\";\nimport { HEAP_EVENTS } from \"@app/provider/types\";\nimport { ScrollContext } from \"@natera/platform/lib/components/scrollbar\";\nimport { TestType } from \"@app/provider/testData/types\";\nimport useIsMobileDimension from \"../../hooks/useIsMobileDimension\";\n\n// https://github.com/wojtekmaj/react-pdf/issues/97\npdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;\n\nconst messages = defineMessages({\n pdfDownload: {\n id: \"pdfDownload\",\n defaultMessage: \"Download\",\n },\n pdfLoadError: {\n id: \"pdfLoadError\",\n defaultMessage: \"Sorry, we cannot retrieve results right now.\",\n },\n pdfSubLoadError: {\n id: \"pdfSubLoadError\",\n defaultMessage: \"Please try again later.\",\n },\n});\n\ntype onDocumentLoadSuccess = (pdf: pdfjs.PDFDocumentProxy) => Promise;\ntype onPageLoadSuccess = (pdf: pdfjs.PDFPageProxy) => Promise;\n\ntype Props = {\n file: string;\n fileName: string;\n downloadHeapEvent?: HEAP_EVENTS;\n};\n\ninterface LinkDimensions {\n originalTopPosition: number;\n originalLeftPosition: number;\n originalWidth: number;\n originalWidthLaptop?: number;\n originalLeftPositionMobile?: number;\n originalHeight: number;\n url: string;\n}\n\nconst StaticPdfViewer: React.FC = ({\n file,\n fileName,\n downloadHeapEvent,\n}) => {\n const intl = useIntl();\n const { fileService } = React.useContext(ServiceContext);\n const { getTestDetails } = React.useContext(TestDetailsContext);\n const { config } = React.useContext(ConfigContext);\n const [numPages, setNumPages] = React.useState(null);\n const [pdfWidth, setPdfWidth] = React.useState(null);\n const [pageWidth, setPageWidth] = React.useState(null);\n const isMobile = useIsMobileDimension();\n const refPdfContainer = React.useRef(null);\n\n const testDetails = getTestDetails();\n\n const onDownload = async () => {\n try {\n fileService.downloadStatic(file, fileName);\n } catch (error) {\n console.error(`Failed to download static file: ${file}, error: ${error}`);\n } finally {\n if (testDetails && downloadHeapEvent) {\n heap.track(downloadHeapEvent, {\n public_order_uid: testDetails.orderUidPublic,\n lims_clinic_id: testDetails.clinic?.limsId,\n });\n }\n }\n };\n\n const onDocumentLoadSuccess: onDocumentLoadSuccess = async ({\n numPages: nextNumPages,\n }) => {\n setNumPages(nextNumPages);\n };\n\n const onPageLoadSuccess: onPageLoadSuccess = async (page) => {\n const viewport = page.getViewport({ scale: 1 });\n const width = viewport.width;\n setPageWidth(width);\n\n const containerWidth = refPdfContainer.current?.clientWidth;\n\n if (!containerWidth) {\n return;\n }\n\n setPdfWidth(containerWidth);\n };\n const laptopDimension = 1280;\n const isLaptop = window.innerWidth >= laptopDimension;\n\n const linkMappings: Record = {\n ALTERA: [\n {\n originalTopPosition: 424,\n originalLeftPosition: 140,\n originalWidth: 368,\n originalWidthLaptop: 340,\n originalHeight: 57,\n url: config.links.ALTERA_EXPLAINER_VIDEO,\n },\n {\n originalTopPosition: 688,\n originalLeftPosition: 140,\n originalWidth: 547,\n originalWidthLaptop: 495,\n originalHeight: 57,\n url: config.links.SCHEDULE_A_GENETIC_INFORMATION_SESSION,\n },\n ],\n EMPOWER: [\n {\n originalTopPosition: 370,\n originalLeftPosition: 570,\n originalLeftPositionMobile: 650,\n originalWidth: 280,\n originalHeight: 57,\n url: config.links.product.EMPOWER_ONCOLOGY,\n },\n {\n originalTopPosition: 870,\n originalLeftPosition: 620,\n originalLeftPositionMobile: 700,\n originalWidth: 280,\n originalHeight: 57,\n url: config.links.MY_NATERA,\n },\n ],\n };\n\n const scalePosition = (\n originalPosition: number,\n pageWidth: number | null,\n pdfWidth: number | null\n ) => {\n if (pageWidth && pdfWidth) return (originalPosition / pageWidth) * pdfWidth;\n };\n\n const scaleLink = (\n link: LinkDimensions,\n pageWidth: number | null,\n pdfWidth: number | null\n ) => ({\n scaledTopPosition: scalePosition(\n link.originalTopPosition,\n pageWidth,\n pdfWidth\n ),\n scaledLeftPosition: scalePosition(\n link.originalLeftPosition,\n pageWidth,\n pdfWidth\n ),\n scaledLeftPositionMobile:\n link.originalLeftPositionMobile &&\n scalePosition(link.originalLeftPositionMobile, pageWidth, pdfWidth),\n scaledWidth: scalePosition(link.originalWidth, pageWidth, pdfWidth),\n scaledWidthLaptop:\n link.originalWidthLaptop &&\n scalePosition(link.originalWidthLaptop, pageWidth, pdfWidth),\n scaledHeight: scalePosition(link.originalHeight, pageWidth, pdfWidth),\n url: link.url,\n });\n\n const scaledLinks =\n testDetails &&\n linkMappings[testDetails?.testType]?.map((link) =>\n scaleLink(link, pageWidth, pdfWidth)\n );\n\n return (\n \n \n {file && (\n
\n \n
\n )}\n
\n \n {file && (\n \n
\n
\n {testDetails?.testType === TestType.ALTERA &&\n Array.from(new Array(numPages), (el, index) => (\n \n {index + 1 === 4 && pdfWidth && pageWidth && (\n <>\n {scaledLinks?.map((scaledLink, index) => (\n \n \n \n ))}\n >\n )}\n \n ))}\n {testDetails?.testType === TestType.EMPOWER &&\n Array.from(new Array(numPages), (el, index) => (\n \n {index + 1 === 7 && pdfWidth && pageWidth && (\n <>\n {scaledLinks?.map((scaledLink, index) => (\n \n \n \n ))}\n >\n )}\n \n ))}\n \n
\n
\n )}\n {!file && (\n \n
\n \n
\n
\n {intl.formatMessage(messages.pdfLoadError)}\n
\n
\n {intl.formatMessage(messages.pdfSubLoadError)}\n
\n
\n )}\n \n {file && (\n \n )}\n
\n \n \n );\n};\n\nexport default StaticPdfViewer;\n","export { default } from \"./personalInfo\";\n","import React, { FC } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { StepperContext } from \"@natera/stepper\";\nimport { LoadingContext } from \"@natera/platform/lib/components/context\";\nimport StepperHeaderProgress from \"@app/components/stepperHeaderProgress\";\nimport { OrderContext, ProfileContext, UserContext } from \"@app/provider\";\nimport PersonalInfoForm from \"@app/components/personalInfo/personalInfoForm\";\nimport { Notification } from \"@app/components\";\nimport { useDialog } from \"@natera/platform/lib/hooks\";\nimport PersonalInfoUpdateDialog from \"@app/components/personalInfo/personalInfoDialog\";\nimport { useNavigate } from \"react-router-dom\";\n\nimport { HEAP_EVENTS } from \"@app/provider/types\";\nimport { getTestNameForHeap } from \"@app/utils\";\n\nimport \"./personalInfo.scss\";\n\nconst messages = defineMessages({\n personalInfoTitle: {\n id: \"personalInfoTitle\",\n defaultMessage: \"Personal Information\",\n },\n personalInfoUpdateNote: {\n id: \"personalInfoUpdateNote\",\n defaultMessage: \"You can update your personal information {profileLink}\",\n },\n profileLink: {\n id: \"profileLink\",\n defaultMessage: \"here\",\n },\n});\n\nconst PersonalInfo: FC = () => {\n const intl = useIntl();\n const navigate = useNavigate();\n\n const personalInfoUpdateDialog = useDialog(PersonalInfoUpdateDialog);\n\n const { resolve } = React.useContext(StepperContext);\n const { uppUser, isLoading } = React.useContext(UserContext);\n const { profileData, profileDataIsLoading } = React.useContext(\n ProfileContext\n );\n const { orderData } = React.useContext(OrderContext);\n const orderUidPublic = orderData?.orderUidPublic;\n const limsId = orderData?.clinic?.limsId;\n\n const handleNextButtonClick = () => {\n resolve(profileData);\n };\n\n const handleBackButtonClick = () => {\n navigate(-1);\n };\n\n const handleDialog = () => {\n personalInfoUpdateDialog.open({\n onCloseDialog: () => personalInfoUpdateDialog.close(),\n });\n heap.track(HEAP_EVENTS.upp_simpleorder_editpersonalinfo, {\n tests_ordered: getTestNameForHeap(orderData),\n lims_clinic_id: limsId,\n public_order_uid: orderUidPublic,\n });\n };\n\n return (\n <>\n {personalInfoUpdateDialog.getDialog()}\n \n \n {intl.formatMessage(messages.personalInfoUpdateNote, {\n profileLink: (\n \n ),\n })}\n \n\n \n \n
\n
\n
\n {intl.formatMessage(messages.personalInfoTitle)}\n
\n \n
\n
\n
\n \n >\n );\n};\n\nexport default PersonalInfo;\n","import { routes } from \"@app/routing\";\nimport React, { FC } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { useNavigate } from \"react-router-dom\";\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { Button } from \"@natera/form\";\n\nconst messages = defineMessages({\n personalInfoDialogTitle: {\n id: \"personalInfoDialogTitle\",\n defaultMessage: \"After updating your personal information\",\n },\n personalInfoDialogContent: {\n id: \"personalInfoDialogContent\",\n defaultMessage:\n \"To complete your order after updating your personal information, please go back to the homepage and click the ‘complete order’ button on the testcard.\",\n },\n personalInfoDialogContinue: {\n id: \"personalInfoDialogContinue\",\n defaultMessage: \"Continue\",\n },\n personalInfoDialogBack: {\n id: \"personalInfoDialogBack\",\n defaultMessage: \"Back\",\n },\n});\n\nconst PersonalInfoUpdateDialog: FC<{ onCloseDialog: () => void }> = ({\n onCloseDialog,\n}) => {\n const intl = useIntl();\n const navigate = useNavigate();\n\n const handleContinue = () => {\n navigate(routes.profile, { replace: true });\n };\n\n return (\n \n );\n};\n\nexport default PersonalInfoUpdateDialog;\n","import { HeapPHIDecorator } from \"@app/components/analytics\";\nimport React, { FC } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Button, DisplayField, Form } from \"@natera/form\";\nimport { Profile } from \"@app/provider/profile\";\nimport { UppUser } from \"@app/service/user\";\nimport { FormField } from \"@app/components\";\n\nimport \"./personalInfo.scss\";\nimport { getFormattedDOB, getProfileFullName } from \"@app/utils\";\n\nconst messages = defineMessages({\n personalInfoFormFullName: {\n id: \"personalInfoFormFullName\",\n defaultMessage: \"Full Name\",\n },\n personalInfoFormDateOfBirth: {\n id: \"personalInfoFormDateOfBirth\",\n defaultMessage: \"Date of Birth\",\n },\n personalInfoFormMobileNumber: {\n id: \"personalInfoFormMobileNumber\",\n defaultMessage: \"Mobile Number\",\n },\n personalInfoFormEmail: {\n id: \"personalInfoFormEmail\",\n defaultMessage: \"Email\",\n },\n personalInfoNext: {\n id: \"personalInfoNext\",\n defaultMessage: \"Next\",\n },\n personalInfoBack: {\n id: \"personalInfoBack\",\n defaultMessage: \"Back\",\n },\n});\n\ninterface PersonalInfoProps {\n onSubmit: () => void;\n onBack: () => void;\n profileData?: Profile;\n uppUser?: UppUser;\n}\n\nconst PersonalInfoForm: FC = ({\n onSubmit,\n onBack,\n profileData,\n uppUser,\n}) => {\n const intl = useIntl();\n\n const dateOfBirth = getFormattedDOB(profileData?.dateOfBirth);\n\n return (\n \n );\n};\n\nexport default PersonalInfoForm;\n","import React, { FC } from \"react\";\nimport { Notification } from \"@app/components\";\nimport { useIntl, defineMessages } from \"react-intl\";\n\nexport const messages = defineMessages({\n poBoxValidationErrorTitle: {\n id: \"poBoxValidationErrorTitle\",\n defaultMessage: \"PO Boxes are not permitted.\",\n },\n poBoxValidationErrorKitContent: {\n id: \"poBoxValidationErrorKitContent\",\n defaultMessage:\n \"We cannot ship a kit to a PO box. Please select or enter a physical address.\",\n },\n poBoxValidationErrorBloodDrawContent: {\n id: \"poBoxValidationErrorBloodDrawContent\",\n defaultMessage:\n \"Please select or enter a physical address at which your blood can be drawn.\",\n },\n});\n\ntype POBoxErrorNotificationProps = {\n formType: AddressFormType;\n};\n\nexport enum AddressFormType {\n KIT,\n MOBILE_BLOOD_DRAW,\n}\n\nexport const POBoxErrorNotification: FC = ({\n formType,\n}) => {\n const intl = useIntl();\n\n const errorMessage =\n formType === AddressFormType.KIT\n ? messages.poBoxValidationErrorKitContent\n : messages.poBoxValidationErrorBloodDrawContent;\n\n return (\n \n \n {intl.formatMessage(errorMessage)}
\n \n \n );\n};\n","export { default } from \"./progress\";\n","import React, { FC } from \"react\";\nimport classNames from \"classnames\";\n\nimport \"./progress.scss\";\n\ninterface ProgressProps {\n value: number;\n className?: string;\n}\n\nconst Progress: FC = ({ value, className }) => {\n return (\n \n );\n};\n\nexport default Progress;\n","export { default as ProvideInsuranceForm } from \"./provideInsuranceForm\";\n","import React from \"react\";\nimport { Grid, GridCell, GridRow } from \"@natera/material/lib/layout\";\nimport { Button, Form, FormField, Textfield } from \"@natera/form\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { useErrorController } from \"@natera/platform/lib/hooks\";\n\nconst messages = defineMessages({\n provideInsuranceFormMemberId: {\n id: \"provideInsuranceFormMemberId\",\n defaultMessage: \"Member ID\",\n },\n provideInsuranceFormMemberIdPlaceholder: {\n id: \"provideInsuranceFormMemberIdPlaceholder\",\n defaultMessage: \"Enter Member ID\",\n },\n provideInsuranceFormReEnterMemberId: {\n id: \"provideInsuranceFormReEnterMemberId\",\n defaultMessage: \"Re-enter Member ID\",\n },\n provideInsuranceFormReEnterMemberIdPlaceholder: {\n id: \"provideInsuranceFormReEnterMemberIdPlaceholder\",\n defaultMessage: \"Enter Member ID\",\n },\n provideInsuranceFormMandatory: {\n id: \"provideInsuranceFormMandatory\",\n defaultMessage: \"This information is required.\",\n },\n provideInsuranceFormMustMatch: {\n id: \"provideInsuranceFormMustMatch\",\n defaultMessage: \"Member IDs must match\",\n },\n provideInsuranceFormInvalid: {\n id: \"provideInsuranceFormInvalid\",\n defaultMessage: \"Please enter a valid Member ID\",\n },\n provideInsuranceFormButtonNext: {\n id: \"provideInsuranceFormButtonNext\",\n defaultMessage: \"Next\",\n },\n provideInsuranceFormButtonBack: {\n id: \"provideInsuranceFormButtonBack\",\n defaultMessage: \"Back\",\n },\n});\n\ntype Props = {\n defaultValue?: string;\n onSubmit: (memberId: string) => void;\n goBack: () => void;\n};\n\nconst memberId = \"memberId\";\nconst reMemberId = \"reMemberId\";\n\nconst ProvideInsuranceForm: React.FC = ({\n defaultValue,\n onSubmit,\n goBack,\n}) => {\n const intl = useIntl();\n\n const errorController = useErrorController();\n\n const handleSubmit: React.FormEventHandler = (event) => {\n event.preventDefault();\n errorController.clearErrors();\n\n const formData = new FormData(event.currentTarget);\n\n const memberIdValue = formData.get(memberId)?.toString();\n const reMemberIdValue = formData.get(reMemberId)?.toString();\n\n if (!memberIdValue) {\n errorController.setValidationError(\n memberId,\n intl.formatMessage(messages.provideInsuranceFormMandatory)\n );\n\n return;\n }\n\n if (memberIdValue || reMemberIdValue) {\n const isInvalidMemberId =\n memberIdValue && memberIdValue !== memberIdValue.trim();\n\n if (isInvalidMemberId) {\n errorController.setValidationError(\n memberId,\n intl.formatMessage(messages.provideInsuranceFormInvalid)\n );\n }\n\n const isInvalidReMemberId =\n reMemberIdValue && reMemberIdValue !== reMemberIdValue.trim();\n\n if (isInvalidReMemberId) {\n errorController.setValidationError(\n reMemberId,\n intl.formatMessage(messages.provideInsuranceFormInvalid)\n );\n }\n\n if (isInvalidMemberId || isInvalidReMemberId) return;\n }\n\n if (memberIdValue !== reMemberIdValue) {\n errorController.setValidationError(\n memberId,\n intl.formatMessage(messages.provideInsuranceFormMustMatch)\n );\n\n errorController.setValidationError(\n reMemberId,\n intl.formatMessage(messages.provideInsuranceFormMustMatch)\n );\n\n return;\n }\n\n onSubmit(memberIdValue);\n };\n\n return (\n \n );\n};\n\nexport default ProvideInsuranceForm;\n","export { default } from \"./providerType\";\n","import React, { FC } from \"react\";\nimport { IDP_TYPE } from \"@app/service/user\";\nimport Svg from \"@natera/material/lib/svg\";\nimport LetterIcon from \"@assets/svg/icons/letter.svg\";\nimport AppleLogo from \"@assets/svg/apple-logo.svg\";\nimport GoogleLogo from \"@assets/svg/google-logo.svg\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nconst messages = defineMessages({\n providerTypeEmailProvider: {\n id: \"providerTypeEmailProvider\",\n defaultMessage: \"Email\",\n },\n providerTypeAppleProvider: {\n id: \"providerTypeAppleProvider\",\n defaultMessage: \"Apple\",\n },\n providerTypeGoogleProvider: {\n id: \"providerTypeGoogleProvider\",\n defaultMessage: \"Google\",\n },\n});\n\ntype Props = {\n idpType: IDP_TYPE | undefined;\n showEmailIcon?: boolean;\n};\n\nconst ProviderType: FC = ({ idpType, showEmailIcon }) => {\n const intl = useIntl();\n\n return (\n <>\n {idpType === IDP_TYPE.EMAIL && (\n \n {showEmailIcon && (\n \n )}\n {intl.formatMessage(messages.providerTypeEmailProvider)}\n
\n )}\n\n {idpType === IDP_TYPE.APPLE && (\n \n \n {intl.formatMessage(messages.providerTypeAppleProvider)}\n
\n )}\n\n {idpType === IDP_TYPE.GOOGLE && (\n \n \n {intl.formatMessage(messages.providerTypeGoogleProvider)}\n
\n )}\n >\n );\n};\n\nexport default ProviderType;\n","import React, { FC, useContext, useState } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport useIsMobileDimension from \"../../hooks/useIsMobileDimension\";\nimport RecurringTestingImage from \"@assets/images/recurringTestingSGN.png\";\nimport { VideoPlayer } from \"@app/components\";\nimport { HEAP_EVENTS } from \"@app/provider/types\";\nimport { ConfigContext, NotificationContext, UserContext } from \"@app/provider\";\nimport Dialog from \"@natera/material/lib/dialog\";\nimport R from \"ramda\";\n\nimport \"./renewalInfoDialog.scss\";\n\nconst messages = defineMessages({\n renewalPageTitle: {\n id: \"renewalPageTitle\",\n defaultMessage: \"Renew Your Test\",\n },\n renewalPageHeader: {\n id: \"renewalPageHeader\",\n defaultMessage: \"Knowing earlier matters\",\n },\n renewalPageHeaderInfo: {\n id: \"renewalPageHeaderInfo\",\n defaultMessage:\n \"You have been receiving recurring Signatera blood tests and your order is up for renewal. Your doctor will recommend when and how often you will have your blood drawn for a Signatera test, but it may be time to discuss renewing your recurring order.\",\n },\n renewalPageEnsuring: {\n id: \"renewalPageEnsuring\",\n defaultMessage: \"How do I ensure I am re-enrolled?\",\n },\n renewalPageEnsuringInfo: {\n id: \"renewalPageEnsuringInfo\",\n defaultMessage:\n \"To continue receiving Signatera tests on an ongoing basis, {boldContent}. Once your doctor has renewed your recurring Signatera order, Natera is available to work with you to schedule mobile phlebotomy services and assist with scheduling your blood draws at your home or work. Your Natera team is standing by to assist with everything from scheduling blood draws and genetic counselor information sessions to financial assistance.\",\n },\n renewalPageEnsuringInfoBoldContent: {\n id: \"renewalPageEnsuringInfoBoldContent\",\n defaultMessage: \"talk with your doctor about renewing your enrollment\",\n },\n renewalPageQuestions: {\n id: \"renewalPageQuestions\",\n defaultMessage: \"Any questions?\",\n },\n renewalPageAssistance: {\n id: \"renewalPageAssistance\",\n defaultMessage:\n \"For more assistance with renewing your recurring orders, contact us at 650.446.4657 or at {link} to speak with our Patient Coordinator team.\",\n },\n renewalPageAssistanceLink: {\n id: \"renewalPageAssistanceLink\",\n defaultMessage: \"oncologypc@natera.com\",\n },\n renewalPageRecurringTesting: {\n id: \"renewalPageRecurringTesting\",\n defaultMessage: \"Why is recurring testing important?\",\n },\n renewalPageRecurringTestingImage: {\n id: \"renewalPageRecurringTestingImage\",\n defaultMessage: \"Recurring testing image\",\n },\n renewalPageRecurringTestingInfo: {\n id: \"renewalPageRecurringTestingInfo\",\n defaultMessage:\n \"Using Signatera, we can measure changes in the amount of circulating tumor DNA (ctDNA) in your blood over time. You and your doctor can use this information to understand if there may be cancer remaining after treatment, how your cancer is responding to therapy, or if your cancer may be recurring. Receiving this information throughout your treatment journey ensures you and your doctor have real time guidance about how to optimize your treatment plan.\",\n },\n renewalPageTestimonials: {\n id: \"renewalPageTestimonials\",\n defaultMessage: \"Testimonials\",\n },\n renewalPageTestimonialsFirstVideoTitle: {\n id: \"renewalPageTestimonialsFirstVideoTitle\",\n defaultMessage: \"Keith’s Story\",\n },\n renewalPageTestimonialsFirstVideoText: {\n id: \"renewalPageTestimonialsFirstVideoText\",\n defaultMessage:\n \"Listen in how one CRC patient and his physician used Signatera as a part of his treatment strategy to help identify an early signal that cancer may be lurking.\",\n },\n renewalPageTestimonialsSecondVideoTitle: {\n id: \"renewalPageTestimonialsSecondVideoTitle\",\n defaultMessage: \"Angela’s Story\",\n },\n renewalPageTestimonialsSecondVideoText: {\n id: \"renewalPageTestimonialsSecondVideoText\",\n defaultMessage:\n \"Monitoring ctDNA in Breast Cancer: Moving on with life with Signatera.\",\n },\n renewalPageResourses: {\n id: \"renewalPageResourses\",\n defaultMessage: \"Resourses\",\n },\n renewalPageResoursesCancerSociety: {\n id: \"renewalPageResoursesCancerSociety\",\n defaultMessage:\n \"For more information about your diagnosis, check out the {americanCancerSociety} at Cancer.org\",\n },\n renewalPageAmericanCancerSociety: {\n id: \"renewalPageAmericanCancerSociety\",\n defaultMessage: \"American Cancer Society\",\n },\n renewalPageResoursesLocalSupport: {\n id: \"renewalPageResoursesLocalSupport\",\n defaultMessage:\n \"For local support, ask your clinic for a list of support groups that may meet in person or virtually \",\n },\n renewalPageResoursesFindOthers: {\n id: \"renewalPageResoursesFindOthers\",\n defaultMessage:\n \"To find others going through your specific cancer, you can search online for advocacy organizations or call Natera for recommendations\",\n },\n renewalPageResoursesNatera: {\n id: \"renewalPageResoursesNatera\",\n defaultMessage: \"For more information about Signatera, visit {nateraLink}.\",\n },\n renewalPageResoursesNateraLink: {\n id: \"renewalPageResoursesNateraLink\",\n defaultMessage: \"natera.com/signaterapatients\",\n },\n renewalPageFirstVideoAltText: {\n id: \"renewalPageFirstVideoAltText\",\n defaultMessage: \"Keith’s testimonial video\",\n },\n renewalPageSecondVideoAltText: {\n id: \"renewalPageSecondVideoAltText\",\n defaultMessage: \"Angela’s testimonial video\",\n },\n});\n\ninterface RenewalInfoDialogProps {\n onCloseDialog: () => void;\n limsId?: number;\n orderUidPublic?: string;\n}\n\nconst RenewalInfoDialog: FC = ({\n onCloseDialog,\n limsId,\n orderUidPublic,\n}) => {\n const intl = useIntl();\n const isMobile = useIsMobileDimension();\n const { uppUser } = useContext(UserContext);\n const { config } = React.useContext(ConfigContext);\n const { clear } = useContext(NotificationContext);\n\n const [isClosing, setIsClosing] = useState(false);\n const [firstVideoUrl, setFirstVideoUrl] = useState(\"\");\n const [secondVideoUrl, setSecondVideoUrl] = useState(\"\");\n\n const TESTIMONIALS_VIDEO = {\n firstStory: \"https://natera.wistia.com/medias/suevsq3plh\",\n secondStory: \"https://natera.wistia.com/medias/n2r97nr1v7\",\n };\n\n React.useEffect(() => {\n const loadVideoUrls = async () => {\n const firstUrl = R.last(TESTIMONIALS_VIDEO.firstStory.split(\"/\")) || \"\";\n const secondUrl = R.last(TESTIMONIALS_VIDEO.secondStory.split(\"/\")) || \"\";\n if (firstUrl) {\n setFirstVideoUrl(firstUrl);\n }\n if (secondUrl) {\n setSecondVideoUrl(secondUrl);\n }\n };\n loadVideoUrls();\n }, []);\n\n React.useEffect(() => {\n if (isMobile) {\n const element = document.querySelector(\".renewal-dialog.mobile\");\n element && element.classList.add(\"animate-up\");\n }\n }, [isMobile]);\n\n React.useEffect(() => {\n heap.track(HEAP_EVENTS.upp_viewrenewal_page, {\n identity: uppUser?.patientUID,\n lims_clinic_id: limsId,\n public_order_uid: orderUidPublic,\n });\n }, []);\n\n const handleClose = () => {\n setIsClosing(true);\n setTimeout(() => {\n clear();\n onCloseDialog();\n }, 600);\n };\n\n return (\n \n );\n};\n\nexport default RenewalInfoDialog;\n","import React, { FC, useContext, useState } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport \"./renewalPopUp.scss\";\nimport useIsMobileDimension from \"../../hooks/useIsMobileDimension\";\nimport { HEAP_EVENTS } from \"@app/provider/types\";\nimport { NotificationContext, UserContext } from \"@app/provider\";\nimport Dialog from \"@natera/material/lib/dialog\";\nimport Button from \"@natera/material/lib/button\";\nimport ResponceImage from \"@assets/images/renewalPatientResponce.png\";\n\nconst messages = defineMessages({\n renewalPopUpTitle: {\n id: \"renewalPopUpTitle\",\n defaultMessage:\n \"Are you interested in discussing renewal with your healthcare provider?\",\n },\n renewalPopUpAgreeButton: {\n id: \"renewalPopUpAgreeButton\",\n defaultMessage: \"Yes, please contact my healthcare provider on my behalf.\",\n },\n renewalPopUpDisagreeButton: {\n id: \"renewalPopUpDisagreeButton\",\n defaultMessage:\n \"No, I’m not interested in discussing renewal at this time.\",\n },\n renewalPopUpGratitude: {\n id: \"renewalPopUpGratitude\",\n defaultMessage: \"Thanks for your response\",\n },\n});\n\ninterface RenewalPopUpProps {\n onCloseDialog: () => void;\n limsId?: number;\n orderUidPublic?: string;\n}\n\nconst RenewalPopUp: FC = ({\n onCloseDialog,\n limsId,\n orderUidPublic,\n}) => {\n const intl = useIntl();\n const isMobile = useIsMobileDimension();\n const { uppUser } = useContext(UserContext);\n const { clear } = useContext(NotificationContext);\n\n const [activeDialog, setActiveDialog] = useState<\"first\" | \"second\" | null>(\n \"first\"\n );\n const [closingDialog, setClosingDialog] = useState<\"first\" | \"second\" | null>(\n null\n );\n const animationDuration = 600;\n\n React.useEffect(() => {\n if (isMobile && activeDialog) {\n const element = document.querySelector(`.popUp-dialog.mobile`);\n if (element) {\n element.classList.add(\"animate-up\");\n }\n }\n }, [isMobile, activeDialog]);\n\n const handleCloseFirstDialog = () => {\n setClosingDialog(\"first\");\n setTimeout(() => {\n setActiveDialog(\"second\");\n setClosingDialog(null);\n }, animationDuration);\n };\n\n const handleCloseSecondDialog = () => {\n setClosingDialog(\"second\");\n setTimeout(() => {\n clear();\n onCloseDialog();\n }, animationDuration);\n };\n\n const handleAgree = () => {\n heap.track(HEAP_EVENTS.upp_renewal_signatera_yes_interested, {\n identity: uppUser?.patientUID,\n lims_clinic_id: limsId,\n public_order_uid: orderUidPublic,\n });\n handleCloseFirstDialog();\n };\n\n const handleDisagree = () => {\n heap.track(HEAP_EVENTS.upp_renewal_signatera_not_interested, {\n identity: uppUser?.patientUID,\n lims_clinic_id: limsId,\n public_order_uid: orderUidPublic,\n });\n handleCloseFirstDialog();\n };\n\n return (\n <>\n {activeDialog === \"first\" && (\n \n )}\n\n {activeDialog === \"second\" && (\n \n )}\n >\n );\n};\n\nexport default RenewalPopUp;\n","import React, { FC } from \"react\";\n\nimport useScreenSize from \"@app/hooks/useScreenSize\";\n\ninterface ResponsiveImageProps {\n mobileSrc: string;\n desktopSrc: string;\n alt: string;\n className?: string;\n}\n\nconst minDesktopWidth = 768;\n\nconst ResponsiveImage: FC = ({\n alt,\n className,\n mobileSrc,\n desktopSrc,\n}) => {\n const { screenWidth } = useScreenSize();\n\n const imageResourceLink = (mobileSrc: string, desktopSrc: string): string => {\n if (screenWidth < minDesktopWidth) {\n return mobileSrc;\n }\n return desktopSrc;\n };\n\n return (\n
\n );\n};\n\nexport default ResponsiveImage;\n","import React, { FC } from \"react\";\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Button } from \"@natera/form\";\nimport { useLocation, useNavigate } from \"react-router-dom\";\nimport { routes } from \"@app/routing\";\nimport { ConfigContext } from \"@app/provider\";\nimport { HEAP_EVENTS, HeapEventLocation } from \"@app/provider/types\";\nimport { LinkHeap } from \"@app/components\";\n\nimport \"./apologiesModal.scss\";\n\nconst messages = defineMessages({\n apologiesModalMessageTitle: {\n id: \"apologiesModalMessageTitle\",\n defaultMessage: \"We're sorry.\",\n },\n apologiesModalMessageModify: {\n id: \"apologiesModalMessageModify\",\n defaultMessage:\n \"We are unable to modify your appointment request at this time.\",\n },\n apologiesModalMessageCreate: {\n id: \"apologiesModalMessageCreate\",\n defaultMessage:\n \"We are unable to submit your appointment request at this time.\",\n },\n apologiesModalMessageTextContact: {\n id: \"apologiesModalMessageTextContact\",\n defaultMessage: \"Any questions? {contactUs}\",\n },\n apologiesModalMessageTextContactUs: {\n id: \"apologiesModalMessageTextContactUs\",\n defaultMessage: \"Contact us\",\n },\n apologiesModalMessageBackToHome: {\n id: \"apologiesModalMessageBackToHome\",\n defaultMessage: \"Home\",\n },\n apologiesModalMessageBack: {\n id: \"apologiesModalMessageBack\",\n defaultMessage: \"Back\",\n },\n});\n\ninterface ApologiesModalLocationState {\n prevPage: string;\n}\n\ntype Props = {\n isModify: boolean;\n onClose: () => void;\n isGuest?: boolean;\n};\n\nconst ApologiesModal: FC = ({ isModify, onClose, isGuest }) => {\n const intl = useIntl();\n const { config } = React.useContext(ConfigContext);\n\n const navigate = useNavigate();\n const location = useLocation();\n\n const state = location.state as ApologiesModalLocationState | undefined;\n const isBackToHome = !isModify || (isModify && !state?.prevPage);\n\n const handleClick = () => {\n if (isGuest) {\n onClose();\n } else {\n window.history.length > 1 ? navigate(-1) : navigate(routes.home);\n }\n };\n\n return (\n \n );\n};\n\nexport default ApologiesModal;\n","export { default } from \"./apologiesModal\";\n","import React, { FC } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { Button } from \"@natera/form\";\nimport { useNavigate } from \"react-router-dom\";\nimport { routes } from \"@app/routing\";\nimport \"./clinicRequestDialog.scss\";\n\nconst messages = defineMessages({\n clinicRequestDialogTitle: {\n id: \"clinicRequestDialogTitle\",\n defaultMessage: \"Contact your clinic\",\n },\n clinicRequestDialogDescription1: {\n id: \"clinicRequestDialogDescription1\",\n defaultMessage:\n \"Reach out to your clinic directly to see if they offer on-site blood draw services.\",\n },\n clinicRequestDialogDescription2: {\n id: \"clinicRequestDialogDescription2\",\n defaultMessage:\n \"If they do not offer blood draw services, come back to the patient portal to find a lab nearby or request mobile phlebotomy service.\",\n },\n clinicRequestDialogClinicRequestDone: {\n id: \"clinicRequestDialogClinicRequestDone\",\n defaultMessage: \"Done\",\n },\n clinicRequestDialogClinicRequestBack: {\n id: \"clinicRequestDialogClinicRequestBack\",\n defaultMessage: \"Back\",\n },\n});\n\ninterface ClinicRequestDialogProps {\n goBack: () => void;\n isGuest: boolean;\n}\n\nconst ClinicRequestDialog: FC = ({\n goBack,\n isGuest,\n}) => {\n const intl = useIntl();\n const navigate = useNavigate();\n\n const handleDone = () => {\n isGuest ? goBack() : navigate(routes.home);\n };\n\n return (\n \n
\n
\n );\n};\n\nexport default ClinicRequestDialog;\n","export { default } from \"./clinicRequestDialog\";\n","import React, { FC, useMemo } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { Button } from \"@natera/form\";\nimport \"./comboOrderModal.scss\";\n\nconst messages = defineMessages({\n comboOrderModalMessageTitle: {\n id: \"comboOrderModalMessageTitle\",\n defaultMessage: \"Combo order\",\n },\n comboOrderModalMessageItem1: {\n id: \"comboOrderModalMessageItem1\",\n defaultMessage: \"Your order includes multiple tests:\\n\",\n },\n comboOrderModalMessageItem2: {\n id: \"comboOrderModalMessageItem2\",\n defaultMessage:\n \"You only need to schedule one appointment for all tests in your order.\",\n },\n\n comboOrderModalMessageContinue: {\n id: \"comboOrderModalMessageContinue\",\n defaultMessage: \"Continue\",\n },\n comboOrderModalMessageItemsAnd: {\n id: \"comboOrderModalMessageItemsAnd\",\n defaultMessage: \" and \",\n },\n});\n\ntype Props = {\n orderTypes: string[];\n onClose: () => void;\n};\n\nconst ComboOrderModal: FC = ({ orderTypes, onClose }) => {\n const intl = useIntl();\n\n const orderTypesList = useMemo(\n () =>\n orderTypes.slice(0, -1).join(\", \") +\n ` ${intl.formatMessage(messages.comboOrderModalMessageItemsAnd)} ` +\n orderTypes.slice(-1),\n [orderTypes]\n );\n\n return (\n \n );\n};\n\nexport default ComboOrderModal;\n","export { default } from \"./comboOrderModal\";\n","export { default as ApologiesModal } from \"./apologiesModal\";\nexport { default as SuccessModal } from \"./successModal\";\nexport { default as ComboOrderModal } from \"./comboOrderModal\";\nexport { default as ClinicRequestModal } from \"./clinicModal\";\n","import React, { FC } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { Button } from \"@natera/form\";\nimport \"./skipKitShippingDialog.scss\";\n\nconst messages = defineMessages({\n skipKitShippingDialogTitle: {\n id: \"skipKitShippingDialogTitle\",\n defaultMessage: \"Contact your clinic\",\n },\n skipKitShippingDialogDescription: {\n id: \"skipKitShippingDialogDescription\",\n defaultMessage:\n \"Your blood draw specialist will have a kit ready for you at the time of your draw. We will not ship you a kit due to your location.\",\n },\n skipKitShippingDialogContinue: {\n id: \"skipKitShippingDialogskipKitShippingDone\",\n defaultMessage: \"Continue\",\n },\n});\n\ninterface SkipKitShippingDialogProps {\n onClick: () => void;\n onClose: () => void;\n}\n\nconst SkipKitShippingDialog: FC = ({\n onClick,\n onClose,\n}) => {\n const intl = useIntl();\n\n const handleDone = () => {\n onClick();\n };\n\n return (\n \n
\n
\n );\n};\n\nexport default SkipKitShippingDialog;\n","export { default } from \"./successModal\";\n","import React, { FC } from \"react\";\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { Button } from \"@natera/form\";\n\nimport { defineMessages, useIntl } from \"react-intl\";\n\nconst messages = defineMessages({\n successModalCreateSuccessMessage: {\n id: \"successModalCreateSuccessMessage\",\n defaultMessage: \"Your request has been submitted\",\n },\n successModalModifySuccessMessage: {\n id: \"successModalModifySuccessMessage\",\n defaultMessage: \"Your request has been updated\",\n },\n successModalSuccessMessageSubmit: {\n id: \"successModalSuccessMessageSubmit\",\n defaultMessage: \"See Details\",\n },\n});\n\nexport interface SuccessModalProps {\n isAfterModify: boolean;\n handleCloseDialog: () => void;\n}\n\nconst SuccessModal: FC = ({\n isAfterModify,\n handleCloseDialog,\n}) => {\n const intl = useIntl();\n\n const handleClick = () => handleCloseDialog();\n\n return (\n \n );\n};\n\nexport default SuccessModal;\n","import React, { FC, useContext } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nimport { Button, Form } from \"@natera/form\";\nimport { DrawRequestContext, OrderRenewalContext } from \"@app/provider\";\nimport { AppointmentAddress } from \"@app/components/appointmentAddress\";\nimport { AppointmentTimeslots } from \"@app/components/appointmentTimeslots\";\n\nimport { StepperContent } from \"@app/components/ui/layout\";\nimport { RenewalBanner } from \"@app/components/banners\";\n\nimport \"./appointmentTimeConfirmationStep.scss\";\n\nconst messages = defineMessages({\n appointmentTimeConfirmationTitle: {\n id: \"appointmentTimeConfirmationTitle\",\n defaultMessage: \"Mobile Blood Draw\",\n },\n appointmentTimeConfirmationDescriptionContent: {\n id: \"appointmentTimeConfirmationDescriptionContent\",\n defaultMessage:\n \"You will get a call from the scheduling team to confirm your appointment 24-48 hours prior to your first selected time slot.\",\n },\n appointmentTimeConfirmationModifyAppointment: {\n id: \"appointmentTimeConfirmationModifyAppointment\",\n defaultMessage: \"Change Appointment\",\n },\n appointmentTimeConfirmationBackHome: {\n id: \"appointmentTimeConfirmationBackHome\",\n defaultMessage: \"Home\",\n },\n});\n\ninterface Props {\n handleModifyAppointment: () => void;\n onBack?: () => void;\n isPublicRequest?: boolean;\n}\n\nconst AppointmentTimeConfirmationStep: FC = ({\n handleModifyAppointment,\n onBack,\n isPublicRequest,\n}) => {\n const intl = useIntl();\n const { drawRequestData: drawRequest, selectedTimeZone } = useContext(\n DrawRequestContext\n );\n const { renewalInfo, openRenewalDialog } = React.useContext(\n OrderRenewalContext\n );\n const handleSubmit: React.FormEventHandler = (event) => {\n event.preventDefault();\n handleModifyAppointment();\n };\n\n const renderRenewalBanner = () =>\n renewalInfo?.hasRenewal &&\n renewalInfo?.isLastSignateraOrder && (\n \n );\n\n return (\n \n );\n};\nexport default AppointmentTimeConfirmationStep;\n","export { default as AppointmentTimeConfirmation } from \"./appointmentTimeConfirmationStep\";\n","export { default } from \"./modifyAppointment\";\n","import React, { FC, useContext } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nimport { DrawRequestContext, IntlContext, ProfileContext } from \"@app/provider\";\nimport { DrawRequestTimeslots } from \"@app/provider/drawRequest\";\nimport TimeslotsForm, {\n TimeslotsFormData,\n} from \"@app/components/forms/timeslotsForm/timeslotsForm\";\n\nimport \"./modifyAppointment.scss\";\nimport StepperHeaderProgress from \"@app/components/stepperHeaderProgress/stepperHeaderProgress\";\nimport { StepperContent } from \"@app/components/ui/layout\";\nimport { TestType } from \"@app/provider/testData/types\";\n\nconst messages = defineMessages({\n mobilePhlebotomyTimeslotsTitle: {\n id: \"mobilePhlebotomyTimeslotsTitle\",\n defaultMessage: \"Mobile Blood Draw\",\n },\n mobilePhlebotomyTimeslotsDescriptionTitle: {\n id: \"mobilePhlebotomyTimeslotsDescriptionTitle\",\n defaultMessage: \"When are some good times for your blood draw?\",\n },\n mobilePhlebotomyTimeslotsDescription: {\n id: \"mobilePhlebotomyTimeslotsDescription\",\n defaultMessage:\n \"Please select three time slots across three different dates to ensure that we can match you with an appointment.\",\n },\n mobilePhlebotomySubmitAppointmentRequest: {\n id: \"mobilePhlebotomySubmitAppointmentRequest\",\n defaultMessage: \"Submit\",\n },\n});\n\nexport interface ModifyAppointmentProps {\n handleBackToTimeConfirmation: () => void;\n testType?: TestType;\n orderUidPublic?: string;\n testUid?: string;\n token?: string;\n}\n\nconst ModifyAppointment: FC = ({\n handleBackToTimeConfirmation,\n ...props\n}) => {\n const intl = useIntl();\n const {\n isLoading,\n updateDrawRequest,\n openUpdateDrawErrorDialog,\n } = useContext(DrawRequestContext);\n\n const { updatePatientLanguage } = useContext(ProfileContext);\n const { currentLanguage } = useContext(IntlContext);\n\n const handleModifyTimeslots = async (data: TimeslotsFormData) => {\n try {\n await updatePatientLanguage(currentLanguage, props.token);\n await updateDrawRequest({\n timeZone: data.timeZone,\n timeSlots: data.timeSlots as DrawRequestTimeslots,\n ...props,\n });\n handleBackToTimeConfirmation();\n } catch {\n openUpdateDrawErrorDialog();\n handleBackToTimeConfirmation();\n }\n };\n\n return (\n \n <>\n \n \n >\n \n );\n};\n\nexport default ModifyAppointment;\n","import React from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Notification } from \"@app/components\";\n\nconst messages = defineMessages({\n mobilePhlebotomyNotificationTitle: {\n id: \"mobilePhlebotomyNotificationTitle\",\n defaultMessage: \"Please select three date/time slots\",\n },\n mobilePhlebotomyNotificationText: {\n id: \"mobilePhlebotomyNotificationText\",\n defaultMessage:\n \"We need you to select three different date/times to continue with scheduling.\",\n },\n});\n\nconst TimeslotsWarning: React.FC = () => {\n const intl = useIntl();\n\n return (\n \n \n {intl.formatMessage(messages.mobilePhlebotomyNotificationText)}\n \n \n );\n};\n\nexport default TimeslotsWarning;\n","export * from \"./labs\";\nexport * from \"./mobilePhlebotomySteps\";\nexport { SampleDrawKitStep } from \"./kit\";\nexport { SampleDrawPreferenceStep } from \"./sampleDrawPreference\";\n","export { default as SampleDrawKitStep } from \"./sampleDrawKitStep\";\n","import React from \"react\";\n\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { Button } from \"@natera/form\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { ConfigContext } from \"@app/provider\";\nimport { HEAP_EVENTS } from \"@app/provider/types\";\nimport { LinkHeap } from \"@app/components\";\nimport \"./kitDialog.scss\";\n\nconst messages = defineMessages({\n kitErrorDialogHeader: {\n id: \"kitErrorDialogHeader\",\n defaultMessage: \"Kit cannot be ordered at this time\",\n },\n kitErrorDialogDescription: {\n id: \"kitErrorDialogDescription\",\n defaultMessage:\n \"We’re unable to complete your kit order. Please {contactUs} to request a kit.\",\n },\n kitErrorDialogDescriptionContactUs: {\n id: \"kitErrorDialogDescriptionContactUs\",\n defaultMessage: \"contact us\",\n },\n kitErrorDialogButtonError: {\n id: \"kitErrorDialogButtonError\",\n defaultMessage: \"Done\",\n },\n});\n\ntype Props = {\n onClose: () => void;\n};\n\nconst KitErrorDialog: React.FC = ({ onClose }) => {\n const intl = useIntl();\n const { config } = React.useContext(ConfigContext);\n\n return (\n \n );\n};\n\nexport default KitErrorDialog;\n","import React from \"react\";\n\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { Button } from \"@natera/form\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nimport \"./kitDialog.scss\";\n\nconst messages = defineMessages({\n kitSuccessDialogHeader: {\n id: \"kitSuccessDialogHeader\",\n defaultMessage: \"Kit is on its way!\",\n },\n kitSuccessDialogDescription: {\n id: \"kitSuccessDialogDescription\",\n defaultMessage:\n \"We’ll be sending the kit to the address you provided. Now, let’s schedule your sample draw.\",\n },\n kitSuccessDialogButtonContinue: {\n id: \"kitSuccessDialogButtonContinue\",\n defaultMessage: \"Continue\",\n },\n});\n\ntype Props = {\n onClose: () => void;\n};\n\nconst KitSuccessDialog: React.FC = ({ onClose }) => {\n const intl = useIntl();\n\n return (\n \n );\n};\n\nexport default KitSuccessDialog;\n","import { AddressForm } from \"@app/components/forms\";\nimport { Address } from \"@app/provider\";\nimport { Button } from \"@natera/form\";\nimport React from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nexport const messages = defineMessages({\n sampleDrawKitAddAddressNextButtonText: {\n id: \"sampleDrawKitAddAddressNextButtonText\",\n defaultMessage: \"Save\",\n },\n sampleDrawKitAddAddressBackButtonText: {\n id: \"sampleDrawKitAddAddressBackButtonText\",\n defaultMessage: \"Back\",\n },\n});\n\ntype Props = {\n onSubmit: (address: Partial) => void;\n onBack?: () => void;\n};\n\nconst SampleDrawKitAddAddress: React.FC = ({ onSubmit, onBack }) => {\n const intl = useIntl();\n\n return (\n \n \n {onBack && (\n \n )}\n >\n }\n />\n );\n};\n\nexport default SampleDrawKitAddAddress;\n","import React from \"react\";\nimport { SelectAddressForm } from \"@app/components/forms\";\nimport { Address } from \"@app/provider\";\nimport { Button } from \"@natera/form\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nexport const messages = defineMessages({\n sampleDrawKitSelectAddressNextButtonText: {\n id: \"sampleDrawKitSelectAddressNextButtonText\",\n defaultMessage: \"Next\",\n },\n sampleDrawKitSelectAddressBackButtonText: {\n id: \"sampleDrawKitSelectAddressBackButtonText\",\n defaultMessage: \"Back\",\n },\n sampleDrawKitSelectAddressAddNewAddressButton: {\n id: \"sampleDrawKitSelectAddressAddNewAddressButton\",\n defaultMessage: \"Add a New Address\",\n },\n});\n\ntype Props = {\n addresses: Address[];\n onAddNewAddress: () => void;\n onSubmit: (address: Partial) => void;\n onBack?: () => void;\n};\n\nconst SampleDrawKitSelectAddress: React.FC = ({\n addresses,\n onAddNewAddress,\n onSubmit,\n onBack,\n}) => {\n const intl = useIntl();\n\n return (\n \n \n \n {onBack && (\n \n )}\n >\n }\n />\n );\n};\n\nexport default SampleDrawKitSelectAddress;\n","import { StepperContent } from \"@app/components/ui/layout/stepperContent\";\nimport React, { useContext, useEffect, useState } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport SampleDrawKitAddAddress from \"./sampleDrawKitAddAddress\";\nimport {\n Address,\n KitContext,\n ProfileContext,\n TestDetailsContext,\n} from \"@app/provider\";\nimport SampleDrawKitSelectAddress from \"./sampleDrawKitSelectAddress\";\nimport { getListOfAddresses } from \"@app/utils\";\nimport { useDialog } from \"@natera/platform/lib/hooks\";\nimport { SpinnerView } from \"@app/components\";\nimport KitSuccessDialog from \"./kitSuccessDialog\";\nimport KitErrorDialog from \"./kitErrorDialog\";\nimport SkipKitShippingDialog from \"../../dialogs/skipKitShippingModal/skipKitShippingDialog\";\nimport {\n AddressFormType,\n POBoxErrorNotification,\n} from \"@app/components/poBoxErrorNotification/poBoxErrorNotification\";\nimport { isPOBoxOrPMB } from \"@app/utils/isPOBoxOrPMB\";\n\nconst messages = defineMessages({\n sampleDrawKitStepTitle: {\n id: \"sampleDrawKitStepTitle\",\n defaultMessage: \"Kit Shipping Details\",\n },\n sampleDrawKitStepDescriptionTitle: {\n id: \"sampleDrawKitStepDescriptionTitle\",\n defaultMessage: \"Where should we send your kit?\",\n },\n kitShippingAddressSelectDescriptionContent: {\n id: \"kitShippingAddressSelectDescriptionContent\",\n defaultMessage:\n \"A test kit is needed to get your sample drawn. To have your kit shipped to a different address from the one shown, add a new address.\",\n },\n kitShippingAddressEnterNewAddressDescriptionContent: {\n id: \"kitShippingAddressEnterNewAddressDescriptionContent\",\n defaultMessage:\n \"A test kit is needed to get your sample drawn. To have your kit shipped, please enter a new address.\",\n },\n});\n\nexport enum ADDRESS_VIEW_TYPE {\n CURRENT = \"CURRENT\",\n NEW = \"NEW\",\n}\n\nexport type SampleDrawKitProps = {\n onSubmit: () => Promise;\n onBack?: () => Promise;\n profileAddresses?: Address[];\n orderUidPublic?: string;\n testUid?: string;\n token?: string;\n isPublicMpFlow?: boolean;\n};\n\nconst SampleDrawKitStep: React.FC = ({\n onSubmit,\n onBack,\n orderUidPublic: orderUidPublicProp,\n testUid: testUidProp,\n profileAddresses,\n token,\n isPublicMpFlow,\n}) => {\n const intl = useIntl();\n const successDialog = useDialog(KitSuccessDialog);\n const errorDialog = useDialog(KitErrorDialog);\n const skipKitShippingDialog = useDialog(SkipKitShippingDialog);\n\n const { getProfile, getProfileData: profile } = useContext(ProfileContext);\n const {\n addKit,\n addKitIsLoading,\n setSkipKitShipping,\n setSkipLabStep,\n } = useContext(KitContext);\n const { getOrderUidPublic, getTestUid } = useContext(TestDetailsContext);\n\n const orderUidPublic = orderUidPublicProp ?? getOrderUidPublic();\n const testUid = testUidProp ?? getTestUid();\n const addresses: Address[] = getListOfAddresses(\n profileAddresses ? profileAddresses : profile?.addresses ?? []\n );\n\n const hasAddresses = addresses.length > 0;\n\n const [selectedAddressView, setSelectedAddressView] = useState<\n ADDRESS_VIEW_TYPE\n >(hasAddresses ? ADDRESS_VIEW_TYPE.CURRENT : ADDRESS_VIEW_TYPE.NEW);\n const [showPOBoxError, setShowPOBoxError] = useState(false);\n\n const closeStep = (closeDialog: () => void) => () => {\n closeDialog();\n onSubmit();\n };\n\n const handleSubmit = async (address: Partial) => {\n if (isPOBoxOrPMB(address.street1, address?.street2)) {\n setShowPOBoxError(true);\n return;\n }\n\n if (!address.countryCode) {\n address.countryCode = \"US\";\n }\n\n try {\n const { result, kitOrderSkippedForPR } = await addKit(\n orderUidPublic,\n testUid,\n address,\n token,\n isPublicMpFlow\n );\n await getProfile();\n\n if (result) {\n if (kitOrderSkippedForPR) {\n skipKitShippingDialog.open({\n onClick: () => {\n setSkipKitShipping(true);\n setSkipLabStep(true);\n closeStep(skipKitShippingDialog.close)();\n },\n onClose: skipKitShippingDialog.close,\n });\n return;\n }\n\n successDialog.open({ onClose: closeStep(successDialog.close) });\n } else {\n errorDialog.open({\n onClose: closeStep(errorDialog.close),\n });\n }\n } catch (error) {\n errorDialog.open({\n onClose: closeStep(errorDialog.close),\n });\n }\n };\n\n const onAddNewAddress = () => setSelectedAddressView(ADDRESS_VIEW_TYPE.NEW);\n const onCurrentAddress = () =>\n setSelectedAddressView(ADDRESS_VIEW_TYPE.CURRENT);\n\n const onBackForNewAddress = hasAddresses ? onCurrentAddress : onBack;\n\n useEffect(() => {\n setShowPOBoxError(false);\n }, [selectedAddressView]);\n\n return (\n <>\n {showPOBoxError && (\n \n )}\n \n <>\n {successDialog.getDialog()}\n {errorDialog.getDialog()}\n {skipKitShippingDialog.getDialog()}\n \n {selectedAddressView === ADDRESS_VIEW_TYPE.CURRENT ? (\n \n ) : (\n \n )}\n >\n \n >\n );\n};\n\nexport default SampleDrawKitStep;\n","import React from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Dialog } from \"@natera/material/lib/dialog\";\nimport { Button } from \"@natera/form\";\nimport { LinkHeap } from \"@app/components\";\nimport { HEAP_EVENTS, HeapEventLocation } from \"@app/provider/types\";\nimport { ConfigContext } from \"@app/provider\";\nimport \"./timingInfoDialog.scss\";\n\nconst messages = defineMessages({\n timingInfoDialogHeader: {\n id: \"timingInfoDialogHeader\",\n defaultMessage: \"Before scheduling a draw, please consider:\",\n },\n timingInfoDialogDescription: {\n id: \"timingInfoDialogDescription\",\n defaultMessage:\n \"Blood draws should be coordinated around patient treatment in order to not impact results. Please wait:\",\n },\n timingInfoDialogDescriptionPartOne: {\n id: \"timingInfoDialogDescriptionPartOne\",\n defaultMessage: \"3 days post IV chemo\",\n },\n timingInfoDialogDescriptionPartTwo: {\n id: \"timingInfoDialogDescriptionPartTwo\",\n defaultMessage: \"24 hours post radioactive PET isotope\",\n },\n timingInfoDialogDescriptionPartThree: {\n id: \"timingInfoDialogDescriptionPartThree\",\n defaultMessage:\n \"3 weeks post Packed Red Cell transfusion or 3 months post Whole Blood Transfusion\",\n },\n timingInfoDialogButtonContinue: {\n id: \"timingInfoDialogButtonContinue\",\n defaultMessage: \"Continue\",\n },\n timingInfoDialogDescriptionHelp: {\n id: \"timingInfoDialogDescriptionHelp\",\n defaultMessage: \"Need help scheduling a draw?\",\n },\n timingInfoDialogDescriptionContactUs: {\n id: \"timingInfoDialogDescriptionContactUs\",\n defaultMessage: \"Contact Us\",\n },\n});\n\ntype Props = {\n onClose: () => void;\n onContinue: () => void;\n};\n\nconst TimingInfoDialog: React.FC = ({ onClose, onContinue }) => {\n const intl = useIntl();\n const { config } = React.useContext(ConfigContext);\n\n return (\n \n );\n};\n\nexport default TimingInfoDialog;\n","export { LabList } from \"./labList\";\nexport { ZipSelectorStep } from \"./zipSelector\";\n","export { default as LabList } from \"./labList\";\n","export { default } from \"./labItem\";\n","import React, { FC, useCallback, useState } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport classNames from \"classnames\";\nimport { Notification } from \"@app/components\";\nimport { IconButton } from \"@natera/material/lib/button\";\nimport { stripHtmlTags } from \"@app/utils/common\";\nimport { LinkButton } from \"@natera/form\";\nimport { BloodDrawSite } from \"@app/provider\";\nimport Arrow from \"@assets/svg/icons/lab-arrow.svg\";\nimport { Link } from \"@natera/navigation\";\n\nimport \"./labItem.scss\";\n\nconst messages = defineMessages({\n labCollectionLabListLabItemDistance: {\n id: \"labCollectionLabListLabItemDistance\",\n defaultMessage: \"{distance} mi away\",\n },\n labCollectionLabListLabItemClosed: {\n id: \"labCollectionLabListLabItemClosed\",\n defaultMessage: \"Closed\",\n },\n labCollectionLabListLabItemExpand: {\n id: \"labCollectionLabListLabItemExpand\",\n defaultMessage: \"Expand\",\n },\n labCollectionLabListLabItemCollapse: {\n id: \"labCollectionLabListLabItemCollapse\",\n defaultMessage: \"Collapse\",\n },\n scheduleAppointmentButton: {\n id: \"scheduleAppointmentButton\",\n defaultMessage: \"Schedule appointment\",\n },\n});\n\ninterface LabItemProps {\n bloodDrawSite: BloodDrawSite;\n isPublicMpFlow?: boolean;\n}\n\nconst LabItem: FC = ({ bloodDrawSite, isPublicMpFlow }) => {\n const intl = useIntl();\n const [isOpen, setIsOpen] = useState(false);\n const { distance, name, full_address, phone, site_hours } = bloodDrawSite;\n\n const toggle = useCallback(() => {\n setIsOpen((value) => !value);\n }, [isOpen]);\n\n const publicMpContent = () => {\n return (\n <>\n {bloodDrawSite?.comments && (\n \n {stripHtmlTags(bloodDrawSite.comments)}\n \n )}\n {bloodDrawSite?.appointment_scheduling_url && (\n }\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {intl.formatMessage(messages.scheduleAppointmentButton)}\n \n )}\n >\n );\n };\n\n return (\n \n
\n \n {Arrow}\n \n
\n\n
\n
\n {intl.formatMessage(messages.labCollectionLabListLabItemDistance, {\n distance: distance.toFixed(0),\n })}\n
\n\n
{name}
\n\n
{full_address}
\n\n
\n
\n\n
\n {site_hours.map((siteHour) => (\n
\n {siteHour.day_of_week}\n\n \n {!siteHour.close && !siteHour.open\n ? intl.formatMessage(\n messages.labCollectionLabListLabItemClosed\n )\n : `${siteHour.open} - ${siteHour.close}`}\n \n
\n ))}\n
\n\n {isPublicMpFlow && publicMpContent()}\n
\n
\n
\n );\n};\n\nexport default LabItem;\n","import React, { FC, useContext } from \"react\";\nimport { useNavigate } from \"react-router-dom\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nimport { Button } from \"@natera/material/lib/button\";\n\nimport { StepperContext } from \"@natera/stepper\";\nimport { BloodDrawContext, UppAuthContext } from \"@app/provider\";\nimport { routes } from \"@app/routing\";\nimport LabItem from \"./labItem\";\nimport { StepperContent } from \"@app/components/ui/layout\";\nimport { Form } from \"@natera/form\";\n\nconst messages = defineMessages({\n sampleDrawLabTitle: {\n id: \"sampleDrawLabTitle\",\n defaultMessage: \"Lab Locator\",\n },\n labCollectionLabListDescription: {\n id: \"labCollectionLabListDescription\",\n defaultMessage: \"Please call the lab to request an appointment.\",\n },\n labCollectionLabListDone: {\n id: \"labCollectionLabListDone\",\n defaultMessage: \"Done\",\n },\n labCollectionLabListBack: {\n id: \"labCollectionLabListBack\",\n defaultMessage: \"Back To Search\",\n },\n});\n\nconst LabList: FC = () => {\n const navigate = useNavigate();\n const intl = useIntl();\n const { profile } = useContext(UppAuthContext);\n const { bloodDrawSites } = useContext(BloodDrawContext);\n const { goBack } = useContext(StepperContext);\n\n const done: React.FormEventHandler = (event) => {\n event.preventDefault();\n navigate(routes.home, { replace: true });\n };\n\n return (\n \n );\n};\n\nexport default LabList;\n","export { default as ZipSelectorStep } from \"./zipSelectorStep\";\n","import { ZipSelectorForm } from \"@app/components/forms\";\nimport { StepperContent } from \"@app/components/ui/layout\";\nimport { BloodDrawContext } from \"@app/provider\";\nimport { defineMessages } from \"react-intl\";\nimport { StepperContext } from \"@natera/stepper\";\nimport React from \"react\";\nimport { useIntl } from \"react-intl\";\nimport { SpinnerView } from \"@app/components\";\nimport { Button } from \"@natera/form\";\nimport { ZipValidationErrors } from \"@app/components/forms/zipSelectorForm/zipSelectorForm\";\n\nconst messages = defineMessages({\n sampleDrawLabTitle: {\n id: \"sampleDrawLabTitle\",\n defaultMessage: \"Lab Locator\",\n },\n labCollectionZipSelectorFind: {\n id: \"labCollectionZipSelectorFind\",\n defaultMessage: \"Choose a location to get your blood drawn.\",\n },\n labCollectionZipSelectorLocation: {\n id: \"labCollectionZipSelectorLocation\",\n defaultMessage:\n \"Please enter your zip code to find nearby labs. \\n Labs within 100 miles will be shown.\",\n },\n labCollectionZipSelectorShow: {\n id: \"labCollectionZipSelectorShow\",\n defaultMessage: \"Show labs near me\",\n },\n labCollectionZipSelectorBack: {\n id: \"labCollectionZipSelectorBack\",\n defaultMessage: \"Back\",\n },\n});\n\nconst ZipSelectorStep: React.FC = () => {\n const intl = useIntl();\n\n const { goBack, resolve } = React.useContext(StepperContext);\n const { getBloodDrawSites, isLoading } = React.useContext(BloodDrawContext);\n\n const [\n zipValidationErrorKey,\n setZipValidationErrorKey,\n ] = React.useState(null);\n\n const onSubmit = async (zipCode: string) => {\n const data = await getBloodDrawSites({ location: zipCode });\n if (!data?.length) {\n setZipValidationErrorKey(ZipValidationErrors.NO_LAB);\n return;\n }\n resolve({});\n };\n\n return (\n \n \n \n \n \n\n \n >\n }\n />\n \n
\n );\n};\n\nexport default ZipSelectorStep;\n","import React, { FC, useContext, useState } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Button, Form, Textarea } from \"@natera/form\";\nimport { StepperContext } from \"@natera/stepper\";\nimport {\n DrawRequestContext,\n HeapAnalyticDataContext,\n IntlContext,\n ProfileContext,\n TestDetailsContext,\n UppAuthContext,\n} from \"@app/provider\";\nimport { FormField } from \"@app/components\";\nimport { SAMPLE_DRAW_STEP_IDS } from \"@app/pages/private/sampleDraw/sampleDraw\";\nimport StepperHeaderProgress from \"@app/components/stepperHeaderProgress\";\nimport * as R from \"ramda\";\nimport { HEAP_EVENTS, HeapProps, ShippingAddress } from \"@app/provider/types\";\nimport { StepperContent } from \"@app/components/ui/layout\";\n\nimport { TestType } from \"@app/provider/testData/types\";\nimport { getParamsForHeapMPApptFailureEvent } from \"@app/utils\";\n\nimport \"./additionalInstructionsStep.scss\";\n\nconst messages = defineMessages({\n additionalInstructionsStepTitle: {\n id: \"additionalInstructionsStepTitle\",\n defaultMessage: \"Mobile Blood Draw\",\n },\n additionalInstructionsStepDescriptionTitle: {\n id: \"additionalInstructionsStepDescriptionTitle\",\n defaultMessage:\n \"Would you like to add any comments or instructions for your blood draw appointment?\",\n },\n additionalInstructionsFormLabel: {\n id: \"additionalInstructionsFormLabel\",\n defaultMessage: \"Comments\",\n },\n additionalInstructionsFormInputPlaceholder: {\n id: \"additionalInstructionsFormInputPlaceholder\",\n defaultMessage:\n \"Examples: Look for the green house, ring doorbell at the side door, use code #104 to open the parking gate, etc.\",\n },\n additionalInstructionsSubmitAppointmentRequest: {\n id: \"additionalInstructionsSubmitAppointmentRequest\",\n defaultMessage: \"Submit\",\n },\n additionalInstructionsBack: {\n id: \"additionalInstructionsBack\",\n defaultMessage: \"Back\",\n },\n});\n\ntype AdditionalInstructionsStepProps = {\n handleCreateDrawRequestError?: () => void;\n testType?: TestType;\n orderUidPublic?: string;\n testUid?: string;\n token?: string;\n isPublicRequest?: boolean;\n};\n\nconst AdditionalInstructionsStep: FC = ({\n handleCreateDrawRequestError,\n ...props\n}) => {\n const intl = useIntl();\n const [additionalInstructions, setAdditionalInstructions] = useState(\n \"\"\n );\n const [loading, setLoading] = useState(false);\n\n const { getTestDetails } = useContext(TestDetailsContext);\n const { updatePatientLanguage } = useContext(ProfileContext);\n const { currentLanguage } = useContext(IntlContext);\n\n const testDetails = getTestDetails();\n\n const {\n createDrawRequest,\n openCreateDrawErrorDialog,\n verifiedSampleDrawData,\n } = useContext(DrawRequestContext);\n\n const { profile } = React.useContext(UppAuthContext);\n\n const { drawRequestDataForHeapEventData } = useContext(\n HeapAnalyticDataContext\n );\n\n const { getData, resolve, goBack } = useContext(StepperContext);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setLoading(true);\n const shippingAddress = getData(SAMPLE_DRAW_STEP_IDS.MP1)?.address;\n\n const timeSlots = getData(SAMPLE_DRAW_STEP_IDS.MP2)?.timeSlots;\n const timeZone = getData(SAMPLE_DRAW_STEP_IDS.MP2)?.timeZone;\n\n try {\n await updatePatientLanguage(currentLanguage, props.token);\n await createDrawRequest({\n timeZone,\n shippingAddress: R.omit([\"uid\"], shippingAddress) as ShippingAddress,\n timeSlots,\n notes: additionalInstructions,\n ...props,\n });\n\n resolve({});\n } catch {\n const heapEventProps: HeapProps = getParamsForHeapMPApptFailureEvent(\n Boolean(props.isPublicRequest),\n profile,\n {\n verifiedSampleDrawData,\n testDetails,\n drawRequestDataForHeapEventData,\n }\n );\n\n if (props.isPublicRequest) {\n heapEventProps.identity =\n verifiedSampleDrawData?.profileInfo.profile?.uid ?? \"\";\n }\n\n heap.track(HEAP_EVENTS.upp_sampledraw_mp_appt_failure, heapEventProps);\n\n handleCreateDrawRequestError\n ? handleCreateDrawRequestError()\n : openCreateDrawErrorDialog();\n } finally {\n setLoading(false);\n }\n };\n\n const handleBackButtonClick = () => goBack();\n\n const handleChangeAdditionalInstructions: React.ChangeEventHandler = (\n event\n ) =>\n event.target.value.length <= 255 &&\n setAdditionalInstructions(event.target.value);\n\n return (\n <>\n \n \n \n \n >\n );\n};\nexport default AdditionalInstructionsStep;\n","export { default as AdditionalInstructionsStep } from \"./additionalInstructionsStep\";\n","export { default as SampleDrawMPAddressStep } from \"./sampleDrawMPAddressStep\";\n","import { AddressForm } from \"@app/components/forms\";\nimport { Address } from \"@app/provider\";\nimport { Button } from \"@natera/form\";\nimport React from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nexport const messages = defineMessages({\n sampleDrawMPAddAddressNextButtonText: {\n id: \"sampleDrawMPAddAddressNextButtonText\",\n defaultMessage: \"Add\",\n },\n sampleDrawMPAddAddressBackButtonText: {\n id: \"sampleDrawMPAddAddressBackButtonText\",\n defaultMessage: \"Back\",\n },\n});\n\ntype Props = {\n onSubmit: (address: Partial) => void;\n onBack?: () => void;\n};\n\nconst SampleDrawMPAddAddress: React.FC = ({ onSubmit, onBack }) => {\n const intl = useIntl();\n\n return (\n \n \n {onBack && (\n \n )}\n >\n }\n />\n );\n};\n\nexport default SampleDrawMPAddAddress;\n","import { StepperContent } from \"@app/components/ui/layout/stepperContent\";\nimport React, { useContext, useEffect, useState } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Address, KitContext, ProfileContext } from \"@app/provider\";\nimport { getListOfAddresses } from \"@app/utils\";\nimport { StepperContext } from \"@natera/stepper\";\nimport SampleDrawMPAddAddress from \"./sampleDrawMPAddAddress\";\nimport SampleDrawMPSelectAddress from \"./sampleDrawMPSelectAddress\";\nimport {\n AddressFormType,\n POBoxErrorNotification,\n} from \"@app/components/poBoxErrorNotification/poBoxErrorNotification\";\nimport { isPOBoxOrPMB } from \"@app/utils/isPOBoxOrPMB\";\nimport StepperHeaderProgress from \"@app/components/stepperHeaderProgress\";\nimport { DrawRequestFlow } from \"@app/provider/drawRequest\";\n\nconst messages = defineMessages({\n sampleDrawMPAddressStepTitle: {\n id: \"sampleDrawMPAddressStepTitle\",\n defaultMessage: \"Mobile Blood Draw\",\n },\n sampleDrawMPAddressStepDescriptionTitle: {\n id: \"sampleDrawMPAddressStepDescriptionTitle\",\n defaultMessage: \"Where would you like to have your blood drawn?\",\n },\n sampleDrawMPAddressStepDescriptionContent: {\n id: \"sampleDrawMPAddressStepDescriptionContent\",\n defaultMessage: \"Please select or add an address.\",\n },\n});\n\nexport enum ADDRESS_VIEW_TYPE {\n CURRENT = \"CURRENT\",\n NEW = \"NEW\",\n}\n\ninterface SampleDrawMPAddressStepProps {\n profileAddresses?: Address[];\n onBackKitShippingStep?: () => void;\n isPublicMpFlow?: boolean;\n flow?: DrawRequestFlow;\n}\n\nconst SampleDrawMPAddressStep: React.FC = ({\n profileAddresses,\n onBackKitShippingStep,\n isPublicMpFlow,\n flow,\n}) => {\n const intl = useIntl();\n\n const { resolve, goBack } = useContext(StepperContext);\n const { getProfileData: profile } = useContext(ProfileContext);\n const { skipKitShipping, skipLabStep } = useContext(KitContext);\n\n const addresses: Address[] = getListOfAddresses(\n profileAddresses ? profileAddresses : profile?.addresses ?? []\n );\n\n const hasAddresses = addresses.length > 0;\n\n const onAddNewAddress = () => setSelectedAddressView(ADDRESS_VIEW_TYPE.NEW);\n const onCurrentAddress = () =>\n setSelectedAddressView(ADDRESS_VIEW_TYPE.CURRENT);\n\n const onBack = () => {\n if (flow === DrawRequestFlow.ACCOUNT && !skipLabStep) {\n goBack();\n } else {\n skipKitShipping && onBackKitShippingStep\n ? onBackKitShippingStep()\n : goBack();\n }\n };\n const onBackForNewAddress = hasAddresses ? onCurrentAddress : onBack;\n\n const [selectedAddressView, setSelectedAddressView] = useState<\n ADDRESS_VIEW_TYPE\n >(hasAddresses ? ADDRESS_VIEW_TYPE.CURRENT : ADDRESS_VIEW_TYPE.NEW);\n const [showPOBoxError, setShowPOBoxError] = useState(false);\n\n const onSumbit = async (address: Partial) => {\n if (isPOBoxOrPMB(address.street1, address?.street2)) {\n setShowPOBoxError(true);\n return;\n }\n if (!address.countryCode) {\n address.countryCode = \"US\";\n }\n resolve({ address });\n };\n\n useEffect(() => {\n setShowPOBoxError(false);\n }, [selectedAddressView]);\n\n return (\n <>\n {showPOBoxError && (\n \n )}\n \n \n <>\n {selectedAddressView === ADDRESS_VIEW_TYPE.CURRENT ? (\n \n ) : (\n \n )}\n >\n \n >\n );\n};\n\nexport default SampleDrawMPAddressStep;\n","import React from \"react\";\nimport { SelectAddressForm } from \"@app/components/forms\";\nimport { Address } from \"@app/provider\";\nimport { Button } from \"@natera/form\";\nimport { defineMessages, useIntl } from \"react-intl\";\n\nexport const messages = defineMessages({\n sampleDrawMPSelectAddressNextButtonText: {\n id: \"sampleDrawMPSelectAddressNextButtonText\",\n defaultMessage: \"Next\",\n },\n sampleDrawMPSelectAddressBackButtonText: {\n id: \"sampleDrawMPSelectAddressBackButtonText\",\n defaultMessage: \"Back\",\n },\n sampleDrawMPSelectAddressNewAddressButton: {\n id: \"sampleDrawMPSelectAddressNewAddressButton\",\n defaultMessage: \"Enter a New Address\",\n },\n});\n\ntype Props = {\n addresses: Address[];\n onAddNewAddress: () => void;\n onSubmit: (address: Partial) => void;\n onBack?: () => void;\n};\n\nconst SampleDrawMPSelectAddress: React.FC = ({\n addresses,\n onAddNewAddress,\n onSubmit,\n onBack,\n}) => {\n const intl = useIntl();\n\n return (\n \n \n \n {onBack && (\n \n )}\n >\n }\n />\n );\n};\n\nexport default SampleDrawMPSelectAddress;\n","import React, { FC, useContext, useMemo, useState } from \"react\";\nimport StepperHeaderProgress from \"@app/components/stepperHeaderProgress\";\nimport ModifyAppointment from \"@app/components/sampleDraw/mobilePhlebotomy/appointmentTimeStep/modifyAppointment\";\nimport { DrawRequestContext } from \"@app/provider\";\nimport { AppointmentTimeConfirmation } from \"@app/components/sampleDraw/mobilePhlebotomy/appointmentTimeStep/appointmentTimeConfirmation\";\nimport { TestType } from \"@app/provider/testData/types\";\n\ntype AppointmentTimeStepProps = {\n onBack?: () => void;\n testType?: TestType;\n orderUidPublic?: string;\n testUid?: string;\n token?: string;\n isPublicRequest?: boolean;\n};\n\nconst AppointmentTimeStep: FC = ({\n onBack,\n ...props\n}) => {\n const { drawRequestId: reqId } = useContext(DrawRequestContext);\n\n const [modifyAppointment, setModifyAppointment] = useState(false);\n\n const handleModifyAppointment = () => setModifyAppointment(true);\n\n const showModifyAppointmentView = useMemo(() => modifyAppointment && reqId, [\n modifyAppointment,\n reqId,\n ]);\n\n const handleBackToTimeConfirmation = () => setModifyAppointment(false);\n\n return (\n <>\n {showModifyAppointmentView ? (\n \n ) : (\n <>\n {!modifyAppointment && }\n \n >\n )}\n >\n );\n};\n\nexport default AppointmentTimeStep;\n","export { default as AppointmentTimeStep } from \"./appointmentTimeStep\";\n","export { SampleDrawMPAddressStep } from \"./address\";\nexport { TimeslotsStep } from \"./timeslots\";\nexport { AdditionalInstructionsStep } from \"./additionalInstructionsStep\";\nexport { AppointmentTimeStep } from \"./appointmentTimeStep\";\n","export { default as TimeslotsStep } from \"./timeslotsStep\";\n","import React from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { StepperContext } from \"@natera/stepper\";\n\nimport TimeslotsForm from \"@app/components/forms/timeslotsForm/timeslotsForm\";\nimport { StepperContent } from \"@app/components/ui/layout\";\nimport StepperHeaderProgress from \"@app/components/stepperHeaderProgress\";\nimport { SpecificDatesProvider } from \"@app/provider\";\n\nconst messages = defineMessages({\n mobilePhlebotomyTimeslotsTitle: {\n id: \"mobilePhlebotomyTimeslotsTitle\",\n defaultMessage: \"Mobile Blood Draw\",\n },\n mobilePhlebotomyTimeslotsDescriptionTitle: {\n id: \"mobilePhlebotomyTimeslotsDescriptionTitle\",\n defaultMessage: \"When are some good times for your blood draw?\",\n },\n mobilePhlebotomyTimeslotsDescription: {\n id: \"mobilePhlebotomyTimeslotsDescription\",\n defaultMessage:\n \"Please select three time slots across three different dates to ensure that we can match you with an appointment.\",\n },\n mobilePhlebotomyTimeslotsNext: {\n id: \"mobilePhlebotomyTimeslotsNext\",\n defaultMessage: \"Next\",\n },\n});\n\nconst Timeslots: React.FC = () => {\n const intl = useIntl();\n const { goBack, resolve } = React.useContext(StepperContext);\n\n return (\n <>\n \n \n \n \n \n \n >\n );\n};\n\nexport default Timeslots;\n","export { default as SampleDrawPreferenceStep } from \"./sampleDrawPreference\";\n","import React, { FC, useEffect } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { Button, Form, RadioButton, RadioGroup } from \"@natera/form\";\nimport { StepperContext } from \"@natera/stepper\";\nimport { DRAW_PREFERENCE_TO_SHOW } from \"@app/pages/private/sampleDraw/sampleDraw\";\nimport { HEAP_EVENTS } from \"@app/provider/types\";\nimport {\n DrawRequestContext,\n HeapAnalyticDataContext,\n TestDetailsContext,\n UppAuthContext,\n} from \"@app/provider\";\nimport { StepperContent } from \"@app/components/ui/layout\";\nimport { SpinnerView } from \"@app/components\";\nimport { useDialog } from \"@natera/platform/lib/hooks\";\nimport { ClinicRequestModal } from \"@app/components/sampleDraw/dialogs\";\nimport { TestType } from \"@app/provider/testData/types\";\nimport StepperHeaderProgress from \"@app/components/stepperHeaderProgress\";\n\nimport \"./sampleDrawPreference.scss\";\n\nconst messages = defineMessages({\n clinicPreferenceTitle: {\n id: \"clinicPreferenceTitle\",\n defaultMessage: \"My Clinic\",\n },\n clinicPreferenceDescription: {\n id: \"clinicPreferenceDescription\",\n defaultMessage:\n \"Contact your clinic directly to see if they offer on-site blood draw services.\",\n },\n sampleDrawPreferenceTitle: {\n id: \"sampleDrawPreferenceTitle\",\n defaultMessage: \"Sample Collection\",\n },\n sampleDrawPreferenceDescriptionTitle: {\n id: \"sampleDrawPreferenceDescriptionTitle\",\n defaultMessage: \"What is the best way to get a blood draw?\",\n },\n sampleDrawPreferenceDescriptionContent: {\n id: \"sampleDrawPreferenceDescriptionContent\",\n defaultMessage:\n \"Natera will cover the cost of your blood draw when you use one of the following methods. Select the method that works best for you.\",\n },\n sampleDrawPreferenceMobilePhlebotomyTitle: {\n id: \"sampleDrawPreferenceMobilePhlebotomyTitle\",\n defaultMessage: \"Mobile Blood Draw\",\n },\n sampleDrawPreferenceMobilePhlebotomyDescription: {\n id: \"sampleDrawPreferenceMobilePhlebotomyDescription\",\n defaultMessage:\n \"You can have someone come to your desired location to perform your blood draw.\",\n },\n sampleDrawPreferenceLabTitle: {\n id: \"sampleDrawPreferenceLabTitle\",\n defaultMessage: \"Local Lab\",\n },\n sampleDrawPreferenceLabDescription: {\n id: \"sampleDrawPreferenceLabDescription\",\n defaultMessage: \"Visit a Natera-approved lab to have your blood drawn.\",\n },\n sampleDrawPreferenceNext: {\n id: \"sampleDrawPreferenceNext\",\n defaultMessage: \"Next\",\n },\n sampleDrawPreferenceBack: {\n id: \"sampleDrawPreferenceBack\",\n defaultMessage: \"Back\",\n },\n});\n\nexport const SAMPLE_DRAW_PREFERENCE_LIST = {\n clinic: {\n title: messages.clinicPreferenceTitle,\n description: messages.clinicPreferenceDescription,\n },\n lab: {\n title: messages.sampleDrawPreferenceLabTitle,\n description: messages.sampleDrawPreferenceLabDescription,\n },\n mobilePhlebotomy: {\n title: messages.sampleDrawPreferenceMobilePhlebotomyTitle,\n description: messages.sampleDrawPreferenceMobilePhlebotomyDescription,\n },\n};\n\nexport interface SampleDrawPreferenceProps {\n handleSelectSampleDrawPreference: (\n draw_preference?: DRAW_PREFERENCE_TO_SHOW\n ) => void;\n onBack: () => void;\n}\n\nconst SampleDrawPreference: FC = ({\n handleSelectSampleDrawPreference,\n onBack,\n}) => {\n const intl = useIntl();\n\n const { resolve } = React.useContext(StepperContext);\n const { isLoading, verifiedSampleDrawData } = React.useContext(\n DrawRequestContext\n );\n\n const { drawRequestDataForHeapEventData } = React.useContext(\n HeapAnalyticDataContext\n );\n\n const { getTestDetails } = React.useContext(TestDetailsContext);\n const { profile } = React.useContext(UppAuthContext);\n\n const testDetails = getTestDetails();\n\n const testType =\n testDetails?.testType ??\n verifiedSampleDrawData?.sampleInfo.sample?.testType;\n const clinicModal = useDialog(ClinicRequestModal);\n const isOncologyOrder =\n testDetails?.isOncologyOrder ??\n verifiedSampleDrawData?.sampleInfo.sample?.isOncologyOrder;\n\n const isWHTestType =\n testType &&\n [\n TestType.EMPOWER,\n TestType.HORIZON,\n TestType.PANORAMA,\n TestType.VISTARA,\n ].includes(testType) &&\n !isOncologyOrder;\n\n const [\n selectedSampleDrawPreference,\n setSelectedSampleDrawPreference,\n ] = React.useState(\n isWHTestType ? undefined : DRAW_PREFERENCE_TO_SHOW.lab\n );\n\n useEffect(() => {\n handleSelectSampleDrawPreference(selectedSampleDrawPreference);\n }, [selectedSampleDrawPreference]);\n\n const handleSubmit: React.FormEventHandler = (event) => {\n event.preventDefault();\n const heapProps = {\n lims_clinic_id: drawRequestDataForHeapEventData?.lims_clinic_id,\n drawtype:\n selectedSampleDrawPreference ===\n DRAW_PREFERENCE_TO_SHOW.mobilePhlebotomy\n ? \"mobile_phlebotomy\"\n : selectedSampleDrawPreference,\n test_name: drawRequestDataForHeapEventData?.test_name,\n business_unit: drawRequestDataForHeapEventData?.business_unit,\n flow: profile ? \"account\" : \"guest\",\n };\n heap.track(HEAP_EVENTS.upp_sampledraw_pref, heapProps);\n selectedSampleDrawPreference === DRAW_PREFERENCE_TO_SHOW.clinic\n ? clinicModal.open({ goBack: clinicModal.close, isGuest: !profile })\n : resolve({});\n };\n\n const handleSampleDrawPreferenceSelect = (\n drawPreferenceType: DRAW_PREFERENCE_TO_SHOW\n ) => {\n setSelectedSampleDrawPreference(drawPreferenceType);\n };\n\n const renderDrawPreferenceItem = (\n drawPreferenceType: DRAW_PREFERENCE_TO_SHOW\n ) => {\n const drawPreferenceText =\n drawPreferenceType in SAMPLE_DRAW_PREFERENCE_LIST &&\n SAMPLE_DRAW_PREFERENCE_LIST[drawPreferenceType];\n\n return drawPreferenceText ? (\n \n \n {intl.formatMessage(drawPreferenceText.title)}\n
\n \n {intl.formatMessage(drawPreferenceText.description)}\n
\n >\n }\n value={drawPreferenceType}\n />\n ) : null;\n };\n\n const getDrawPreferences = () =>\n Object.keys(DRAW_PREFERENCE_TO_SHOW)\n .filter((drawPreferenceType: DRAW_PREFERENCE_TO_SHOW) => {\n if (!isWHTestType)\n return drawPreferenceType !== DRAW_PREFERENCE_TO_SHOW.clinic;\n return drawPreferenceType;\n })\n .map((drawPreferenceType: DRAW_PREFERENCE_TO_SHOW) =>\n renderDrawPreferenceItem(drawPreferenceType)\n );\n\n return (\n \n
\n
\n
\n \n \n {clinicModal.getDialog()}\n
\n );\n};\n\nexport default SampleDrawPreference;\n","export { default } from \"./secondaryActionCard\";\n","import React, { FC } from \"react\";\nimport { useIntl } from \"react-intl\";\nimport { InfoCard } from \"@natera/patient\";\nimport { Button } from \"@natera/form\";\nimport { useDialog } from \"@natera/platform/lib/hooks\";\nimport { CompassionateCareDialog } from \"@app/components\";\nimport CardParams from \"./secondaryActionCardParams\";\nimport { SecondaryCard } from \"@app/provider/testData/types\";\nimport \"./secondaryActionCard.scss\";\n\ninterface SecondaryActionCardProps {\n card: SecondaryCard;\n}\n\nconst SecondaryActionCard: FC = ({ card }) => {\n const intl = useIntl();\n const compassionateCareDialog = useDialog(CompassionateCareDialog);\n\n const compassionateCareAction = () => {\n compassionateCareDialog.open({\n onCloseDialog: () => compassionateCareDialog.close(),\n });\n };\n\n const params = CardParams({ compassionateCareAction, card });\n\n const cardParam = params[card.type];\n\n return (\n <>\n {compassionateCareDialog.getDialog()}\n \n
\n \n
\n {card.title}\n
\n
\n {card.description}\n
\n
\n \n
\n
\n \n
\n >\n );\n};\n\nexport default SecondaryActionCard;\n","import React, { useContext } from \"react\";\nimport { defineMessages } from \"react-intl\";\nimport {\n SecondaryActionCardType,\n SecondaryActionCardTypeForHeapEvent,\n SecondaryCard,\n} from \"@app/provider/testData/types\";\nimport TeachingIcon from \"@assets/svg/icons/teaching.svg\";\nimport SalivaImage from \"@assets/svg/icons/saliva.svg\";\nimport BillImage from \"@assets/svg/icons/bill.svg\";\nimport DollarIcon from \"@assets/svg/icons/dollar.svg\";\nimport ContentAsideImage from \"@assets/svg/contentAsideImage.svg\";\nimport Svg from \"@natera/material/lib/svg\";\nimport { useNavigate } from \"react-router-dom\";\nimport { routes } from \"@app/routing\";\nimport { ConfigContext, IntlContext, Language } from \"@app/provider\";\nimport { openNewWindow } from \"@app/utils\";\nimport { HEAP_EVENTS } from \"@app/provider/types\";\n\nimport \"./secondaryActionCard.scss\";\n\nimport \"./secondaryActionCard.scss\";\n\nconst messages = defineMessages({\n secondaryActionCardLearnMore: {\n id: \"secondaryActionCardLearnMore\",\n defaultMessage: \"Learn More\",\n },\n});\n\nexport interface CardParam {\n icon: string;\n contentAside?: React.ReactNode;\n btn: {\n title: {\n id: string;\n defaultMessage: string;\n };\n action: () => void;\n };\n}\n\ninterface CardParamProps {\n compassionateCareAction: () => void;\n card: SecondaryCard;\n}\n\nexport const getCardTypeForHeap = (cardType: SecondaryActionCardType) => {\n switch (cardType) {\n case SecondaryActionCardType.COMPASSIONATE_CARE:\n return SecondaryActionCardTypeForHeapEvent.COMPCARE_INFO;\n case SecondaryActionCardType.WOMENS_HEALTH_PRICING_BILLING:\n return SecondaryActionCardTypeForHeapEvent.BILLING_FAQ_WH;\n case SecondaryActionCardType.ONCOLOGY_PRICING_BILLING:\n return SecondaryActionCardTypeForHeapEvent.BILLING_FAQ_ONC;\n case SecondaryActionCardType.EMPOWER:\n return SecondaryActionCardTypeForHeapEvent.EMPOWER_INFO;\n case SecondaryActionCardType.PANORAMA_HORIZON:\n return SecondaryActionCardTypeForHeapEvent.HORIZON_PANORAMA_INFO;\n case SecondaryActionCardType.HORIZON:\n return SecondaryActionCardTypeForHeapEvent.HORIZON_INFO;\n case SecondaryActionCardType.SALIVA:\n return SecondaryActionCardTypeForHeapEvent.SALIVA_COLLECTION_INFO;\n case SecondaryActionCardType.VISTARA:\n return SecondaryActionCardTypeForHeapEvent.VISTARA_INFO;\n case SecondaryActionCardType.GENETIC_TESTING:\n return SecondaryActionCardTypeForHeapEvent.MULTITEST_INFO_WH;\n case SecondaryActionCardType.PANORAMA:\n return SecondaryActionCardTypeForHeapEvent.PANORAMA_INFO;\n case SecondaryActionCardType.PROSPERA_HEART:\n return SecondaryActionCardTypeForHeapEvent.PROSPERA_INFO;\n case SecondaryActionCardType.PROSPERA_KIDNEY:\n return SecondaryActionCardTypeForHeapEvent.PROSPERA_INFO;\n case SecondaryActionCardType.PROSPERA_LIVER:\n return SecondaryActionCardTypeForHeapEvent.PROSPERA_INFO;\n case SecondaryActionCardType.PROSPERA_LUNG:\n return SecondaryActionCardTypeForHeapEvent.PROSPERA_INFO;\n case SecondaryActionCardType.PROSPERA_OTHER:\n return SecondaryActionCardTypeForHeapEvent.PROSPERA_INFO;\n case SecondaryActionCardType.PROSPERA_SPK:\n return SecondaryActionCardTypeForHeapEvent.PROSPERA_INFO;\n case SecondaryActionCardType.RENASIGHT_KIDNEY:\n return SecondaryActionCardTypeForHeapEvent.RENASIGHT_INFO;\n case SecondaryActionCardType.ALTERA:\n return SecondaryActionCardTypeForHeapEvent.ALTERA_INFO;\n case SecondaryActionCardType.SIGNATERA:\n return SecondaryActionCardTypeForHeapEvent.SIGNATERA_INFO;\n default:\n return \"\";\n }\n};\n\nconst CardParams = ({\n compassionateCareAction,\n card,\n}: CardParamProps): Record => {\n const navigate = useNavigate();\n const { config } = useContext(ConfigContext);\n const { currentLanguage } = useContext(IntlContext);\n\n const openNewWindowAndSendHeapEvent = (link: string) => {\n openNewWindow(link);\n heap.track(HEAP_EVENTS.upp_secondarycard_click, {\n card_type: getCardTypeForHeap(card.type),\n lims_clinic_id: card.limsClinicId,\n });\n };\n\n const historyPushAndSendHeapEvent = (location: string) => {\n navigate(location);\n heap.track(HEAP_EVENTS.upp_secondarycard_click, {\n card_type: getCardTypeForHeap(card.type),\n lims_clinic_id: card.limsClinicId,\n });\n };\n\n const cardParams = React.useMemo(\n () => ({\n [SecondaryActionCardType.COMPASSIONATE_CARE]: {\n icon: DollarIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: compassionateCareAction,\n },\n },\n [SecondaryActionCardType.SALIVA]: {\n icon: TeachingIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: () =>\n historyPushAndSendHeapEvent(\n `${routes.displayVideo}/${SecondaryActionCardType.SALIVA}`\n ),\n },\n },\n [SecondaryActionCardType.RENASIGHT_KIDNEY]: {\n icon: TeachingIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: () =>\n openNewWindowAndSendHeapEvent(config.links.product.RENASIGHT),\n },\n },\n [SecondaryActionCardType.PROSPERA_KIDNEY]: {\n icon: TeachingIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: () =>\n openNewWindowAndSendHeapEvent(config.links.product.PROSPERA.KIDNEY),\n },\n },\n [SecondaryActionCardType.PROSPERA_SPK]: {\n icon: TeachingIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: () =>\n openNewWindowAndSendHeapEvent(config.links.product.PROSPERA.SPK),\n },\n },\n [SecondaryActionCardType.PROSPERA_HEART]: {\n icon: TeachingIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: () =>\n openNewWindowAndSendHeapEvent(config.links.product.PROSPERA.HEART),\n },\n },\n [SecondaryActionCardType.PROSPERA_LIVER]: {\n icon: TeachingIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: () =>\n openNewWindowAndSendHeapEvent(config.links.product.PROSPERA.LIVER),\n },\n },\n [SecondaryActionCardType.PROSPERA_LUNG]: {\n icon: TeachingIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: () =>\n openNewWindowAndSendHeapEvent(config.links.product.PROSPERA.LUNG),\n },\n },\n [SecondaryActionCardType.PROSPERA_OTHER]: {\n icon: TeachingIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: () =>\n openNewWindowAndSendHeapEvent(config.links.product.PROSPERA.OTHER),\n },\n },\n [SecondaryActionCardType.EMPOWER]: {\n icon: TeachingIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: () => {\n if (currentLanguage === Language.EN) {\n openNewWindowAndSendHeapEvent(config.links.product.EMPOWER.EN);\n } else {\n openNewWindowAndSendHeapEvent(config.links.product.EMPOWER.ES);\n }\n },\n },\n },\n [SecondaryActionCardType.HORIZON]: {\n icon: TeachingIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: () =>\n openNewWindowAndSendHeapEvent(config.links.product.HORIZON),\n },\n },\n [SecondaryActionCardType.PANORAMA]: {\n icon: TeachingIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: () =>\n openNewWindowAndSendHeapEvent(config.links.product.PANORAMA),\n },\n },\n [SecondaryActionCardType.VISTARA]: {\n icon: TeachingIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: () =>\n openNewWindowAndSendHeapEvent(config.links.product.VISTARA),\n },\n },\n [SecondaryActionCardType.GENETIC_TESTING]: {\n icon: TeachingIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: () =>\n openNewWindowAndSendHeapEvent(config.links.product.WOMENS_HEALTH),\n },\n },\n [SecondaryActionCardType.PANORAMA_HORIZON]: {\n icon: TeachingIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: () =>\n openNewWindowAndSendHeapEvent(\n config.links.product.PANORAMA_HORIZON\n ),\n },\n },\n [SecondaryActionCardType.ALTERA]: {\n icon: TeachingIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: () => {\n openNewWindowAndSendHeapEvent(config.links.product.ALTERA);\n },\n },\n },\n [SecondaryActionCardType.SIGNATERA]: {\n icon: TeachingIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: () => {\n openNewWindowAndSendHeapEvent(config.links.product.SIGNATERA);\n },\n },\n },\n [SecondaryActionCardType.WOMENS_HEALTH_PRICING_BILLING]: {\n icon: DollarIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: () =>\n openNewWindowAndSendHeapEvent(\n config.links.WOMENS_HEALTH_PRICING_BILLING\n ),\n },\n },\n [SecondaryActionCardType.ONCOLOGY_PRICING_BILLING]: {\n icon: DollarIcon,\n contentAside: (\n \n ),\n btn: {\n title: messages.secondaryActionCardLearnMore,\n action: () =>\n openNewWindowAndSendHeapEvent(\n config.links.ONCOLOGY_PRICING_BILLING\n ),\n },\n },\n }),\n [currentLanguage]\n );\n\n return cardParams;\n};\n\nexport default CardParams;\n","import { defineMessages, useIntl } from \"react-intl\";\nimport React from \"react\";\nimport { Button, Form } from \"@natera/form\";\nimport { PatientEthnicityInput } from \"@app/components/selectEthnicity/ethnicityStep\";\nimport {\n EthnicityContext,\n EthnicityController,\n EthnicitySelect as BaseEthnicitySelect,\n} from \"@natera/patient\";\nimport { Ethnicity, PatientEthnicityOutput } from \"@app/provider/profile/types\";\nimport { HEAP_EVENTS } from \"@app/provider/types\";\nimport { getTestNameForHeap } from \"@app/utils\";\nimport { OrderContext } from \"@app/provider/order\";\n\nconst messages = defineMessages({\n selectEthnicityNext: {\n id: \"selectEthnicityNext\",\n defaultMessage: \"Next\",\n },\n selectEthnicityBack: {\n id: \"selectEthnicityBack\",\n defaultMessage: \"Back\",\n },\n ethnicityAfricanAmericanDescription: {\n id: \"ethnicityAfricanAmericanDescription\",\n defaultMessage: \"African American / Black\",\n },\n ethnicityHispanicDescription: {\n id: \"ethnicityHispanicDescription\",\n defaultMessage: \"Hispanic / Latin American\",\n },\n ethnicityMediterraneanDescription: {\n id: \"ethnicityMediterraneanDescription\",\n defaultMessage: \"Mediterranean\",\n },\n ethnicityCaucasianDescription: {\n id: \"ethnicityCaucasianDescription\",\n defaultMessage: \"Caucasian / Non-Hispanic White\",\n },\n ethnicityAshkenaziDescription: {\n id: \"ethnicityAshkenaziDescription\",\n defaultMessage: \"Ashkenazi Jewish\",\n },\n ethnicitySephardicDescription: {\n id: \"ethnicitySephardicDescription\",\n defaultMessage: \"Sephardic Jewish\",\n },\n ethnicityFrenchCanadianDescription: {\n id: \"ethnicityFrenchCanadianDescription\",\n defaultMessage: \"French Canadian\",\n },\n ethnicityEastAsianDescription: {\n id: \"ethnicityEastAsianDescription\",\n defaultMessage: \"East Asian\",\n },\n ethnicitySoutheastAsianDescription: {\n id: \"ethnicitySoutheastAsianDescription\",\n defaultMessage: \"Southeast Asian\",\n },\n ethnicitySouthAsianDescription: {\n id: \"ethnicitySouthAsianDescription\",\n defaultMessage: \"South Asian\",\n },\n ethnicityOtherDescription: {\n id: \"ethnicityOtherDescription\",\n defaultMessage: \"Other\",\n },\n});\n\ntype Props = {\n defaultValue?: string[];\n profileEthnicities: PatientEthnicityOutput | undefined;\n onSubmit: (value: PatientEthnicityInput) => void;\n goBack: () => void;\n loading?: boolean;\n};\n\nexport const submitEthnicities = (\n onSubmit: (value: PatientEthnicityInput) => void,\n checkedEthnicities: string[] | undefined,\n ethnicities: Ethnicity[]\n): void => {\n const ethnicityInput: PatientEthnicityInput = {\n codes: checkedEthnicities!,\n subEthnicity: \"\",\n };\n\n const ethnicitiesList = ethnicities?.map((value) => value.code);\n const customEthnicity = checkedEthnicities?.find(\n (ethnicity) => !ethnicitiesList?.includes(ethnicity)\n );\n\n if (customEthnicity) {\n checkedEthnicities?.push(\"OTH\");\n checkedEthnicities?.splice(checkedEthnicities?.indexOf(customEthnicity), 1);\n ethnicityInput.subEthnicity = customEthnicity;\n }\n onSubmit(ethnicityInput);\n};\n\nexport const getCheckedPatientEthnicitiesWithSubethnicity = (\n profileEthnicities: PatientEthnicityOutput | undefined\n): string[] => {\n const checkedEthnicities = profileEthnicities?.ethnicityTypes.map(\n (item) => item.code\n );\n if (profileEthnicities?.subEthnicity) {\n checkedEthnicities?.push(profileEthnicities?.subEthnicity);\n const othEthnicity = checkedEthnicities?.find((value) => value == \"OTH\");\n if (othEthnicity) {\n checkedEthnicities?.splice(checkedEthnicities.indexOf(othEthnicity), 1);\n }\n }\n return checkedEthnicities ? checkedEthnicities : [];\n};\n\nconst EthnicityForm: React.FC = ({\n profileEthnicities,\n defaultValue,\n onSubmit,\n goBack,\n loading,\n}) => {\n const intl = useIntl();\n const ethnicities = [\n {\n code: \"AFA\",\n description: intl.formatMessage(\n messages.ethnicityAfricanAmericanDescription\n ),\n descriptionForHeap: \"black\",\n },\n {\n code: \"HIS\",\n description: intl.formatMessage(messages.ethnicityHispanicDescription),\n descriptionForHeap: \"hispanic\",\n },\n {\n code: \"MED\",\n description: intl.formatMessage(\n messages.ethnicityMediterraneanDescription\n ),\n descriptionForHeap: \"mediterranean\",\n },\n {\n code: \"CAU\",\n description: intl.formatMessage(messages.ethnicityCaucasianDescription),\n descriptionForHeap: \"caucasian\",\n },\n {\n code: \"AJW\",\n description: intl.formatMessage(messages.ethnicityAshkenaziDescription),\n descriptionForHeap: \"ashkenazi_jewish\",\n },\n {\n code: \"SJW\",\n description: intl.formatMessage(messages.ethnicitySephardicDescription),\n descriptionForHeap: \"sephardic_jewish\",\n },\n {\n code: \"CAN\",\n description: intl.formatMessage(\n messages.ethnicityFrenchCanadianDescription\n ),\n descriptionForHeap: \"french_canadian\",\n },\n {\n code: \"EAS\",\n description: intl.formatMessage(messages.ethnicityEastAsianDescription),\n descriptionForHeap: \"east_asian\",\n },\n {\n code: \"SEA\",\n description: intl.formatMessage(\n messages.ethnicitySoutheastAsianDescription\n ),\n descriptionForHeap: \"southeast_asian\",\n },\n {\n code: \"SAS\",\n description: intl.formatMessage(messages.ethnicitySouthAsianDescription),\n descriptionForHeap: \"south_asian\",\n },\n ];\n\n const patientEthnicityCodes = getCheckedPatientEthnicitiesWithSubethnicity(\n profileEthnicities\n );\n\n const [checkedEthnicities, setCheckedEthnicities] = React.useState<\n string[] | undefined\n >(defaultValue ? defaultValue : patientEthnicityCodes);\n const isOtherEthnicities = (value: string) => {\n return !ethnicities.some((ethnicity) => ethnicity.code === value);\n };\n const { orderData } = React.useContext(OrderContext);\n const orderUidPublic = orderData?.orderUidPublic;\n const limsId = orderData?.clinic?.limsId;\n\n const ethnicityCheckboxes = ethnicities.map((ethnicity) => ({\n ...ethnicity,\n checked: checkedEthnicities?.includes(ethnicity.code),\n }));\n\n const controller: EthnicityController = {\n getEthnicities: () => ethnicityCheckboxes,\n isOtherEthnicities,\n };\n\n const handleCheckboxGroup = (values: string[]) =>\n setCheckedEthnicities(values);\n\n const getEthnicitiesForHeap = (\n checkedEthnicities: string[] | undefined,\n ethnicities: {\n code: string;\n description: string;\n descriptionForHeap: string;\n }[]\n ) => {\n if (!checkedEthnicities || checkedEthnicities.length === 0) {\n return \"noneselected\";\n }\n\n const checkedCode = checkedEthnicities.find((item) => item);\n const foundEthnicity = ethnicities.find(\n (ethnicity) => ethnicity.code === checkedCode\n );\n const description = foundEthnicity?.descriptionForHeap;\n\n return checkedEthnicities.length > 1\n ? \"more_than_one\"\n : checkedEthnicities.length === 1\n ? description\n : \"\";\n };\n\n const onSubmitCheckedEthnicities: React.FormEventHandler = (\n e\n ) => {\n e.preventDefault();\n submitEthnicities(onSubmit, checkedEthnicities, ethnicities);\n heap.track(HEAP_EVENTS.upp_simpleorder_ethinicity, {\n tests_ordered: getTestNameForHeap(orderData),\n lims_clinic_id: limsId,\n public_order_uid: orderUidPublic,\n ethnicity: getEthnicitiesForHeap(checkedEthnicities, ethnicities),\n });\n };\n\n return (\n \n );\n};\n\nexport default EthnicityForm;\n","import { StepperContent } from \"@app/components/ui/layout/stepperContent\";\nimport React, { useContext } from \"react\";\nimport EthnicityForm from \"./ethnicityForm/ethnicityForm\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { StepperContext } from \"@natera/stepper\";\nimport { NotificationContext, ProfileContext } from \"@app/provider\";\nimport StepperHeaderProgress from \"@app/components/stepperHeaderProgress\";\nimport { useNavigate } from \"react-router-dom\";\nimport { routes } from \"@app/routing\";\n\nexport interface Ethnicity {\n code: string;\n description: string;\n}\n\nexport interface PatientEthnicityOutput {\n ethnicityTypes: Ethnicity[];\n subEthnicity: string;\n}\n\nexport interface PatientEthnicityInput {\n codes: string[];\n subEthnicity?: string;\n}\n\nconst messages = defineMessages({\n selectEthnicityTitle: {\n id: \"selectEthnicityTitle\",\n defaultMessage: \"Select Ethnicity\",\n },\n selectEthnicityUpdateError: {\n id: \"selectEthnicityUpdateError\",\n defaultMessage: \"We're sorry. Something went wrong.\",\n },\n});\n\ninterface EthnicityStepProps {\n isInitialStep?: boolean;\n}\n\nconst EthnicityStep: React.FC = ({ isInitialStep }) => {\n const intl = useIntl();\n const navigate = useNavigate();\n\n const { addNotification } = useContext(NotificationContext);\n const { goBack, resolve, getData, getCurrentStep } = React.useContext(\n StepperContext\n );\n const {\n profileData,\n addPatientEthnicities,\n addPatientEthnicitiesIsLoading,\n } = React.useContext(ProfileContext);\n const profileEthnicities = profileData?.ethnicities;\n const currentStepId = getCurrentStep()?.stepId;\n const ethnicitiesToUpdate =\n currentStepId && getData(currentStepId)?.ethnicitiesToUpdate;\n if (\n ethnicitiesToUpdate?.codes &&\n Array.isArray(ethnicitiesToUpdate?.codes) &&\n ethnicitiesToUpdate?.codes.includes(\"OTH\")\n ) {\n ethnicitiesToUpdate?.codes.push(ethnicitiesToUpdate?.subEthnicity);\n ethnicitiesToUpdate?.codes.splice(\n ethnicitiesToUpdate?.codes.indexOf(\"OTH\"),\n 1\n );\n }\n const data = ethnicitiesToUpdate?.codes;\n\n const handleSubmit = async (ethnicitiesToUpdate: PatientEthnicityInput) => {\n try {\n await addPatientEthnicities({\n uid: profileData?.uid ? profileData?.uid : \"\",\n ethnicities: ethnicitiesToUpdate,\n });\n resolve({\n ethnicitiesToUpdate,\n });\n } catch (error) {\n addNotification({\n message: intl.formatMessage(messages.selectEthnicityUpdateError),\n type: \"error\",\n });\n }\n };\n\n const handleNext = (value: PatientEthnicityInput) => handleSubmit(value);\n\n const routerBack = () => {\n window.history.length > 1 ? navigate(-1) : navigate(routes.home);\n };\n\n const handleBack = () => {\n isInitialStep ? routerBack() : goBack();\n };\n\n return (\n <>\n \n \n \n \n >\n );\n};\n\nexport default EthnicityStep;\n","export { default } from \"./sentEmailAfterUnlockView\";\n","import * as React from \"react\";\nimport { FC } from \"react\";\nimport Email from \"@assets/svg/icons/email.svg\";\nimport { HeapPHIDecorator } from \"@app/components/analytics\";\nimport { maskEmail } from \"@app/utils\";\nimport { Button } from \"@natera/material/lib/button\";\nimport { Link } from \"react-router-dom\";\nimport { SpinnerView } from \"@app/components\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport Svg from \"@natera/material/lib/svg\";\nimport { Form, LinkButton } from \"@natera/form\";\n\nimport \"./sentEmailAfterUnlockView.scss\";\n\nconst messages = defineMessages({\n sentEmailAfterUnlockViewCheckMail: {\n id: \"sentEmailAfterUnlockViewCheckMail\",\n defaultMessage: \"Check your mail\",\n },\n sentEmailAfterUnlockViewInstructions: {\n id: \"sentEmailAfterUnlockViewInstructions\",\n defaultMessage:\n \"We have sent password recovery instructions to your email.\",\n },\n sentEmailAfterUnlockViewValidLink: {\n id: \"sentEmailAfterUnlockViewValidLink\",\n defaultMessage: \"The link is valid only for {time} minutes.\",\n },\n sentEmailAfterUnlockViewResendResetLinkButton: {\n id: \"sentEmailAfterUnlockViewResendResetLinkButton\",\n defaultMessage: \"Resend Reset Link\",\n },\n sentEmailAfterUnlockViewDone: {\n id: \"sentEmailAfterUnlockViewDone\",\n defaultMessage: \"Done\",\n },\n sentEmailAfterUnlockViewCheckSpam: {\n id: \"sentEmailAfterUnlockViewCheckSpam\",\n defaultMessage:\n \"Did not receive the email? Check your spam filter,{br} or {link}\",\n },\n sentEmailAfterUnlockViewTryAnotherEmail: {\n id: \"sentEmailAfterUnlockViewTryAnotherEmail\",\n defaultMessage: \"Try another email address\",\n },\n});\n\ninterface SentEmailAfterUnlockViewProps {\n email: string;\n handleResendEmail: () => void;\n resendIsDisabled: boolean;\n isLoading: boolean;\n tryAnotherEmailLink: string;\n handleTryAnotherEmail?: () => void;\n}\n\nconst SentEmailAfterUnlockView: FC = ({\n email,\n handleResendEmail,\n resendIsDisabled,\n isLoading,\n tryAnotherEmailLink,\n handleTryAnotherEmail,\n}) => {\n const intl = useIntl();\n\n const handleSubmit: React.FormEventHandler = (e) => {\n e.preventDefault();\n handleResendEmail();\n };\n\n return (\n \n
\n \n
\n
\n
\n {intl.formatMessage(messages.sentEmailAfterUnlockViewCheckMail)}\n
\n\n
\n {intl.formatMessage(messages.sentEmailAfterUnlockViewInstructions)}\n
\n\n
\n \n {maskEmail(email || \"\")}\n \n
\n\n
\n {intl.formatMessage(messages.sentEmailAfterUnlockViewValidLink, {\n time: \"60\",\n })}\n
\n
\n
\n\n
\n {intl.formatMessage(messages.sentEmailAfterUnlockViewCheckSpam, {\n br:
,\n link: (\n \n {intl.formatMessage(\n messages.sentEmailAfterUnlockViewTryAnotherEmail\n )}\n \n ),\n })}\n
\n\n
\n
\n );\n};\n\nexport default SentEmailAfterUnlockView;\n","export { default, messages } from \"./setupProfileReviewInfo\";\n","import React, { FC } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { InfoCard, InfoCardField } from \"@app/components\";\nimport { SetupProfileData } from \"@app/provider/profile/types\";\nimport { Button, Form } from \"@natera/form\";\nimport { convertPhoneNumberToDisplayValue } from \"@app/utils/convertPhoneNumber\";\nimport \"./setupProfileReviewInfo.scss\";\n\nexport const messages = defineMessages({\n setupProfileReviewInfoFirstName: {\n id: \"setupProfileReviewInfoFirstName\",\n defaultMessage: \"First Name\",\n },\n setupProfileReviewInfoMiddleName: {\n id: \"setupProfileReviewInfoMiddleName\",\n defaultMessage: \"Middle Name\",\n },\n setupProfileReviewInfoLastName: {\n id: \"setupProfileReviewInfoLastName\",\n defaultMessage: \"Last Name\",\n },\n setupProfileReviewInfoAlternateLastName: {\n id: \"setupProfileReviewInfoAlternateLastName\",\n defaultMessage: \"Alternate Last Name (Optional)\",\n },\n setupProfileReviewInfoDateOfBirth: {\n id: \"setupProfileReviewInfoDateOfBirth\",\n defaultMessage: \"Date of Birth\",\n },\n setupProfileReviewInfoMobileNumber: {\n id: \"setupProfileReviewInfoMobileNumber\",\n defaultMessage: \"Mobile Number\",\n },\n setupProfileReviewInfoZipCode: {\n id: \"setupProfileReviewInfoZipCode\",\n defaultMessage: \"Zip Code\",\n },\n setupProfileReviewInfoNotApplicable: {\n id: \"setupProfileReviewInfoNotApplicable\",\n defaultMessage: \"Not Applicable\",\n },\n setupProfileReviewInfoEditBtn: {\n id: \"setupProfileReviewInfoEditBtn\",\n defaultMessage: \"Edit\",\n },\n setupProfileReviewInfoConfirmBtn: {\n id: \"setupProfileReviewInfoConfirmBtn\",\n defaultMessage: \"Confirm\",\n },\n});\n\ninterface SetupProfileReviewInfoProps {\n profileData: SetupProfileData;\n onEdit: () => void;\n onSubmit: () => void;\n isLoading?: boolean;\n}\n\nconst SetupProfileReviewInfo: FC = ({\n profileData,\n onEdit,\n onSubmit,\n isLoading,\n}) => {\n const intl = useIntl();\n\n const displayDateOfBirth = () => {\n const dOB = profileData.dateOfBirth;\n return dOB\n ? new Date(dOB).toLocaleDateString(\"en-US\", {\n timeZone: \"UTC\",\n month: \"long\",\n day: \"numeric\",\n year: \"numeric\",\n })\n : \"\";\n };\n\n const displayZipCode = () =>\n profileData.addresses?.length ? profileData.addresses[0].zipCode : \"\";\n\n const handleSubmit: React.FormEventHandler = (e) => {\n e.preventDefault();\n onSubmit();\n };\n\n return (\n \n );\n};\n\nexport default SetupProfileReviewInfo;\n","import React, { FC, useContext, useEffect } from \"react\";\nimport classNames from \"classnames\";\nimport { useIntl, defineMessages } from \"react-intl\";\n\nimport { useDialog } from \"@natera/platform/lib/hooks\";\nimport { Button } from \"@natera/form\";\nimport { Svg } from \"@natera/material/lib/svg\";\nimport { CredentialsIdentityProvider } from \"@natera/platform/lib/service/session\";\nimport GoogleLogoSvg from \"@assets/svg/google-logo.svg\";\nimport AppleLogoSvg from \"@assets/svg/apple-logo.svg\";\nimport {\n ServiceContext,\n ConfigContext,\n UppAuthContext,\n UserContext,\n NotificationContext,\n} from \"@app/provider\";\nimport { ResultCodes } from \"@app/service/resultCodes\";\nimport AcknowledgementsDialog from \"../acknowledgmentsDialog\";\nimport \"./signInWithAuthenticationProviders.scss\";\nimport { PatientPortalUser } from \"@app/service/session\";\nimport { IDP_TYPE } from \"@app/service/user\";\nimport { HEAP_EVENTS } from \"@app/provider/types\";\nimport { LinkSource } from \"@app/hooks/useTokenizedLinks\";\nimport HighlightWrapper from \"../highlightWrapper/highlightWrapper\";\nimport {\n getLoginMethodFromCookie,\n saveLoginMethodToCookie,\n} from \"@app/utils/cookiesHelper\";\nimport { Link } from \"react-router-dom\";\nimport { routes } from \"@app/routing\";\nimport { ACKNOWLEDGMENT_FLOW } from \"../acknowledgmentsDialog/acknowledgmentsDialog\";\nimport { LoginStatus } from \"@app/provider/user\";\n\nconst messages = defineMessages({\n signInWithAuthenticationProvidersContinueWithGoogle: {\n id: \"signInWithAuthenticationProvidersContinueWithGoogle\",\n defaultMessage: \"Continue with Google\",\n },\n signInWithAuthenticationProvidersContinueWithApple: {\n id: \"signInWithAuthenticationProvidersContinueWithApple\",\n defaultMessage: \"Continue with Apple\",\n },\n highlightedTooltipDescriptionGoogle: {\n id: \"highlightedTooltipDescriptionGoogle\",\n defaultMessage: \"You previously logged in with your Google account.\",\n },\n highlightedTooltipDescriptionApple: {\n id: \"highlightedTooltipDescriptionApple\",\n defaultMessage: \"You previously logged in with your Apple account.\",\n },\n signInWithAuthenticationProvidersUserExistedNotification: {\n id: \"signInWithAuthenticationProvidersUserExistedNotification\",\n defaultMessage: \"This email address is already in use.\",\n },\n signInWithAuthenticationProvidersSignInTitle: {\n id: \"signInWithAuthenticationProvidersSignInTitle\",\n defaultMessage: \"Log In\",\n },\n signInWithAuthenticationProvidersUnrecognizedError: {\n id: \"signInWithAuthenticationProvidersUnrecognizedError\",\n defaultMessage: \"We're sorry. Something went wrong.\",\n },\n});\n\ninterface SignInWithIdentityProvidersProps {\n className?: string;\n invite: string | null;\n tokenSource?: LinkSource;\n isSignInFlow?: boolean;\n}\n\nconst SignInWithIdentityProviders: FC = ({\n className,\n invite,\n tokenSource,\n isSignInFlow,\n}) => {\n const intl = useIntl();\n\n const { clear, addNotification } = useContext(NotificationContext);\n const { sessionService } = useContext(ServiceContext);\n const { config } = useContext(ConfigContext);\n const {\n startSignInByAuthenticationProvider,\n endSignInByAuthenticationProvider,\n logout,\n signInByAuthenticationProviderInProgress,\n } = useContext(UppAuthContext);\n const {\n uppUserError,\n uppUser,\n deletedUserData,\n loadProfile,\n createUser,\n createUserError,\n resetCreateUserError,\n logUserLogin,\n } = useContext(UserContext);\n\n const acknowdledgementsDialog = useDialog(AcknowledgementsDialog);\n\n const handleAgreeAcknowledgements = (\n currentUser: PatientPortalUser\n ) => async () => {\n try {\n await createUser({\n oktaUID: currentUser.uid,\n email: currentUser.sub,\n invite,\n });\n\n await loadProfile();\n } finally {\n acknowdledgementsDialog.close();\n endSignInByAuthenticationProvider();\n }\n };\n\n const handleCloseAcknowledgementsDialog = async () => {\n await logout();\n acknowdledgementsDialog.close();\n endSignInByAuthenticationProvider();\n };\n\n useEffect(() => {\n if (uppUserError) {\n sessionService.getUserData().then((value) => {\n if (\n uppUserError.find(\n (e) => e.code === ResultCodes.USER_NOT_FOUND_ERROR\n ) &&\n value\n ) {\n acknowdledgementsDialog.open({\n userEmail: value.email,\n onAgreeAcknowledgements: handleAgreeAcknowledgements(value),\n onCloseDialog: () => handleCloseAcknowledgementsDialog(),\n flow: ACKNOWLEDGMENT_FLOW.ACCOUNT,\n });\n }\n });\n }\n\n if (createUserError) {\n switch (createUserError) {\n case ResultCodes.USER_ALREADY_CREATED_ERROR: {\n addNotification({\n title: intl.formatMessage(\n messages.signInWithAuthenticationProvidersUserExistedNotification\n ),\n message: (\n \n {intl.formatMessage(\n messages.signInWithAuthenticationProvidersSignInTitle\n )}\n \n ),\n type: \"error\",\n });\n\n break;\n }\n\n default: {\n addNotification({\n type: \"error\",\n message: intl.formatMessage(\n messages.signInWithAuthenticationProvidersUnrecognizedError\n ),\n });\n }\n }\n resetCreateUserError();\n }\n }, [uppUserError, createUserError]);\n\n const sendTokenizedOrOrganicHeapEvent = async (\n invite: string | null,\n tokenizedEventName: HEAP_EVENTS,\n organicEventName: HEAP_EVENTS,\n method: IDP_TYPE\n ) => {\n if (invite) {\n heap.track(tokenizedEventName, {\n method,\n source: tokenSource,\n });\n } else {\n heap.track(organicEventName, { method });\n }\n };\n\n useEffect(() => {\n const processSignInSuccess = async () => {\n if (uppUser) {\n endSignInByAuthenticationProvider();\n\n if (signInByAuthenticationProviderInProgress) {\n await logUserLogin(\n uppUser.email,\n LoginStatus.SUCCESS,\n invite,\n uppUser.idpType\n );\n }\n }\n };\n\n processSignInSuccess();\n }, [uppUser]);\n\n useEffect(() => {\n if (deletedUserData?.success) {\n window.location.reload();\n }\n }, []);\n\n const handleAuth = async (\n credentials: CredentialsIdentityProvider,\n idp: IDP_TYPE\n ) => {\n clear();\n try {\n if (await sessionService.getToken()) {\n await sessionService.clearToken();\n }\n\n startSignInByAuthenticationProvider();\n await sessionService.loginIdentityProvider(credentials);\n saveLoginMethodToCookie(idp);\n await loadProfile();\n } catch (error) {\n await sendTokenizedOrOrganicHeapEvent(\n invite,\n HEAP_EVENTS.upp_tokenizedlogin_failure,\n HEAP_EVENTS.upp_organiclogin_failure,\n idp\n );\n console.error(error);\n }\n };\n\n const isHighlightedGoogle =\n IDP_TYPE.GOOGLE === getLoginMethodFromCookie() && !!isSignInFlow;\n const isHighlightedApple =\n IDP_TYPE.APPLE === getLoginMethodFromCookie() && !!isSignInFlow;\n\n return (\n \n {acknowdledgementsDialog.getDialog()}\n \n \n \n \n \n \n \n \n );\n};\n\nexport default SignInWithIdentityProviders;\n","export { default } from \"./SignInWithAuthenticationProviders\";\n","import React, { FC } from \"react\";\nimport \"./acknowledgmentContent.scss\";\n\ntype AcknowledgmentContentProps = {\n children: React.ReactNode;\n actions: React.ReactNode;\n checkbox?: React.ReactNode;\n};\n\nconst AcknowledgmentContent: FC = ({\n children,\n actions,\n checkbox,\n}) => {\n return (\n \n \n {children}\n
\n {checkbox}\n {actions}
\n \n );\n};\n\nexport default AcknowledgmentContent;\n","export { default as PaymentMethodForm } from \"./paymentMethodForm\";\nexport { default as PaymentMethodStep } from \"./paymentMethodStep\";\n","import { PaymentMethodSelector } from \"@app/components/paymentMethod\";\nimport {\n PaymentType,\n PaymentTypeForHeap,\n SubSteps,\n} from \"@app/pages/private/simpleOrder/paymentMethod/paymentMethod\";\nimport { Button, Form } from \"@natera/form\";\nimport { StepperContext } from \"@natera/stepper\";\nimport React, { useContext, useEffect } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { GovernmentStep } from \"./steps/selectGovernment\";\nimport { CommercialStep } from \"./steps/selectCommercial\";\nimport { MultipleInsurancesFirstStep } from \"./steps/multipleInsurances\";\nimport { SelfPayStep } from \"@app/components/simpleOrder/payment/steps\";\nimport { HEAP_EVENTS } from \"@app/provider/types\";\nimport { getTestNameForHeap } from \"@app/utils\";\nimport { OrderContext } from \"@app/provider/order\";\nimport { Steps } from \"@app/pages/private/simpleOrder\";\nimport {\n PaymentMethodType,\n SimpleOrderStepperContext,\n} from \"@app/provider/simpleOrder/SimpleOrderStepperProvider\";\n\nconst messages = defineMessages({\n paymentMethodHeaderTitle: {\n id: \"paymentMethodHeaderTitle\",\n defaultMessage: \"Payment Method\",\n },\n paymentMethodHeaderSubTitle: {\n id: \"paymentMethodHeaderSubTitle\",\n defaultMessage: \"Which situation best describes you?\",\n },\n paymentMethodHeaderText: {\n id: \"paymentMethodHeaderText\",\n defaultMessage: \"Select the payment method that works best for you.\",\n },\n paymentMethodButtonNext: {\n id: \"paymentMethodButtonNext\",\n defaultMessage: \"Next\",\n },\n paymentMethodButtonBack: {\n id: \"paymentMethodButtonBack\",\n defaultMessage: \"Back\",\n },\n});\n\ntype Props = {\n onConfirm: (data: unknown) => void;\n goBack: () => void;\n};\n\nconst PaymentMethodForm: React.FC = ({ onConfirm, goBack }) => {\n const intl = useIntl();\n const {\n resetStep,\n resolve,\n getData,\n createStep,\n removeStep,\n } = React.useContext(StepperContext);\n\n const { getSubStepData, resolveSubStep } = useContext(\n SimpleOrderStepperContext\n );\n\n const data = getData(SubSteps.SELECT_METHOD);\n const { orderData } = React.useContext(OrderContext);\n const orderUidPublic = orderData?.orderUidPublic;\n const limsId = orderData?.clinic?.limsId;\n\n const subStepData = getSubStepData(Steps.PAYMENT_METHOD);\n\n const [selectedPaymentType, setSelectedPaymentType] = React.useState<\n PaymentType | undefined\n >((subStepData as PaymentMethodType)?.paymentMethod ?? data?.paymentMethod);\n\n const paymentTypeHeap = () => {\n switch (selectedPaymentType) {\n case PaymentType.COMMERCIAL:\n return PaymentTypeForHeap.COMMERCIAL;\n case PaymentType.GOVERNMENT_ISSUED:\n return PaymentTypeForHeap.GOVERNMENT;\n case PaymentType.MULTIPLE:\n return PaymentTypeForHeap.TWO_INSURANCES;\n case PaymentType.DO_NOT_HAVE:\n return PaymentTypeForHeap.NO_INSURANCE;\n case PaymentType.SELF_PAY:\n return PaymentTypeForHeap.DONT_USE_INSURANCE;\n }\n };\n\n useEffect(() => {\n if (selectedPaymentType) {\n addSteps(selectedPaymentType);\n }\n }, []);\n\n const addSteps = (paymentMethod: PaymentType) => {\n if (paymentMethod === PaymentType.COMMERCIAL) {\n createStep(SubSteps.SELECT_COMMERCIAL_COMPANY, {\n index: 1,\n children: ,\n });\n }\n\n if (paymentMethod === PaymentType.GOVERNMENT_ISSUED) {\n createStep(SubSteps.SELECT_GOVERNMENT_COMPANY, {\n index: 1,\n children: ,\n });\n }\n\n if (paymentMethod === PaymentType.MULTIPLE) {\n createStep(SubSteps.MULTIPLE_FIRST, {\n index: 1,\n children: ,\n });\n }\n\n if (paymentMethod === PaymentType.DO_NOT_HAVE) {\n createStep(SubSteps.DO_NOT_HAVE, {\n index: 1,\n children: (\n \n ),\n });\n }\n\n if (paymentMethod === PaymentType.SELF_PAY) {\n createStep(SubSteps.SELF_PAY, {\n index: 1,\n children: (\n \n ),\n });\n }\n };\n\n const removesSteps = () => {\n const subStepsForRemove = Object.values(SubSteps).filter(\n (key) => key !== SubSteps.SELECT_METHOD\n );\n\n subStepsForRemove.forEach((subStepKey) => removeStep(subStepKey));\n };\n\n const handleSelectPaymentType = (paymentMethod: PaymentType) => {\n removesSteps();\n addSteps(paymentMethod);\n\n setSelectedPaymentType(paymentMethod);\n };\n\n const handleSubmit: React.FormEventHandler = (event) => {\n event.preventDefault();\n\n const data: PaymentMethodType = { paymentMethod: selectedPaymentType };\n\n if (\n subStepData &&\n selectedPaymentType !== (subStepData as PaymentMethodType)?.paymentMethod\n ) {\n data.paymentMethodInfo = undefined;\n }\n\n resolveSubStep({ stepId: Steps.PAYMENT_METHOD, subStepData: data });\n resolve(data);\n\n heap.track(HEAP_EVENTS.upp_simpleorder_payment, {\n tests_ordered: getTestNameForHeap(orderData),\n lims_clinic_id: limsId,\n public_order_uid: orderUidPublic,\n payment_type: paymentTypeHeap(),\n });\n };\n\n const handleBack = () => {\n resetStep(SubSteps.SELECT_METHOD);\n goBack();\n };\n\n return (\n \n );\n};\n\nexport default PaymentMethodForm;\n","import React from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { PaymentMethodForm } from \"@app/components/simpleOrder/payment\";\nimport { StepperContent } from \"@app/components/ui/layout/stepperContent\";\n\nconst messages = defineMessages({\n paymentMethodStepHeaderTitle: {\n id: \"paymentMethodStepHeaderTitle\",\n defaultMessage: \"Payment Method\",\n },\n paymentMethodStepHeaderSubTitle: {\n id: \"paymentMethodStepHeaderSubTitle\",\n defaultMessage: \"Which situation best describes you?\",\n },\n paymentMethodStepHeaderText: {\n id: \"paymentMethodStepHeaderText\",\n defaultMessage: \"Select the payment method that works best for you.\",\n },\n});\n\ntype Props = {\n onSubmit: (data: unknown) => void;\n goBack: () => void;\n};\n\nconst PaymentMethodStep: React.FC = ({ onSubmit, goBack }) => {\n const intl = useIntl();\n\n return (\n \n \n \n );\n};\n\nexport default PaymentMethodStep;\n","import PayorsTypeAhead from \"@app/components/payorsTypeAhead\";\nimport { PayorProvider } from \"@app/provider\";\nimport { Payor } from \"@app/provider/payor\";\nimport { Button, Form, FormField } from \"@natera/form\";\nimport { StepperContext } from \"@natera/stepper\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport React, { useContext } from \"react\";\nimport { payorFieldId } from \"@app/components/payorsTypeAhead/payorsTypeAhead\";\nimport { useErrorController } from \"@natera/platform/lib/hooks\";\n\nimport \"./enterOtherInsuranceCompanyForm.scss\";\nimport {\n MultiplePaymentMethodType,\n PaymentMethodType,\n SimpleOrderStepperContext,\n} from \"@app/provider/simpleOrder/SimpleOrderStepperProvider\";\nimport { Steps } from \"@app/pages/private/simpleOrder\";\nimport {\n getPaymentMethodInfoSubStepsData,\n isCommercialOrGovernmentInsuranceFirst,\n isCommercialOrGovernmentInsuranceSecond,\n} from \"@app/utils\";\n\nconst messages = defineMessages({\n enterOtherInsuranceCompanyFormPayorFieldTitle: {\n id: \"enterOtherInsuranceCompanyFormPayorFieldTitle\",\n defaultMessage: \"Enter insurance company if not listed\",\n },\n enterOtherInsuranceCompanyFormPayorFieldError: {\n id: \"enterOtherInsuranceCompanyFormPayorFieldError\",\n defaultMessage: \"This information is required.\",\n },\n enterOtherInsuranceCompanyFormButtonNext: {\n id: \"enterOtherInsuranceCompanyFormButtonNext\",\n defaultMessage: \"Next\",\n },\n enterOtherInsuranceCompanyFormButtonBack: {\n id: \"enterOtherInsuranceCompanyFormButtonBack\",\n defaultMessage: \"Back\",\n },\n insuranceCompanyOtherText: {\n id: \"insuranceCompanyOtherText\",\n defaultMessage: \"Other\",\n },\n});\n\ntype Props = {\n onSubmit: (company: Payor) => void;\n goBack: () => void;\n};\n\nconst EnterOtherInsuranceCompanyForm: React.FC = ({\n onSubmit,\n goBack,\n}) => {\n const intl = useIntl();\n const errorController = useErrorController();\n const { getCurrentStep } = React.useContext(StepperContext);\n\n const { getSubStepData } = useContext(SimpleOrderStepperContext);\n\n const subStepsData = getSubStepData(Steps.PAYMENT_METHOD) as\n | PaymentMethodType\n | MultiplePaymentMethodType;\n\n const currentStepId = getCurrentStep()?.stepId;\n\n const isInsuranceFirstStep = isCommercialOrGovernmentInsuranceFirst(\n currentStepId\n );\n const isInsuranceSecondStep = isCommercialOrGovernmentInsuranceSecond(\n currentStepId\n );\n\n const getInitialPayor = () => {\n const data = getPaymentMethodInfoSubStepsData(\n subStepsData,\n isInsuranceFirstStep,\n isInsuranceSecondStep\n );\n\n if (!data?.otherCompanyName || !data?.otherCompanyGroupId) {\n return undefined;\n }\n\n return {\n displayName: data.otherCompanyName,\n groupId: data.otherCompanyGroupId,\n };\n };\n\n const [selectedPayor, setSelectedPayor] = React.useState(\n getInitialPayor()\n );\n\n const handleSubmit: React.FormEventHandler = (event) => {\n event.preventDefault();\n\n if (!selectedPayor) {\n errorController.setValidationError(\n payorFieldId,\n intl.formatMessage(\n messages.enterOtherInsuranceCompanyFormPayorFieldError\n )\n );\n return;\n }\n\n onSubmit(selectedPayor);\n };\n\n return (\n \n );\n};\n\nexport default EnterOtherInsuranceCompanyForm;\n","export { default as EnterOtherInsuranceCompanyForm } from \"./enterOtherInsuranceCompanyForm\";\n","import { StepId, StepperContext } from \"@natera/stepper\";\nimport React, { useContext } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { EnterOtherInsuranceCompanyForm } from \"../enterOtherInsuranceCompanyStep/enterOtherInsuranceCompanyForm\";\nimport { StepperContent } from \"@app/components/ui/layout/stepperContent\";\nimport { SubSteps } from \"@app/pages/private/simpleOrder/paymentMethod/paymentMethod\";\nimport { Payor } from \"@app/provider/payor\";\nimport {\n MultiplePaymentMethodType,\n SimpleOrderStepperContext,\n} from \"@app/provider/simpleOrder/SimpleOrderStepperProvider\";\nimport { Steps } from \"@app/pages/private/simpleOrder\";\nimport {\n isCommercialOrGovernmentInsuranceFirst,\n isCommercialOrGovernmentInsuranceSecond,\n} from \"@app/utils\";\n\nconst messages = defineMessages({\n enterOtherInsuranceCompanyStepHeaderTitle: {\n id: \"enterOtherInsuranceCompanyStepHeaderTitle\",\n defaultMessage: \"Payment Method\",\n },\n enterOtherCommercialStepHeaderSubTitle: {\n id: \"enterOtherCommercialStepHeaderSubTitle\",\n defaultMessage: \"Enter insurance company\",\n },\n enterOtherGovernmentStepHeaderSubTitle: {\n id: \"enterOtherGovernmentStepHeaderSubTitle\",\n defaultMessage: \"Enter government-issued insurance information\",\n },\n});\n\ninterface Props {\n previousStepId?: StepId;\n}\n\nconst EnterOtherInsuranceCompanyStep: React.FC = ({\n previousStepId = SubSteps.SELECT_COMMERCIAL_COMPANY,\n}) => {\n const intl = useIntl();\n const { goAt, resolve, getCurrentStep } = React.useContext(StepperContext);\n\n const currentStepId = getCurrentStep()?.stepId;\n\n const { getSubStepData, resolveSubStep } = useContext(\n SimpleOrderStepperContext\n );\n const subStepsData = getSubStepData(Steps.PAYMENT_METHOD);\n\n const isInsuranceFirstStep = isCommercialOrGovernmentInsuranceFirst(\n currentStepId\n );\n const isInsuranceSecondStep = isCommercialOrGovernmentInsuranceSecond(\n currentStepId\n );\n\n const governmentSteps = [\n SubSteps.ENTER_OTHER_GOVERNMENT_COMPANY,\n SubSteps.ENTER_OTHER_GOVERNMENT_COMPANY_FIRST,\n SubSteps.ENTER_OTHER_GOVERNMENT_COMPANY_SECOND,\n ];\n const subTitle =\n currentStepId && governmentSteps.includes(currentStepId as SubSteps)\n ? intl.formatMessage(messages.enterOtherGovernmentStepHeaderSubTitle)\n : intl.formatMessage(messages.enterOtherCommercialStepHeaderSubTitle);\n\n const handleSubmit = (company: Payor) => {\n const enterOtherStepData = {\n otherCompanyName: company.displayName,\n otherCompanyGroupId: company.groupId,\n };\n\n let subStepDataWithOtherCompany;\n\n if (isInsuranceFirstStep) {\n subStepDataWithOtherCompany = {\n paymentMethodInfo: {\n first: {\n paymentMethodInfo: {\n ...(subStepsData as MultiplePaymentMethodType)?.paymentMethodInfo\n ?.first?.paymentMethodInfo,\n ...enterOtherStepData,\n },\n },\n },\n };\n } else if (isInsuranceSecondStep) {\n subStepDataWithOtherCompany = {\n paymentMethodInfo: {\n second: {\n paymentMethodInfo: {\n ...(subStepsData as MultiplePaymentMethodType)?.paymentMethodInfo\n ?.second?.paymentMethodInfo,\n ...enterOtherStepData,\n },\n },\n },\n };\n } else {\n subStepDataWithOtherCompany = {\n paymentMethodInfo: {\n ...enterOtherStepData,\n },\n };\n }\n\n resolveSubStep({\n stepId: Steps.PAYMENT_METHOD,\n subStepData: subStepDataWithOtherCompany,\n });\n\n resolve(enterOtherStepData);\n };\n\n const handleBack = () => {\n goAt(previousStepId);\n };\n\n return (\n \n \n \n );\n};\n\nexport default EnterOtherInsuranceCompanyStep;\n","export { default as EnterOtherInsuranceCompanyStep } from \"./enterOtherInsuranceCompanyStep\";\n","export { SelfPayStep } from \"./selfPay\";\nexport { EnterOtherInsuranceCompanyStep } from \"./enterOtherInsuranceCompanyStep\";\nexport { CommercialStep } from \"./selectCommercial\";\nexport { GovernmentStep } from \"./selectGovernment\";\nexport {\n MultipleInsurancesFirstStep,\n MultipleInsurancesSecondStep,\n} from \"./multipleInsurances\";\nexport { ProvideCommercialStep } from \"./provideComercial\";\nexport { ProvideGovernmentStep } from \"./provideGovernment\";\nexport { InsuranceCostEstimationStep } from \"./insuranceCostEstimationStep\";\n","export { default as InsuranceCostEstimationStep } from \"./insuranceCostEstimationStep\";\n","import { StepperContext } from \"@natera/stepper\";\nimport React from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport { InsuranceCostEstimationForm } from \"@app/components/forms\";\nimport { StepperContent } from \"@app/components/ui/layout/stepperContent\";\nimport {\n Commercial,\n Government,\n PaymentInfo,\n PaymentType,\n SubSteps,\n MultipleInsuranceData,\n} from \"@app/pages/private/simpleOrder/paymentMethod/paymentMethod\";\n\nimport { PredefinedCompanyName } from \"@app/components/companySelector/companySelector\";\nimport {\n getDataFromMultipleFirstStep,\n getDataFromMultipleSecondStep,\n} from \"@app/components/simpleOrder/payment/steps/multipleInsurances/getDataFromMultipleSteps\";\n\nconst messages = defineMessages({\n insuranceCostEstimationStepHeaderTitle: {\n id: \"insuranceCostEstimationStepHeaderTitle\",\n defaultMessage: \"Payment Method\",\n },\n});\n\ninterface Props {\n onSubmit: (data: unknown) => void;\n}\n\nconst InsuranceCostEstimationStep: React.FC = ({ onSubmit }) => {\n const intl = useIntl();\n const { goBack, getData, getSteps } = React.useContext(StepperContext);\n\n const subSteps = getSteps();\n const stepIds = subSteps.map((step) => step.stepId);\n\n const isCommercialFlow = stepIds.includes(SubSteps.SELECT_COMMERCIAL_COMPANY);\n const isGovernmentFlow = stepIds.includes(SubSteps.SELECT_GOVERNMENT_COMPANY);\n const isMultipleFlow =\n stepIds.includes(SubSteps.SELECT_COMMERCIAL_COMPANY_SECOND) ||\n stepIds.includes(SubSteps.SELECT_GOVERNMENT_COMPANY_SECOND);\n\n const getCommercialCompanyData = () => {\n const companyStep = getData(SubSteps.SELECT_COMMERCIAL_COMPANY);\n let companyName: string = companyStep?.companyName;\n let companyGroupId: string = companyStep?.companyGroupId;\n\n if (companyName === PredefinedCompanyName.Other) {\n const otherCompanyStepData = getData(\n SubSteps.ENTER_OTHER_COMMERCIAL_COMPANY\n );\n companyName = otherCompanyStepData?.otherCompanyName;\n companyGroupId = otherCompanyStepData?.otherCompanyGroupId;\n }\n\n const memberId = getData(SubSteps.PROVIDE_COMMERCIAL_INSURANCE).memberId;\n\n const companyData: Commercial = {\n paymentMethod: PaymentType.COMMERCIAL,\n paymentMethodInfo: {\n companyName,\n memberId,\n companyGroupId,\n },\n };\n\n return companyData;\n };\n\n const getGovernmentCompanyData = () => {\n const companyStep = getData(SubSteps.SELECT_GOVERNMENT_COMPANY);\n let companyName: string = companyStep?.companyName;\n let companyGroupId: string = companyStep?.companyGroupId;\n\n if (companyName === PredefinedCompanyName.Other) {\n const otherCompanyStepData = getData(\n SubSteps.ENTER_OTHER_GOVERNMENT_COMPANY\n );\n companyName = otherCompanyStepData?.otherCompanyName;\n companyGroupId = otherCompanyStepData?.otherCompanyGroupId;\n }\n\n const insuranceNumber = getData(SubSteps.PROVIDE_GOVERNMENT_INSURANCE)\n .insuranceNumber;\n\n const companyData: Government = {\n paymentMethod: PaymentType.GOVERNMENT_ISSUED,\n paymentMethodInfo: {\n companyName,\n insuranceNumber,\n companyGroupId,\n },\n };\n\n return companyData;\n };\n\n const getInsuranceCompaniesData = () => {\n const companiesData: PaymentInfo[] = [];\n\n if (isCommercialFlow) {\n const companyData = getCommercialCompanyData();\n companiesData.push(companyData);\n }\n\n if (isGovernmentFlow) {\n const companyData = getGovernmentCompanyData();\n companiesData.push(companyData);\n }\n\n if (isMultipleFlow) {\n const firstCompanyData = getDataFromMultipleFirstStep(subSteps);\n const secondCompanyData = getDataFromMultipleSecondStep(subSteps);\n companiesData.push(firstCompanyData);\n companiesData.push(secondCompanyData);\n }\n\n return companiesData;\n };\n\n const getPaymentMethodData = () => {\n const companiesData = getInsuranceCompaniesData();\n const isMultipleInsurance = companiesData.length > 1;\n\n const paymentMethodResult = isMultipleInsurance\n ? ({\n paymentMethod: PaymentType.MULTIPLE,\n paymentMethodInfo: {\n first: companiesData[0],\n second: companiesData[1],\n },\n } as MultipleInsuranceData)\n : companiesData[0];\n\n return paymentMethodResult;\n };\n\n const handleBack = () => {\n goBack();\n };\n\n return (\n \n \n \n );\n};\n\nexport default InsuranceCostEstimationStep;\n","import { MultipleInsurance } from \"@app/components/ui/inputs/multipleInsurancesSelector/multipleInsurancesSelector\";\nimport {\n SubSteps,\n PaymentInfo,\n PaymentType,\n} from \"@app/pages/private/simpleOrder/paymentMethod/paymentMethod\";\nimport { StepState, StepId, StepData } from \"@natera/stepper\";\nimport { PredefinedCompanyName } from \"@app/components/companySelector/companySelector\";\n\nexport const getDataFromMultipleFirstStep = (\n steps: StepState[]\n): PaymentInfo => {\n const stepsMap: Record = {};\n steps.forEach((step) => {\n stepsMap[step.stepId] = step.data;\n });\n if (stepsMap[SubSteps.MULTIPLE_FIRST] === MultipleInsurance.Government) {\n const companyName =\n stepsMap[SubSteps.SELECT_GOVERNMENT_COMPANY_FIRST].companyName ===\n PredefinedCompanyName.Other\n ? stepsMap[SubSteps.ENTER_OTHER_GOVERNMENT_COMPANY_FIRST]\n .otherCompanyName\n : stepsMap[SubSteps.SELECT_GOVERNMENT_COMPANY_FIRST].companyName;\n\n const companyGroupId =\n stepsMap[SubSteps.SELECT_GOVERNMENT_COMPANY_FIRST].companyName ===\n PredefinedCompanyName.Other\n ? stepsMap[SubSteps.ENTER_OTHER_GOVERNMENT_COMPANY_FIRST]\n .otherCompanyGroupId\n : stepsMap[SubSteps.SELECT_GOVERNMENT_COMPANY_FIRST].companyGroupId;\n\n return {\n paymentMethod: PaymentType.GOVERNMENT_ISSUED,\n paymentMethodInfo: {\n companyName,\n insuranceNumber:\n stepsMap[SubSteps.PROVIDE_GOVERNMENT_INSURANCE_FIRST].insuranceNumber,\n companyGroupId,\n },\n };\n } else {\n const companyName =\n stepsMap[SubSteps.SELECT_COMMERCIAL_COMPANY_FIRST].companyName ===\n PredefinedCompanyName.Other\n ? stepsMap[SubSteps.ENTER_OTHER_COMMERCIAL_COMPANY_FIRST]\n .otherCompanyName\n : stepsMap[SubSteps.SELECT_COMMERCIAL_COMPANY_FIRST].companyName;\n\n const companyGroupId =\n stepsMap[SubSteps.SELECT_COMMERCIAL_COMPANY_FIRST].companyName ===\n PredefinedCompanyName.Other\n ? stepsMap[SubSteps.ENTER_OTHER_COMMERCIAL_COMPANY_FIRST]\n .otherCompanyGroupId\n : stepsMap[SubSteps.SELECT_COMMERCIAL_COMPANY_FIRST].companyGroupId;\n\n return {\n paymentMethod: PaymentType.COMMERCIAL,\n paymentMethodInfo: {\n companyName,\n memberId:\n stepsMap[SubSteps.PROVIDE_COMMERCIAL_INSURANCE_FIRST].memberId,\n companyGroupId,\n },\n };\n }\n};\n","import { MultipleInsurance } from \"@app/components/ui/inputs/multipleInsurancesSelector/multipleInsurancesSelector\";\nimport {\n SubSteps,\n PaymentInfo,\n PaymentType,\n} from \"@app/pages/private/simpleOrder/paymentMethod/paymentMethod\";\nimport { StepState, StepId, StepData } from \"@natera/stepper\";\nimport { PredefinedCompanyName } from \"@app/components/companySelector/companySelector\";\n\nexport const getDataFromMultipleSecondStep = (\n steps: StepState[]\n): PaymentInfo => {\n const stepsMap: Record = {};\n steps.forEach((step) => {\n stepsMap[step.stepId] = step.data;\n });\n\n if (stepsMap[SubSteps.MULTIPLE_SECOND] === MultipleInsurance.Government) {\n const companyName =\n stepsMap[SubSteps.SELECT_GOVERNMENT_COMPANY_SECOND].companyName ===\n PredefinedCompanyName.Other\n ? stepsMap[SubSteps.ENTER_OTHER_GOVERNMENT_COMPANY_SECOND]\n .otherCompanyName\n : stepsMap[SubSteps.SELECT_GOVERNMENT_COMPANY_SECOND].companyName;\n\n const companyGroupId =\n stepsMap[SubSteps.SELECT_GOVERNMENT_COMPANY_SECOND].companyName ===\n PredefinedCompanyName.Other\n ? stepsMap[SubSteps.ENTER_OTHER_GOVERNMENT_COMPANY_SECOND]\n .otherCompanyGroupId\n : stepsMap[SubSteps.SELECT_GOVERNMENT_COMPANY_SECOND].companyGroupId;\n\n return {\n paymentMethod: PaymentType.GOVERNMENT_ISSUED,\n paymentMethodInfo: {\n companyName,\n insuranceNumber:\n stepsMap[SubSteps.PROVIDE_GOVERNMENT_INSURANCE_SECOND]\n .insuranceNumber,\n companyGroupId,\n },\n };\n } else {\n const companyName =\n stepsMap[SubSteps.SELECT_COMMERCIAL_COMPANY_SECOND].companyName ===\n PredefinedCompanyName.Other\n ? stepsMap[SubSteps.ENTER_OTHER_COMMERCIAL_COMPANY_SECOND]\n .otherCompanyName\n : stepsMap[SubSteps.SELECT_COMMERCIAL_COMPANY_SECOND].companyName;\n\n const companyGroupId =\n stepsMap[SubSteps.SELECT_COMMERCIAL_COMPANY_SECOND].companyName ===\n PredefinedCompanyName.Other\n ? stepsMap[SubSteps.ENTER_OTHER_COMMERCIAL_COMPANY_SECOND]\n .otherCompanyGroupId\n : stepsMap[SubSteps.SELECT_COMMERCIAL_COMPANY_SECOND].companyGroupId;\n\n return {\n paymentMethod: PaymentType.COMMERCIAL,\n paymentMethodInfo: {\n companyName,\n memberId:\n stepsMap[SubSteps.PROVIDE_COMMERCIAL_INSURANCE_SECOND].memberId,\n companyGroupId,\n },\n };\n }\n};\n","export { getDataFromMultipleFirstStep } from \"./getDataFromMultipleFirstStep\";\nexport { getDataFromMultipleSecondStep } from \"./getDataFromMultipleSecondStep\";\n","export { default as MultipleInsurancesFirstStep } from \"./multipleInsurancesFirstStep\";\nexport { default as MultipleInsurancesSecondStep } from \"./multipleInsurancesSecondStep\";\n","import { MultipleInsurancesForm } from \"./multipleInsurancesForm\";\nimport { StepperContent } from \"@app/components/ui/layout\";\nimport { MultipleInsurance } from \"@app/components/ui/inputs/multipleInsurancesSelector/multipleInsurancesSelector\";\nimport {\n PaymentType,\n SubSteps,\n} from \"@app/pages/private/simpleOrder/paymentMethod/paymentMethod\";\nimport { StepperContext } from \"@natera/stepper\";\nimport React, { useContext, useEffect } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport {\n CommercialStep,\n GovernmentStep,\n} from \"@app/components/simpleOrder/payment/steps\";\nimport MultipleInsurancesSecondStep from \"./multipleInsurancesSecondStep\";\nimport {\n MultiplePaymentMethodType,\n PaymentMethodType,\n SimpleOrderStepperContext,\n} from \"@app/provider/simpleOrder/SimpleOrderStepperProvider\";\nimport { Steps } from \"@app/pages/private/simpleOrder\";\n\nconst messages = defineMessages({\n multipleInsurancesStepHeaderTitle: {\n id: \"multipleInsurancesStepHeaderTitle\",\n defaultMessage: \"Payment Method\",\n },\n multipleInsurancesStepHeaderSubTitle: {\n id: \"multipleInsurancesStepHeaderSubTitle\",\n defaultMessage: \"More than one insurance\",\n },\n multipleInsurancesStepHeaderTextFirstType: {\n id: \"multipleInsurancesStepHeaderTextFirstType\",\n defaultMessage:\n \"Select the first type of insurance that you would like to use to cover the cost of your test.\",\n },\n multipleInsurancesFormFirstInsurancesTitle: {\n id: \"multipleInsurancesFormFirstInsurancesTitle\",\n defaultMessage: \"First insurance type\",\n },\n});\n\ntype Props = {\n onConfirm: (data: unknown) => void;\n};\n\nconst MultipleInsurancesFirstStep: React.FC = ({ onConfirm }) => {\n const intl = useIntl();\n const {\n goBack,\n resolve,\n getData,\n createStep,\n removeStep,\n goAt,\n } = React.useContext(StepperContext);\n\n const stepData = getData(SubSteps.MULTIPLE_FIRST);\n\n const { getSubStepData, resolveSubStep } = useContext(\n SimpleOrderStepperContext\n );\n const subStepsData = getSubStepData(\n Steps.PAYMENT_METHOD\n ) as MultiplePaymentMethodType;\n\n const getSelectedInsurance = () => {\n const paymentMethod = subStepsData?.paymentMethodInfo?.first?.paymentMethod;\n if (paymentMethod === PaymentType.COMMERCIAL) {\n return MultipleInsurance.Commercial;\n } else if (paymentMethod === PaymentType.GOVERNMENT_ISSUED) {\n return MultipleInsurance.Government;\n }\n return stepData;\n };\n\n const [selectedInsurance, setSelectedInsurance] = React.useState<\n MultipleInsurance | undefined\n >(getSelectedInsurance());\n\n useEffect(() => {\n if (selectedInsurance) {\n handleSelectInsurance(selectedInsurance);\n }\n }, []);\n\n const resolveMultipleFirst = () => {\n createStep(SubSteps.MULTIPLE_SECOND, {\n children: ,\n data: undefined,\n index: 5,\n });\n\n goAt(SubSteps.MULTIPLE_SECOND);\n };\n\n const addSteps = (insurance: MultipleInsurance) => {\n if (insurance === MultipleInsurance.Commercial) {\n createStep(SubSteps.SELECT_COMMERCIAL_COMPANY_FIRST, {\n children: ,\n index: 2,\n });\n } else {\n createStep(SubSteps.SELECT_GOVERNMENT_COMPANY_FIRST, {\n children: ,\n index: 2,\n });\n }\n };\n\n const removeSteps = (insurance: MultipleInsurance | undefined) => {\n if (insurance === MultipleInsurance.Commercial) {\n removeStep(SubSteps.SELECT_COMMERCIAL_COMPANY_FIRST);\n removeStep(SubSteps.PROVIDE_COMMERCIAL_INSURANCE_FIRST);\n removeStep(SubSteps.ENTER_OTHER_COMMERCIAL_COMPANY_FIRST);\n }\n if (insurance === MultipleInsurance.Government) {\n removeStep(SubSteps.SELECT_GOVERNMENT_COMPANY_FIRST);\n removeStep(SubSteps.PROVIDE_GOVERNMENT_INSURANCE_FIRST);\n removeStep(SubSteps.ENTER_OTHER_GOVERNMENT_COMPANY_FIRST);\n }\n\n removeStep(SubSteps.MULTIPLE_SECOND);\n };\n\n const handleSelectInsurance = (insurance: MultipleInsurance) => {\n removeSteps(selectedInsurance);\n addSteps(insurance);\n\n setSelectedInsurance(insurance);\n };\n\n const handleSubmit = (insurance: string) => {\n const paymentMethod =\n insurance === MultipleInsurance.Commercial\n ? PaymentType.COMMERCIAL\n : PaymentType.GOVERNMENT_ISSUED;\n\n const paymentMethodInfoFirst: PaymentMethodType = { paymentMethod };\n\n if (subStepsData?.paymentMethodInfo?.first?.paymentMethod !== paymentMethod)\n paymentMethodInfoFirst.paymentMethodInfo = undefined;\n\n resolveSubStep({\n stepId: Steps.PAYMENT_METHOD,\n subStepData: {\n paymentMethodInfo: { first: { ...paymentMethodInfoFirst } },\n },\n });\n resolve(insurance);\n };\n\n const handleBack = () => {\n goBack();\n };\n\n return (\n {chunks} }\n )}\n >\n \n \n );\n};\n\nexport default MultipleInsurancesFirstStep;\n","export { default as MultipleInsurancesForm } from \"./multipleInsurancesForm\";\n","import { MultipleInsurancesSelector } from \"@app/components\";\nimport { Button, Form, FormField } from \"@natera/form\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport React from \"react\";\nimport { MultipleInsurance } from \"@app/components/ui/inputs/multipleInsurancesSelector/multipleInsurancesSelector\";\n\nimport \"./multipleInsurancesForm.scss\";\n\nconst messages = defineMessages({\n multipleInsurancesFormButtonNext: {\n id: \"multipleInsurancesFormButtonNext\",\n defaultMessage: \"Next\",\n },\n multipleInsurancesFormButtonBack: {\n id: \"multipleInsurancesFormButtonBack\",\n defaultMessage: \"Back\",\n },\n});\n\ntype Props = {\n selectedInsurance?: MultipleInsurance;\n onSelect: (insurance: MultipleInsurance) => void;\n onSubmit: (insurance: MultipleInsurance) => void;\n goBack: () => void;\n label: string;\n};\n\nconst MultipleInsurancesForm: React.FC = ({\n selectedInsurance,\n onSelect,\n onSubmit,\n goBack,\n label,\n}) => {\n const intl = useIntl();\n\n const handleSubmit: React.FormEventHandler = (event) => {\n event.preventDefault();\n\n if (!selectedInsurance) return;\n\n onSubmit(selectedInsurance);\n };\n\n return (\n \n );\n};\n\nexport default MultipleInsurancesForm;\n","import { MultipleInsurancesForm } from \"./multipleInsurancesForm\";\nimport { StepperContent } from \"@app/components/ui/layout\";\nimport { MultipleInsurance } from \"@app/components/ui/inputs/multipleInsurancesSelector/multipleInsurancesSelector\";\nimport {\n PaymentType,\n SubSteps,\n} from \"@app/pages/private/simpleOrder/paymentMethod/paymentMethod\";\nimport { StepperContext } from \"@natera/stepper\";\nimport React, { useContext, useEffect } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport {\n CommercialStep,\n GovernmentStep,\n} from \"@app/components/simpleOrder/payment/steps\";\nimport {\n MultiplePaymentMethodType,\n PaymentMethodType,\n SimpleOrderStepperContext,\n} from \"@app/provider/simpleOrder/SimpleOrderStepperProvider\";\nimport { Steps } from \"@app/pages/private/simpleOrder\";\n\nconst messages = defineMessages({\n multipleInsurancesStepHeaderTitle: {\n id: \"multipleInsurancesStepHeaderTitle\",\n defaultMessage: \"Payment Method\",\n },\n multipleInsurancesStepHeaderSubTitle: {\n id: \"multipleInsurancesStepHeaderSubTitle\",\n defaultMessage: \"More than one insurance\",\n },\n multipleInsurancesStepHeaderTextSecondType: {\n id: \"multipleInsurancesStepHeaderTextSecondType\",\n defaultMessage:\n \"Select the second type of insurance that you would like to use to cover the cost of your test.\",\n },\n multipleInsurancesFormSecondInsurancesTitle: {\n id: \"multipleInsurancesFormSecondInsurancesTitle\",\n defaultMessage: \"Second insurance type\",\n },\n});\n\ntype Props = {\n onConfirm: (data: unknown) => void;\n};\n\nconst MultipleInsurancesSecondStep: React.FC = ({ onConfirm }) => {\n const intl = useIntl();\n const {\n goBack,\n resolve,\n getData,\n createStep,\n removeStep,\n getCurrentStep,\n } = React.useContext(StepperContext);\n\n const stepData = getData(SubSteps.MULTIPLE_SECOND);\n const currentStepIdx = getCurrentStep()?.index;\n\n const { getSubStepData, resolveSubStep } = useContext(\n SimpleOrderStepperContext\n );\n const subStepsData = getSubStepData(\n Steps.PAYMENT_METHOD\n ) as MultiplePaymentMethodType;\n\n const getSelectedInsurance = () => {\n const paymentMethod =\n subStepsData?.paymentMethodInfo?.second?.paymentMethod;\n if (paymentMethod === PaymentType.COMMERCIAL) {\n return MultipleInsurance.Commercial;\n } else if (paymentMethod === PaymentType.GOVERNMENT_ISSUED) {\n return MultipleInsurance.Government;\n }\n return stepData;\n };\n\n const [selectedInsurance, setSelectedInsurance] = React.useState<\n MultipleInsurance | undefined\n >(getSelectedInsurance());\n\n useEffect(() => {\n if (selectedInsurance) {\n handleSelectInsurance(selectedInsurance);\n }\n }, []);\n\n const addSteps = (insurance: MultipleInsurance) => {\n if (insurance === MultipleInsurance.Commercial) {\n createStep(SubSteps.SELECT_COMMERCIAL_COMPANY_SECOND, {\n children: ,\n index: currentStepIdx ? currentStepIdx + 1 : undefined,\n });\n } else {\n createStep(SubSteps.SELECT_GOVERNMENT_COMPANY_SECOND, {\n children: ,\n index: currentStepIdx ? currentStepIdx + 1 : undefined,\n });\n }\n };\n\n const removeSteps = (insurance: MultipleInsurance | undefined) => {\n if (insurance === MultipleInsurance.Commercial) {\n removeStep(SubSteps.SELECT_COMMERCIAL_COMPANY_SECOND);\n removeStep(SubSteps.PROVIDE_COMMERCIAL_INSURANCE_SECOND);\n removeStep(SubSteps.ENTER_OTHER_COMMERCIAL_COMPANY_SECOND);\n }\n if (insurance === MultipleInsurance.Government) {\n removeStep(SubSteps.SELECT_GOVERNMENT_COMPANY_SECOND);\n removeStep(SubSteps.PROVIDE_GOVERNMENT_INSURANCE_SECOND);\n removeStep(SubSteps.ENTER_OTHER_GOVERNMENT_COMPANY_SECOND);\n }\n };\n\n const handleSelectInsurance = (insurance: MultipleInsurance) => {\n removeSteps(selectedInsurance);\n addSteps(insurance);\n\n setSelectedInsurance(insurance);\n };\n\n const handleSubmit = (insurance: string) => {\n const paymentMethod =\n insurance === MultipleInsurance.Commercial\n ? PaymentType.COMMERCIAL\n : PaymentType.GOVERNMENT_ISSUED;\n\n const paymentMethodInfoSecond: PaymentMethodType = { paymentMethod };\n\n if (\n subStepsData?.paymentMethodInfo?.second?.paymentMethod !== paymentMethod\n )\n paymentMethodInfoSecond.paymentMethodInfo = undefined;\n\n resolveSubStep({\n stepId: Steps.PAYMENT_METHOD,\n subStepData: {\n paymentMethodInfo: { second: { ...paymentMethodInfoSecond } },\n },\n });\n resolve(insurance);\n };\n\n const handleBack = () => {\n goBack();\n };\n\n return (\n {chunks} }\n )}\n >\n \n \n );\n};\n\nexport default MultipleInsurancesSecondStep;\n","export { default as ProvideCommercialStep } from \"./provideCommercialStep\";\n","import React, { useContext } from \"react\";\nimport { ProvideInsuranceForm } from \"@app/components/provideInsuranceForm\";\nimport { StepperContent } from \"@app/components/ui/layout/stepperContent\";\nimport { SubSteps } from \"@app/pages/private/simpleOrder/paymentMethod/paymentMethod\";\nimport { StepperContext } from \"@natera/stepper\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport {\n MultiplePaymentMethodType,\n PaymentMethodType,\n SimpleOrderStepperContext,\n} from \"@app/provider/simpleOrder/SimpleOrderStepperProvider\";\nimport { Steps } from \"@app/pages/private/simpleOrder\";\nimport {\n getPaymentMethodInfoSubStepsData,\n isCommercialOrGovernmentInsuranceFirst,\n isCommercialOrGovernmentInsuranceSecond,\n} from \"@app/utils\";\n\nconst messages = defineMessages({\n provideCommercialStepHeaderTitle: {\n id: \"provideCommercialStepHeaderTitle\",\n defaultMessage: \"Payment Method\",\n },\n provideCommercialStepHeaderSubTitle: {\n id: \"provideCommercialStepHeaderSubTitle\",\n defaultMessage: \"Enter insurance information\",\n },\n});\n\ntype Props = {\n onConfirm?: (data?: unknown) => void;\n};\n\nconst ProvideCommercialStep: React.FC = ({ onConfirm }) => {\n const intl = useIntl();\n\n const { goBack, resolve, getCurrentStep, getStep } = React.useContext(\n StepperContext\n );\n const currentStepId = getCurrentStep()?.stepId;\n\n const { getSubStepData, resolveSubStep } = useContext(\n SimpleOrderStepperContext\n );\n const subStepsData = getSubStepData(Steps.PAYMENT_METHOD) as\n | PaymentMethodType\n | MultiplePaymentMethodType;\n\n const isInsuranceFirstStep = isCommercialOrGovernmentInsuranceFirst(\n currentStepId\n );\n const isInsuranceSecondStep = isCommercialOrGovernmentInsuranceSecond(\n currentStepId\n );\n\n const commercialStepData = getPaymentMethodInfoSubStepsData(\n subStepsData,\n isInsuranceFirstStep,\n isInsuranceSecondStep\n );\n\n const handleSubmit = (memberId: string) => {\n let subStepDataWithMemberId;\n if (isInsuranceFirstStep) {\n subStepDataWithMemberId = {\n paymentMethodInfo: {\n first: {\n paymentMethodInfo: {\n ...(subStepsData as MultiplePaymentMethodType)?.paymentMethodInfo\n ?.first?.paymentMethodInfo,\n memberId,\n },\n },\n },\n };\n } else if (isInsuranceSecondStep) {\n subStepDataWithMemberId = {\n paymentMethodInfo: {\n second: {\n paymentMethodInfo: {\n ...(subStepsData as MultiplePaymentMethodType)?.paymentMethodInfo\n ?.second?.paymentMethodInfo,\n memberId,\n },\n },\n },\n };\n } else {\n subStepDataWithMemberId = {\n paymentMethodInfo: { memberId },\n };\n }\n\n resolveSubStep({\n stepId: Steps.PAYMENT_METHOD,\n subStepData: subStepDataWithMemberId,\n });\n\n resolve({ memberId });\n const needToAddSecondMultipleStep = !getStep(SubSteps.MULTIPLE_SECOND);\n if (needToAddSecondMultipleStep) {\n onConfirm && onConfirm();\n }\n };\n\n const handleBack = () => {\n goBack();\n };\n\n return (\n \n \n \n );\n};\n\nexport default ProvideCommercialStep;\n","export { default as ProvideGovernmentStep } from \"./provideGovernmentStep\";\n","import { ProvideGovernmentIssuedForm } from \"@app/components/forms\";\nimport { StepperContent } from \"@app/components/ui/layout/stepperContent\";\nimport { SubSteps } from \"@app/pages/private/simpleOrder/paymentMethod/paymentMethod\";\nimport { StepperContext } from \"@natera/stepper\";\nimport React, { useContext } from \"react\";\nimport { defineMessages, useIntl } from \"react-intl\";\nimport {\n MultiplePaymentMethodType,\n PaymentMethodType,\n SimpleOrderStepperContext,\n} from \"@app/provider/simpleOrder/SimpleOrderStepperProvider\";\nimport { Steps } from \"@app/pages/private/simpleOrder\";\nimport {\n getPaymentMethodInfoSubStepsData,\n isCommercialOrGovernmentInsuranceFirst,\n isCommercialOrGovernmentInsuranceSecond,\n} from \"@app/utils\";\n\nconst messages = defineMessages({\n provideGovernmentStepHeaderTitle: {\n id: \"provideGovernmentStepHeaderTitle\",\n defaultMessage: \"Payment Method\",\n },\n provideGovernmentStepHeaderSubTitle: {\n id: \"provideGovernmentStepHeaderSubTitle\",\n defaultMessage: \"Enter government-issued insurance information\",\n },\n});\n\ntype Props = {\n onConfirm?: (data?: unknown) => void;\n};\n\nconst ProvideGovernmentStep: React.FC = ({ onConfirm }) => {\n const intl = useIntl();\n\n const { goBack, resolve, getCurrentStep, getStep } = React.useContext(\n StepperContext\n );\n const currentStepId = getCurrentStep()?.stepId;\n\n const { getSubStepData, resolveSubStep } = useContext(\n SimpleOrderStepperContext\n );\n\n const subStepsData = getSubStepData(Steps.PAYMENT_METHOD) as\n | PaymentMethodType\n | MultiplePaymentMethodType;\n\n const isInsuranceFirstStep = isCommercialOrGovernmentInsuranceFirst(\n currentStepId\n );\n const isInsuranceSecondStep = isCommercialOrGovernmentInsuranceSecond(\n currentStepId\n );\n\n const governmentStepData = getPaymentMethodInfoSubStepsData(\n subStepsData,\n isInsuranceFirstStep,\n isInsuranceSecondStep\n );\n\n const handleSubmit = (insuranceNumber: string) => {\n let subStepDataWithInsuranceNumber;\n\n if (isInsuranceFirstStep) {\n subStepDataWithInsuranceNumber = {\n paymentMethodInfo: {\n first: {\n paymentMethodInfo: {\n ...(subStepsData as MultiplePaymentMethodType)?.paymentMethodInfo\n ?.first?.paymentMethodInfo,\n insuranceNumber,\n },\n },\n },\n };\n } else if (isInsuranceSecondStep) {\n subStepDataWithInsuranceNumber = {\n paymentMethodInfo: {\n second: {\n paymentMethodInfo: {\n ...(subStepsData as MultiplePaymentMethodType)?.paymentMethodInfo\n ?.second?.paymentMethodInfo,\n insuranceNumber,\n },\n },\n },\n };\n } else {\n subStepDataWithInsuranceNumber = {\n paymentMethodInfo: { insuranceNumber },\n };\n }\n\n resolveSubStep({\n stepId: Steps.PAYMENT_METHOD,\n subStepData: subStepDataWithInsuranceNumber,\n });\n\n resolve({ insuranceNumber });\n const needToAddSecondMultipleStep = !getStep(SubSteps.MULTIPLE_SECOND);\n if (needToAddSecondMultipleStep) {\n onConfirm && onConfirm();\n }\n };\n\n const handleBack = () => {\n goBack();\n };\n\n return (\n \n