= ({\n children,\n visible,\n cancel$,\n width,\n style,\n}) => {\n return (\n }\n onCancel={() => cancel$.next()}\n width={width}\n style={style}\n >\n {children}\n \n );\n};\n","import React, { createContext, useContext, useState } from \"react\";\n\nimport { Subject } from \"rxjs\";\n\nimport { combineComponents } from \"shared/utils/combine-components\";\n\nimport { VeroModalContext } from \"./types\";\n\nfunction useVeroModal(): VeroModalContext
{\n const [visible, setVisible] = useState(false);\n const hide = () => {\n setVisible(false);\n };\n const show = () => setVisible(true);\n const ok$ = new Subject
();\n const cancel$ = new Subject();\n const submit$ = new Subject>();\n const [submitting, setSubmitting] = useState(false);\n submit$.subscribe((promise) => {\n setSubmitting(true);\n promise\n .then((x) => ok$.next(x))\n .catch(console.error) // catch unhandled exceptions to prevent app from crashing\n .finally(() => setSubmitting(false));\n });\n ok$.subscribe(hide);\n cancel$.subscribe(hide);\n\n return {\n visible,\n submitting,\n hide,\n show,\n ok$,\n cancel$,\n submit$,\n };\n}\n\nexport function createModalContext() {\n const Context = createContext>(undefined);\n const Provider: React.FC<{}> = ({ children }) => {\n const state = useVeroModal();\n return {children};\n };\n const useModalContext = () => useContext(Context);\n\n return { Context, Provider, useModalContext };\n}\n\nexport const withModals = (\n Component: React.FC,\n ...providers: React.FC<{}>[]\n) => {\n const Merged = combineComponents(...providers);\n return (props: T) => (\n \n \n \n );\n};\n","import React, { useState, useEffect } from \"react\";\n\ntype Props = {\n delay?: number;\n};\n\nexport const Delayed: React.FC = ({ children, delay = 500 }) => {\n const [isShown, setIsShown] = useState(false);\n\n useEffect(() => {\n const timer = setTimeout(() => {\n setIsShown(true);\n }, delay);\n return () => clearTimeout(timer);\n }, [delay]);\n\n return isShown ? <>{children}> : null;\n};\n","import styled from \"@emotion/styled\";\n\nimport BaseCheckList from \"shared/components/ApplicantsCheckList\";\nimport Well from \"shared/components/Well\";\nimport { MEDIA_QUERIES } from \"shared/config/constants\";\n\nexport const Subtitle = styled.span`\n display: flex;\n flex-wrap: wrap;\n gap: 8;\n`;\n\nexport const ApplicantsCheckList = styled(BaseCheckList)`\n flex: 1;\n`;\n\nexport const MessageWrapper = styled(Well)`\n margin: 24px 0;\n\n .message-icon {\n margin-right: 24px;\n }\n`;\n\nexport const UploadWallWrapper = styled.div`\n .ant-latest-upload-list-picture-card > div:nth-child(2n) {\n margin-right: 0;\n }\n`;\n\nexport const Attachments = styled(\"div\")({\n marginLeft: \"24px\",\n [MEDIA_QUERIES.w.ltSm]: {\n marginLeft: 0,\n },\n});\n","import { createModalContext } from \"shared/components/vero-modal\";\n\nexport const {\n Context: RemoveApplicantModalContext,\n Provider: RemoveApplicantModalProvider,\n useModalContext: useRemoveApplicantModal,\n} = createModalContext();\n","export const fileUploadHandler = (file) => {\n const item = {\n ...file,\n id: `${Date.now()}`,\n name: file.name.toLowerCase(),\n status: \"done\",\n };\n return new Promise((resolve) => {\n const reader = new FileReader();\n reader.readAsDataURL(file);\n reader.onload = (loadedFile) => {\n item.url = loadedFile.target.result;\n resolve(item);\n };\n });\n};\n","import React, { useState } from \"react\";\n\nimport styled from \"@emotion/styled\";\nimport { Field } from \"formik\";\n\nimport { YardiRemoveMainApplicantReasonFormExtension } from \"manager/pages/Marketplace/integrations/yardi/shared\";\nimport { TextArea } from \"shared/components/Form\";\nimport { FormGroups } from \"shared/styles/commonStyles\";\nimport { fileUploadHandler } from \"shared/utils/upload\";\n\nexport const useUpload = () => {\n const [attachments, setAttachments] = useState([]);\n\n const uploadFile = async (file) => {\n const item = await fileUploadHandler(file);\n setAttachments((currentAtt) => [...currentAtt, file]);\n return item;\n };\n\n const excludeFile = async (file) => {\n setAttachments((currentAttachments) =>\n currentAttachments.filter((f) => f.uid !== file.uid)\n );\n };\n\n return { attachments, uploadFile, excludeFile };\n};\n\nconst YardiRemoveMainApplicantContainer = styled(\"div\")({\n ...FormGroups,\n \".description\": {\n fontWeight: 300,\n margin: 0,\n },\n \".reason-select\": {\n marginTop: \"24px\",\n marginBottom: \"32px\",\n },\n});\n\nexport type RemovePrimaryYardiExtensionProps = {\n unit?: {\n yardiConnected?: boolean;\n };\n property?: {\n yardiConnected?: boolean;\n yardiPropertyId?: number;\n };\n isPrimary: boolean;\n};\n\nexport type { YardiReasonFormExtensionFields } from \"manager/pages/Marketplace/integrations/yardi/shared/YardiReasonFormExtension/types\";\n\nexport const useRemovePrimaryYardiExtension = (\n props: RemovePrimaryYardiExtensionProps\n) => {\n const show =\n (props.unit || props.property)?.yardiConnected && props.isPrimary;\n const extension = show ? (\n \n \n \n \n ) : null;\n return { extension };\n};\n","import React from \"react\";\n\nimport { Formik } from \"formik\";\n\nimport { Button, BUTTON_SIZES } from \"shared/components/Button\";\nimport FlexContainer from \"shared/components/FlexContainer\";\nimport { UnderlineLink } from \"shared/components/Links\";\nimport Spacer from \"shared/components/Spacer\";\nimport { LargeTitle, RegularText } from \"shared/components/Typography\";\nimport { VeroModal } from \"shared/components/vero-modal\";\n\nimport {\n RemovePrimaryYardiExtensionProps,\n YardiReasonFormExtensionFields,\n} from \"../hooks\";\nimport { ApplicantsCheckList, Subtitle } from \"../styled\";\n\nimport { ApplicantSummary } from \"../types\";\n\nimport { useRemoveApplicantModal } from \"./context\";\nimport { useHook } from \"./hooks\";\n\nexport interface RemoveApplicantModalProps {\n dealId: string | number;\n application: ApplicantSummary;\n yardi: RemovePrimaryYardiExtensionProps;\n}\n\nexport type RemoveApplicantModalResult = YardiReasonFormExtensionFields & {};\n\nexport const RemoveApplicantModalV2 = (props: RemoveApplicantModalProps) => {\n const state = useRemoveApplicantModal();\n const { remove, application, extension } = useHook(props, state.hide);\n const { cancel$, submit$, submitting } = state;\n\n return (\n \n submit$.next(remove(values))\n }\n validateOnMount\n >\n {({ submitForm, isValid }) => (\n \n Remove this applicant?\n \n Applicant: \n \n \n\n \n\n {extension}\n\n \n Please note: Once you remove {application.firstName}{\" \"}\n {application.lastName}, you will have to re-invite them back into\n the application in case you change your decision.\n
\n\n \n \n cancel$.next()}>Cancel\n \n \n \n )}\n \n );\n};\n","import { openDefaultAnimatedActionModal } from \"shared/components/Modals/AnimatedPendingActionModal\";\nimport { COMMON_PENDING_ANIMATION_MESSAGES } from \"shared/config/constants\";\n\nimport { removeApplicationFromDeal } from \"shared/lib/api/dealApi\";\n\nimport { useRemovePrimaryYardiExtension } from \"../hooks\";\n\nimport {\n RemoveApplicantModalResult,\n RemoveApplicantModalProps,\n} from \"./component\";\n\nexport const useHook = (props: RemoveApplicantModalProps, hide: () => void) => {\n const { dealId, application } = props;\n const remove = async ({ extraParams }: RemoveApplicantModalResult) => {\n const messages = [\n ...COMMON_PENDING_ANIMATION_MESSAGES,\n \"Individual Removed\",\n ];\n hide();\n const loadingModal = openDefaultAnimatedActionModal(messages, 1000);\n try {\n await removeApplicationFromDeal({\n id: String(dealId),\n applicationId: application?.id,\n ...extraParams,\n });\n loadingModal.finishAnimation();\n } catch (err) {\n loadingModal.finishAnimation(() => {}, \"Error\", false, true);\n throw err;\n }\n };\n\n const { extension } = useRemovePrimaryYardiExtension(props.yardi);\n\n return { remove, application, extension };\n};\n","import styled from \"@emotion/styled\";\n\nimport FlexContainer from \"shared/components/FlexContainer\";\nimport Icon from \"shared/components/Icon\";\nimport { COLORS, MEDIA_QUERIES } from \"shared/config/constants\";\nimport { AlignedCenterFlexPartial } from \"shared/styles/commonStyles\";\n\nconst commonCol = {\n ...AlignedCenterFlexPartial,\n padding: \"12px 24px\",\n};\n\nconst headerHeight = \"67px\";\n\nconst secondColSmall = \"380px\";\nconst firstColSmall = `calc(100% - ${secondColSmall})`;\n\ntype Props = {\n isCancelledDeal: any;\n isDeclinedDeal: any;\n};\n\nconst getDealHeaderSecondColBg = (props: Props) => {\n if (props.isDeclinedDeal) {\n return COLORS.lightRed2;\n }\n\n if (props.isCancelledDeal) {\n return COLORS.lightGray4;\n }\n\n return COLORS.violetTheme.lightViolet;\n};\n\nconst DealHeaderContent = styled.div((props: Props) => ({\n ...AlignedCenterFlexPartial,\n color: COLORS.white,\n width: \"100%\",\n alignItems: \"stretch\",\n \"& > div\": {\n minHeight: headerHeight,\n },\n fontWeight: 500,\n \".deal-header-first-col\": {\n ...commonCol,\n gap: \"10px\",\n flexWrap: \"wrap\",\n // width: firstColLarge,\n justifyContent: \"space-between\",\n flex: 1,\n backgroundColor: COLORS.lightViolet,\n borderRadius: \"4px 0 0 4px\",\n \".deal-header-title-container\": {\n ...AlignedCenterFlexPartial,\n marginRight: \"18px\",\n fontWeight: 600,\n fontSize: \"17px\",\n \".deal-header-title-text-wrapper\": {\n maxWidth: \"100%\",\n },\n },\n \".integration-mark\": {\n marginLeft: \"23px\",\n minWidth: \"20px\",\n\n [MEDIA_QUERIES.w.ltMd]: {\n marginLeft: \"0px\",\n },\n },\n \".deal-header-assign-unit\": {\n marginLeft: \"30px\",\n whiteSpace: \"nowrap\",\n color: COLORS.violetTheme.lightGreen,\n\n [MEDIA_QUERIES.w.ltMd]: {\n marginLeft: \"10px\",\n marginRight: \"30px\",\n },\n },\n },\n \".deal-header-second-col\": {\n ...commonCol,\n justifyContent: \"space-between\",\n backgroundColor: getDealHeaderSecondColBg(props),\n borderRadius: \"0 4px 4px 0\",\n \".deal-header-inactive\": {\n ...AlignedCenterFlexPartial,\n span: {\n marginLeft: \"16px\",\n color: COLORS.white,\n },\n \"&.cancelled\": {\n span: {\n color: COLORS.gray2,\n },\n },\n },\n \".deal-header-actions\": {\n ...AlignedCenterFlexPartial,\n \".deal-header-pdf-download\": {\n marginRight: \"30px\",\n },\n },\n },\n [MEDIA_QUERIES.w.ltXl]: {\n \".deal-header-first-col\": {\n width: firstColSmall,\n }\n },\n [MEDIA_QUERIES.w.ltMd]: {\n flexDirection: \"column\",\n height: \"auto\",\n maxHeight: \"none\",\n \".deal-header-first-col\": {\n alignItems: \"stretch\",\n flexDirection: \"column\",\n gap: 0,\n width: \"100%\",\n borderRadius: 0,\n paddingTop: 0,\n paddingBottom: 0,\n \".deal-header-title-container\": {\n width: \"100%\",\n minHeight: \"67px\",\n margin: 0,\n paddingRight: \"20px\",\n \".dropdown-chevron\": {},\n \"&.deal-header-title-no-unit\": {\n justifyContent: \"space-between\",\n paddingRight: 0,\n },\n },\n \".integration-mark\": {\n marginLeft: \"10px\",\n },\n },\n \".deal-header-second-col\": {\n borderRadius: 0,\n width: \"100%\",\n minHeight: \"61px\",\n height: \"61px\",\n backgroundColor: COLORS.background,\n color: COLORS.grayTheme.activeTextColor,\n \".deal-header-inactive\": {\n span: {\n color: COLORS.primary,\n },\n },\n \".deal-header-pdf-download\": {\n display: \"none\",\n },\n },\n },\n}));\n\nconst DealUnitHeaderItemsContent = styled(FlexContainer)({\n ...AlignedCenterFlexPartial,\n // flexWrap: \"wrap\",\n justifyContent: \"flex-end\",\n // fontWeight: 400,\n \".deal-rent\": {\n textAlign: \"end\",\n },\n \".edit-rent-icon\": {\n marginLeft: \"8px\",\n cursor: \"pointer\",\n },\n});\n\nconst UnitPopoverContent = styled.div({\n padding: \"16px\",\n minWidth: \"250px\",\n \".popover-title\": {\n fontSize: \"12px\",\n fontWeight: 600,\n marginBottom: \"16px\",\n },\n \".popover-items\": {\n border: \"none\",\n p: {\n margin: 0,\n },\n \"p + p\": {\n marginTop: \"10px\",\n },\n },\n \".application-title\": {\n marginTop: \"16px\",\n },\n});\n\nconst TitlePopoverContent = styled.div({\n padding: \"16px\",\n maxWidth: \"290px\",\n \".popover-title\": {\n marginBottom: \"6px\",\n },\n});\n\nconst InfoDark = styled(Icon.InfoDark)`\n cursor: pointer;\n margin-left: 20px;\n`;\n\nconst MainText = styled.div({\n whiteSpace: \"nowrap\",\n '& > a': {\n color: COLORS.white\n },\n '& > a:hover': {\n textDecoration: 'underline'\n }\n});\n\nexport {\n DealHeaderContent,\n DealUnitHeaderItemsContent,\n UnitPopoverContent,\n TitlePopoverContent,\n InfoDark,\n MainText,\n};\n","import React from \"react\";\n\n\nimport { UnderlineLink } from \"shared/components/Links\";\nimport { Popover } from \"shared/components/Popover\";\nimport { SmallText } from \"shared/components/Typography\";\nimport { DEAL_UI_STATUS_CODES } from \"shared/config/constants\";\n\nimport { printDollarsFromCents } from \"shared/utils/dollar-print\";\nimport { TitlePopoverContent } from \"./styled\";\n\nconst NO_UNIT_LABEL = \"No unit assigned\";\n\nconst CANCELLED_DEAL_STATUSES = new Set([\n DEAL_UI_STATUS_CODES.listingClosed,\n DEAL_UI_STATUS_CODES.cancelled,\n DEAL_UI_STATUS_CODES.cancelledInYardi,\n]);\n\nconst DECLINED_DEAL_STATUSES = new Set([\n DEAL_UI_STATUS_CODES.declined,\n DEAL_UI_STATUS_CODES.declinedInYardi,\n]);\n\nexport const isDeclinedDeal = (dealUiStatus: DEAL_UI_STATUS_CODES) =>\n DECLINED_DEAL_STATUSES.has(dealUiStatus);\n\nexport const isCanceledDeal = (dealUiStatus: DEAL_UI_STATUS_CODES) =>\n CANCELLED_DEAL_STATUSES.has(dealUiStatus);\n\nexport const getApplicationSource = ({\n isMagicDeal,\n isOpenApiDeal,\n}: { isMagicDeal?: boolean; isOpenApiDeal?: boolean } = {}): string | null => {\n if (isMagicDeal) return \"Magic Deal\";\n if (isOpenApiDeal) return \"Open API\";\n return null;\n};\n\nexport const TitlePopoverWrapper: React.FC<{\n title?: string;\n propertyAddress?: string;\n}> = ({ title, propertyAddress, children }) => {\n return (\n \n {title}
\n {propertyAddress}\n \n }\n >\n {children}\n \n );\n};\n\nexport const getNoUnitText = (\n isMagicDeal?: boolean,\n externalUrl?: string,\n propertyName?: string\n) => {\n let noUnitText;\n if (isMagicDeal) {\n const getAddressView = () => {\n return externalUrl?.startsWith(\"http\") ? (\n \n {externalUrl}\n \n ) : (\n <>{externalUrl || NO_UNIT_LABEL}>\n );\n };\n // NOTE: if it's a magic deal and the deal is on a property,\n // show the property name, otherwise show the external source\n noUnitText = propertyName || getAddressView();\n } else {\n noUnitText = NO_UNIT_LABEL;\n }\n return noUnitText;\n};\n\nexport const getSecurityDepositBalance = (\n securityDeposit?: number,\n isDeducted?: boolean\n) => {\n const formattedBalance = `${printDollarsFromCents(securityDeposit)}${\n isDeducted ? \" (Deducted)\" : \"\"\n }`;\n\n return formattedBalance;\n};\n","import { createModalContext } from \"shared/components/vero-modal\";\n\nexport type OnMovedApplicant = {\n dealId: string;\n};\nexport const {\n Context: MoveApplicantModalContext,\n Provider: MoveApplicantModalProvider,\n useModalContext: useMoveApplicantModal,\n} = createModalContext();\n","import { CSSProperties } from \"react\";\n\nimport styled from \"@emotion/styled\";\n\nimport { MEDIA_QUERIES } from \"shared/config/constants\";\n\nexport const DealWrapper = styled(\"div\")({\n display: \"flex\",\n fontWeight: 400,\n [MEDIA_QUERIES.w.ltSm]: {\n flexDirection: \"column\",\n },\n});\n\nexport const ColumnData = styled(\"div\")(\n (props: { width: CSSProperties[\"width\"] }) => ({\n minWidth: \"120px\",\n width: props?.width,\n marginBottom: 0,\n display: \"flex\",\n alignItems: \"center\",\n marginRight: \"10px\",\n [MEDIA_QUERIES.w.ltSm]: {\n marginBottom: \"10px\",\n },\n \"&>:last-child\": {\n marginRight: 0,\n },\n })\n);\n\nexport const Applications = styled(\"div\")({\n display: \"flex\",\n flexDirection: \"column\",\n});\n\nexport const ApplicantName = styled(\"div\")({\n marginBottom: \"10px\",\n whiteSpace: \"break-spaces\",\n \"&:last-child\": {\n marginBottom: 0,\n },\n});\n\nexport const Address = styled(\"div\")({\n display: \"flex\",\n flexDirection: \"column\",\n whiteSpace: \"break-spaces\",\n});\n\nexport const Property = styled(\"div\")({\n fontSize: \"12px\",\n color: \"#807E8D\",\n});\n","import React from \"react\";\n\nimport withSizes from \"react-sizes\";\n\nimport { formatDate } from \"shared/utils/ui\";\n\nimport { ApplicantSummary } from \"../../types\";\n\nimport { printDollarsFromCents } from \"shared/utils/dollar-print\";\nimport {\n Address,\n ApplicantName,\n Applications,\n ColumnData,\n DealWrapper,\n Property,\n} from \"./styled\";\n\nconst getColumnWidth = (width: number) => {\n if (width > 570) {\n return [150, 200, 250, 100];\n }\n\n return [150, 150, 150, 150];\n};\n\ntype Props = {\n id: number;\n applications: ApplicantSummary[];\n unitName?: string;\n propertyName?: string;\n unitListing?: { unitAvailableOn: Date };\n width?: number;\n rent?: number;\n};\nconst Inner: React.FC = ({\n id,\n applications,\n unitName,\n propertyName,\n unitListing,\n width,\n rent,\n}) => {\n const columnWidth = getColumnWidth(width);\n return (\n \n \n \n {applications?.length\n ? applications?.map((applicant) => (\n \n {applicant?.firstName} {applicant?.lastName}\n \n ))\n : \"N/A\"}\n \n \n \n \n {unitName}\n {propertyName}\n \n \n \n {unitListing?.unitAvailableOn\n ? `Available on ${formatDate(unitListing.unitAvailableOn)}`\n : \"N/A\"}\n \n \n {rent ? `Rent: ${printDollarsFromCents(rent)}` : \"N/A\"}\n \n \n );\n};\n\nexport const DealDescription = withSizes(({ width }) => ({ width }))(Inner);\n","import React from \"react\";\n\nimport { Formik } from \"formik\";\n\nimport { DealToMove } from \"manager/lib/dealsApi\";\nimport { Button, BUTTON_SIZES } from \"shared/components/Button\";\nimport FlexContainer from \"shared/components/FlexContainer\";\nimport { CollapsibleRadioList, SearchableList } from \"shared/components/Form\";\nimport Icon from \"shared/components/Icon\";\nimport { UnderlineLink } from \"shared/components/Links\";\nimport Spacer from \"shared/components/Spacer\";\nimport { LargeTitle, RegularText } from \"shared/components/Typography\";\nimport { VeroModal } from \"shared/components/vero-modal\";\n\nimport { isDeclinedDeal, isCanceledDeal } from \"../../header/utils\";\nimport {\n RemovePrimaryYardiExtensionProps,\n YardiReasonFormExtensionFields,\n} from \"../hooks\";\nimport { ApplicantsCheckList, Subtitle } from \"../styled\";\n\nimport { ApplicantSummary } from \"../types\";\n\nimport { useMoveApplicantModal } from \"./context\";\nimport { DealDescription } from \"./deal-description\";\nimport { useHook } from \"./hooks\";\n\nexport interface MoveApplicantModalProps {\n dealId: string | number;\n application: ApplicantSummary;\n yardi: RemovePrimaryYardiExtensionProps;\n}\n\nexport type MoveApplicantModalForm = YardiReasonFormExtensionFields & {};\n\nexport const MoveApplicantModal = (props: MoveApplicantModalProps) => {\n const state = useMoveApplicantModal();\n const { application } = props;\n const {\n deals,\n loading,\n extension,\n setSearchingValue,\n setDestinationDeal,\n move,\n } = useHook({ ...props, enabled: state.visible });\n const { cancel$, submit$, submitting } = state;\n\n return (\n \n submit$.next(move(values))\n }\n validateOnMount\n >\n {({ submitForm, isValid }) => (\n \n Move applicant to another application\n \n Applicant: \n \n \n\n \n\n {extension}\n\n Select application you want to move this applicant to
\n {\n setSearchingValue(value);\n },\n width: \"370px\",\n debounce: true,\n // @ts-ignore\n disabled: loading,\n }}\n List={CollapsibleRadioList}\n listContainerProps={{\n onChange: ({ target: { value } }) => {\n setDestinationDeal(deals.find((item) => item.id === value));\n },\n }}\n listProps={{\n col1Width: \"auto\",\n items: loading\n ? []\n : (deals ?? []).map((deal: DealToMove) => ({\n key: deal.id,\n label: ,\n disabled: !deal?.canApplicationBeMoved,\n radioTooltipProps: !deal?.canApplicationBeMoved && {\n title:\n isDeclinedDeal(deal?.dealStatus) ||\n isCanceledDeal(deal?.dealStatus)\n ? \"You can not move an applicant to a deal that has already been declined or canceled.\"\n : \"This application cannot be selected. Screening settings differ from the current application.\",\n theme: \"light\",\n placement: \"topLeft\",\n },\n })),\n }}\n placeholder={{\n label: \"Applications\",\n Icon: Icon.NoDealsIcon,\n }}\n hasInputValue={false}\n />\n\n \n \n cancel$.next()}>Cancel\n \n \n \n )}\n \n );\n};\n","import { useMemo, useState } from \"react\";\n\nimport { useGetDealsToMove } from \"manager/hooks/api\";\nimport { DealToMove } from \"manager/lib/dealsApi\";\nimport { moveApplicationToAnotherDeal } from \"shared/lib/api/applicationApi\";\nimport { isSubstrInStr } from \"shared/utils/ui\";\n\nimport { useRemovePrimaryYardiExtension } from \"../hooks\";\n\nimport { MoveApplicantModalProps, MoveApplicantModalForm } from \"./component\";\n\nimport { OnMovedApplicant } from \"./context\";\n\nexport const useHook = ({\n application,\n dealId,\n yardi,\n enabled = true,\n}: MoveApplicantModalProps & { enabled: boolean }) => {\n const [destinationDeal, setDestinationDeal] = useState>(\n {}\n );\n const [searchingValue, setSearchingValue] = useState(\"\");\n\n const { isLoading: isDealsLoading, data } = useGetDealsToMove({\n dealId,\n enabled,\n });\n const move = async (\n result: MoveApplicantModalForm\n ): Promise => {\n await moveApplicationToAnotherDeal({\n applicationId: application.id,\n dealId: destinationDeal.id,\n ...result.extraParams,\n });\n return { dealId: destinationDeal.id };\n };\n\n const deals = useMemo(\n () =>\n data?.filter((deal) => {\n const applicants = deal?.applications?.map(\n (app) => `${app.firstName} ${app.lastName}`\n );\n const applicantsSearch = applicants?.filter((app) =>\n isSubstrInStr(app, searchingValue)\n );\n const propertyNameSearch = isSubstrInStr(\n deal.propertyName,\n searchingValue\n );\n const unitNameSearch = isSubstrInStr(deal.unitName, searchingValue);\n\n return applicantsSearch?.length || propertyNameSearch || unitNameSearch;\n }),\n [searchingValue, data]\n );\n\n const { extension } = useRemovePrimaryYardiExtension(yardi);\n\n return {\n move,\n loading: isDealsLoading,\n deals,\n extension,\n setDestinationDeal,\n setSearchingValue,\n };\n};\n","import React from \"react\";\n\nimport styled from \"@emotion/styled\";\nimport PropTypes from \"prop-types\";\n\nimport { CollapsibleRadioList, ListWrapper } from \"shared/components/Form\";\nimport Icon from \"shared/components/Icon\";\nimport { Modal } from \"shared/components/Modal\";\nimport { LightText } from \"shared/components/Typography\";\nimport { BREAKPOINT_TYPES, COLORS } from \"shared/config/constants\";\nimport withBreakpoint from \"shared/hocs/withBreakpoint\";\nimport { TextEllipsis } from \"shared/styles/commonStyles\";\nimport { breakpointPropType, keyPropType } from \"shared/utils/propTypes\";\n\nconst AssignAgentToDealModalContent = styled.div({\n \".assign-agent-list\": {\n borderRadius: \"2px\",\n },\n \".description-cell\": {\n ...TextEllipsis,\n },\n \".ant-radio-wrapper\": {\n whiteSpace: \"pre-wrap\",\n \"span:last-child\": {\n wordBreak: \"break-word\",\n },\n },\n \".selected-item\": {\n backgroundColor: COLORS.lightGreen,\n },\n});\n\nconst AssignAgentToDealModal = ({\n breakpoint,\n unitName,\n selectedAgent,\n changeAgent,\n submit,\n isAgentsLoading,\n agents,\n isAssigningAgent,\n}) => {\n return (\n \n Unit: {unitName}\n >\n ) : null\n }\n submit={submit}\n submitting={isAssigningAgent}\n submitButtonLabel=\"CONFIRM\"\n width=\"auto\"\n closeOnSubmit={false}\n style={{ maxWidth: 776 }}\n fullScreen={BREAKPOINT_TYPES.xs === breakpoint}\n >\n \n \n {\n changeAgent(item);\n },\n selectedItem: selectedAgent,\n items: isAgentsLoading\n ? []\n : (agents || []).map((agent) => ({\n key: agent.id,\n label: (\n <>\n {agent.name}\n {agent.isCurrent && (me)}\n >\n ),\n description: [{ node: agent.email, noSeparator: true }],\n className:\n agent.id === selectedAgent ? \"selected-item\" : undefined,\n })),\n itemProps: {\n noBorderBottom: false,\n firstItemNoBorderTop: false,\n },\n }}\n listContainerProps={{\n groupName: \"agents\",\n }}\n loading={isAgentsLoading}\n placeholder={{\n label: \"Agents\",\n Icon: Icon.NoEmployeesIcon,\n }}\n />\n \n \n \n );\n};\n\nAssignAgentToDealModal.propTypes = {\n breakpoint: breakpointPropType.isRequired,\n unitName: PropTypes.string,\n selectedAgent: keyPropType.isRequired,\n changeAgent: PropTypes.func.isRequired,\n submit: PropTypes.func.isRequired,\n isAgentsLoading: PropTypes.bool.isRequired,\n agents: PropTypes.arrayOf(\n PropTypes.shape({\n id: keyPropType.isRequired,\n name: PropTypes.string.isRequired,\n email: PropTypes.string.isRequired,\n isCurrent: PropTypes.bool.isRequired,\n })\n ),\n isAssigningAgent: PropTypes.bool.isRequired,\n};\n\nAssignAgentToDealModal.defaultProps = {\n unitName: undefined,\n agents: [],\n};\n\nexport default withBreakpoint(AssignAgentToDealModal);\n","import React, { useState } from \"react\";\n\nimport PropTypes from \"prop-types\";\n\nimport {\n useAssignAgentToDeal,\n useGetAssignableAgents,\n} from \"manager/hooks/api\";\nimport useModal from \"shared/hooks/useModal\";\nimport { keyPropType } from \"shared/utils/propTypes\";\n\nimport AssignAgentToDealModal from \"./AssignAgentToDealModal\";\n\nconst AssignAgentToDealModalContainer = ({\n dealId,\n unitName,\n currentAgentId,\n afterAgentChanged,\n}) => {\n const { selfApi } = useModal();\n const [selectedAgent, setAgent] = useState(currentAgentId);\n const { data: agents, isLoading: isAgentsLoading } = useGetAssignableAgents(\n dealId,\n { enabled: Boolean(dealId) }\n );\n\n const { assignEmployeeToDeal, isLoading: isAssigningAgent } =\n useAssignAgentToDeal();\n\n const submit = () => {\n assignEmployeeToDeal(\n { dealId, employeeId: selectedAgent },\n {\n onSuccess: () => {\n if (afterAgentChanged) {\n afterAgentChanged();\n }\n },\n onSettled: () => selfApi.closeDialog(),\n }\n );\n };\n\n return (\n \n );\n};\n\nAssignAgentToDealModalContainer.propTypes = {\n dealId: keyPropType.isRequired,\n unitName: PropTypes.string,\n currentAgentId: keyPropType.isRequired,\n afterAgentChanged: PropTypes.func.isRequired,\n};\n\nAssignAgentToDealModalContainer.defaultProps = {\n unitName: undefined,\n};\n\nexport default AssignAgentToDealModalContainer;\n","import { createModalContext } from \"shared/components/vero-modal\";\n\nexport const {\n Context: ApproveDealModalContext,\n Provider: ApproveDealModalProvider,\n useModalContext: useApproveDealModal,\n} = createModalContext();\n","import React from \"react\";\n\nimport { Formik } from \"formik\";\n\nimport { Button, BUTTON_SIZES } from \"shared/components/Button\";\nimport FlexContainer from \"shared/components/FlexContainer\";\nimport { UploadWall } from \"shared/components/Form/UploadWall\";\nimport Icon from \"shared/components/Icon\";\nimport { UnderlineLink } from \"shared/components/Links\";\nimport Spacer from \"shared/components/Spacer\";\nimport { LargeTitle, RegularText } from \"shared/components/Typography\";\nimport { VeroModal } from \"shared/components/vero-modal\";\nimport { MAX_FILE_UPLOAD_SIZE_1MB } from \"shared/config/constants\";\n\nimport { ApplicantsCheckList, MessageWrapper, Subtitle } from \"../styled\";\n\nimport { DealSummary } from \"../types\";\n\nimport { useApproveDealModal } from \"./context\";\nimport { useHook } from \"./hooks\";\n\nexport interface ApproveDealModalProps {\n deal: DealSummary;\n}\n\nexport const ApproveDealModalV2 = ({ deal }: ApproveDealModalProps) => {\n const state = useApproveDealModal();\n const { showCountyRecordsPendingMessage, uploadFile, approve } = useHook(\n deal,\n state.hide\n );\n const { cancel$, submit$, submitting } = state;\n\n return (\n submit$.next(approve())}>\n {({ submitForm }) => (\n \n Approve Application\n \n Applicants: \n \n \n\n \n\n \n
\n Please note that once you approve these applicants, they will be\n notified.\n
\n\n {showCountyRecordsPendingMessage && (\n
\n \n \n \n
\n \n You are approving an application without considering the\n county criminal records search, which can take up to 14\n days. Please confirm you'd like to perform this\n decision.\n \n \n \n )}\n\n
\n Choose which attachments to include:\n
\n (Optional)\n
\n\n {/* @ts-ignore */}\n
\n
\n\n \n \n cancel$.next()}>Cancel\n \n \n \n )}\n \n );\n};\n","import { openDefaultAnimatedActionModal } from \"shared/components/Modals/AnimatedPendingActionModal\";\nimport {\n COMMON_PENDING_ANIMATION_MESSAGES,\n COUNTY_CRIMINAL_SEARCH_STATUS_ENUM,\n} from \"shared/config/constants\";\nimport useModal from \"shared/hooks/useModal\";\n\nimport { approveDeal } from \"shared/lib/api/dealApi\";\nimport { notifyError } from \"shared/utils/ui\";\n\nimport AssignDealToUnitModal from \"../../../Modal/Deal/AssignDealToUnitModal\";\nimport { useUpload } from \"../hooks\";\nimport { DealSummary } from \"../types\";\n\nexport const useHook = (deal: DealSummary, hide: () => void) => {\n const { openModalDialog, closeActiveModalDialog } = useModal();\n const { uploadFile, attachments } = useUpload();\n\n const showCountyRecordsPendingMessage =\n deal?.countyCriminalSearchStatus?.value ===\n COUNTY_CRIMINAL_SEARCH_STATUS_ENUM.IN_PROGRESS;\n\n const approve = async () => {\n const messages = [...COMMON_PENDING_ANIMATION_MESSAGES, \"Approved!\"];\n\n hide();\n const animatedPendingActionApi = openDefaultAnimatedActionModal(messages);\n try {\n const response = await approveDeal({\n id: deal?.id,\n attachments,\n extraParams: null,\n });\n if (response.status === 200) {\n window?.Intercom?.('trackEvent', 'Deal Decision', {\n deal_ID: deal?.id,\n decision: 'Approve',\n })\n }\n const updatedDeal = response.data;\n const afterAnimatedPendingModalCloseAction = () => {\n // refetchDealRedux();\n if (!updatedDeal.unitListing) {\n openModalDialog(AssignDealToUnitModal, { dealId: deal?.id });\n }\n };\n\n animatedPendingActionApi.finishAnimation(\n afterAnimatedPendingModalCloseAction\n );\n } catch (err: any) {\n const { errors } = err;\n closeActiveModalDialog();\n if (errors?.nonFieldErrors?.length > 0) {\n notifyError(errors?.nonFieldErrors);\n } else {\n notifyError(\"Failed to approve an application.\");\n }\n throw err;\n }\n };\n return { approve, uploadFile, showCountyRecordsPendingMessage };\n};\n","import { createModalContext } from \"shared/components/vero-modal\";\n\nexport const {\n Context: CancelDealModalContext,\n Provider: CancelDealModalProvider,\n useModalContext: useCancelDealModal,\n} = createModalContext();\n","import React from \"react\";\n\nimport { Field, Formik } from \"formik\";\n\nimport styled from \"styled-components\";\n\nimport ApplicantsCheckList from \"shared/components/ApplicantsCheckList\";\nimport { Button, BUTTON_SIZES } from \"shared/components/Button\";\nimport FlexContainer from \"shared/components/FlexContainer\";\n\nimport { RadioGroup, TextArea, UploadWall } from \"shared/components/Form\";\nimport Icon from \"shared/components/Icon\";\nimport { UnderlineLink } from \"shared/components/Links\";\nimport { Popover, PopoverContent } from \"shared/components/Popover\";\nimport Spacer from \"shared/components/Spacer\";\nimport { LargeTitle, RegularText } from \"shared/components/Typography\";\nimport { VeroModal } from \"shared/components/vero-modal\";\n\nimport { FormGroupsCss } from \"shared/styles/commonStyles\";\n\nimport { Subtitle } from \"../styled\";\nimport { DealSummaryWithProperty } from \"../types\";\n\nimport { useCancelDealModal } from \"./context\";\nimport { useHook } from \"./hooks\";\n\nconst Body = styled.div`\n ${\n // @ts-ignore\n FormGroupsCss\n }\n\n .ant-latest-upload-list-picture-card > div:nth-child(2n) {\n margin-right: 0;\n }\n`;\n\ninterface Props {\n deal: DealSummaryWithProperty;\n}\n\nexport const CancelDealModalV2 = ({ deal }: Props) => {\n const {\n onSubmit,\n uploadFile,\n modalExtension,\n title,\n defaultSubmitLabel,\n emailLabel,\n schema,\n } = useHook(deal);\n const state = useCancelDealModal();\n const { cancel$, submit$, submitting } = state;\n\n return (\n submit$.next(onSubmit(values))}\n >\n {({ errors, touched, isValid, submitForm, values }) => (\n \n {title}\n \n Applicants: \n \n \n\n \n\n \n {modalExtension}\n\n \n \n
\n\n {values?.sendEmail && (\n <>\n \n
\n What would you like the body of the email to say?\n {/* @ts-ignore */}\n \n The subject line will read "Your application has\n been canceled"\n \n }\n >\n \n \n
\n\n
\n
\n\n \n
\n Choose which attachments to include:\n
\n\n
\n
\n >\n )}\n \n\n \n \n cancel$.next()}>Cancel\n \n \n \n )}\n \n );\n};\n","import React from \"react\";\n\nimport * as Yup from \"yup\";\n\nimport { YardiCancelDealReasonFormExtension } from \"manager/pages/Marketplace/integrations/yardi/shared\";\n\nimport { cancelDeal } from \"shared/lib/api/dealApi\";\n\nimport { useUpload } from \"../hooks\";\nimport { DealSummaryWithProperty } from \"../types\";\n\nexport type Form = {\n sendEmail?: string;\n emailBody?: string;\n extraParams?: Record;\n};\n\nexport const useHook = (deal: DealSummaryWithProperty) => {\n const { uploadFile, attachments } = useUpload();\n\n const schema = Yup.object().shape({\n sendEmail: Yup.bool().required(\"Choose to send email or not\"),\n emailBody: Yup.string().when(\"sendEmail\", {\n is: true,\n then: Yup.string().required(\"Email body is required\"),\n }),\n });\n\n const unit = deal?.unit;\n const property = deal?.property;\n const modalExtension = (unit || property)?.yardiConnected ? (\n \n ) : null;\n\n const dealId = deal?.id;\n const onSubmit = async (values: Form) => {\n const { sendEmail, emailBody, extraParams } = values;\n await cancelDeal({\n id: dealId,\n sendEmail,\n emailBody,\n attachments,\n extraParams,\n });\n };\n const title = \"Cancel Application\";\n const defaultSubmitLabel = \"Cancel Application\";\n const emailLabel = \"Would you like to send a cancellation email?\";\n return {\n onSubmit,\n uploadFile,\n modalExtension,\n title,\n defaultSubmitLabel,\n emailLabel,\n schema,\n };\n};\n","import { createModalContext } from \"shared/components/vero-modal\";\n\nexport const {\n Context: DeclineDealModalContext,\n Provider: DeclineDealModalProvider,\n useModalContext: useDeclineDealModal,\n} = createModalContext();\n","import React from \"react\";\n\nimport { Formik } from \"formik\";\n\nimport styled from \"styled-components\";\n\nimport ApplicantsCheckList from \"shared/components/ApplicantsCheckList\";\nimport { Button, BUTTON_SIZES } from \"shared/components/Button\";\nimport FlexContainer from \"shared/components/FlexContainer\";\nimport { UploadWall } from \"shared/components/Form/UploadWall\";\nimport { UnderlineLink } from \"shared/components/Links\";\nimport Spacer from \"shared/components/Spacer\";\nimport { LargeTitle, RegularText } from \"shared/components/Typography\";\nimport { VeroModal } from \"shared/components/vero-modal\";\n\nimport { FormGroupsCss } from \"shared/styles/commonStyles\";\n\nimport { Subtitle } from \"../styled\";\n\nimport { DealSummaryWithProperty } from \"../types\";\n\nimport { useDeclineDealModal } from \"./context\";\nimport { useHook } from \"./hooks\";\n\nconst Body = styled.div`\n ${\n // @ts-ignore\n FormGroupsCss\n }\n\n .ant-latest-upload-list-picture-card > div:nth-child(2n) {\n margin-right: 0;\n }\n`;\n\nexport interface DeclineDealModalProps {\n deal: DealSummaryWithProperty;\n}\n\nexport const DeclineDealModalV2 = ({ deal }: DeclineDealModalProps) => {\n const {\n onSubmit,\n uploadFile,\n excludeFile,\n modalExtension,\n title,\n submitLabel,\n } = useHook(deal);\n const state = useDeclineDealModal();\n const { cancel$, submit$, submitting } = state;\n\n return (\n submit$.next(onSubmit(values))}\n >\n {({ submitForm, isValid }) => (\n \n {title}\n \n Applicants: \n \n \n\n \n\n \n {modalExtension}\n \n
\n Choose which attachments to include:\n
\n\n
\n
\n \n\n \n \n {!submitting && (\n cancel$.next()}>\n Cancel\n \n )}\n \n \n \n )}\n \n );\n};\n","import React from \"react\";\n\nimport { YardiDeclineDealReasonFormExtension } from \"manager/pages/Marketplace/integrations/yardi/shared\";\n\nimport { declineDeal } from \"shared/lib/api/dealApi\";\n\nimport { useUpload } from \"../hooks\";\nimport { DealSummaryWithProperty } from \"../types\";\n\nexport const useHook = (deal: DealSummaryWithProperty) => {\n const { uploadFile, excludeFile, attachments } = useUpload();\n const unit = deal?.unit;\n const property = deal?.property;\n const modalExtension = (unit || property)?.yardiConnected ? (\n \n ) : null;\n\n const dealId = deal?.id;\n const onSubmit = async (values) => {\n const { extraParams } = values;\n const response = await declineDeal({\n id: dealId,\n attachments,\n extraParams,\n });\n if (response.status === 200) {\n window?.Intercom?.('trackEvent', 'Deal Decision', {\n deal_ID: dealId,\n decision: 'Decline',\n })\n }\n };\n const title = \"Decline Application\";\n const submitLabel = \"Decline Application\";\n return {\n onSubmit,\n uploadFile,\n excludeFile,\n modalExtension,\n title,\n submitLabel,\n };\n};\n","import * as Yup from \"yup\";\n\nimport { VALIDATION_MESSAGES } from \"shared/config/constants\";\n\nexport const initialValues = {\n formIncome: null,\n};\n\nexport const validationSchema = Yup.object().shape({\n formIncome: Yup.number()\n .integer()\n .required(VALIDATION_MESSAGES.fieldRequired)\n .nullable(),\n});\n","import { createModalContext } from \"shared/components/vero-modal\";\n\nimport { UpdateIncomeProps } from \"../../types\";\n\nexport const {\n Context: EditIncomeModalContext,\n Provider: EditIncomeModalProvider,\n useModalContext: useEditIncomeModal,\n} = createModalContext();\n","import styled from \"@emotion/styled\";\n\nimport BaseWell from \"shared/components/Well\";\nimport { COLORS } from \"shared/config/constants\";\n\nexport const Well = styled(BaseWell)`\n margin: 24px 0;\n padding: 20px;\n background-color: ${COLORS.backgroundGrey2};\n\n & > * {\n display: block;\n }\n\n .applicant-name {\n color: ${COLORS.lightViolet};\n }\n\n .income {\n color: ${COLORS.darkViolet3};\n }\n`;\n","\nimport { Formik } from \"formik\";\n\nimport { Button } from \"shared/components/Button\";\nimport FlexContainer from \"shared/components/FlexContainer\";\nimport { MaskedInput } from \"shared/components/Form\";\nimport { UnderlineLink } from \"shared/components/Links\";\n\nimport Spacer from \"shared/components/Spacer\";\nimport {\n LargeTitle,\n RegularText,\n SmallText,\n} from \"shared/components/Typography\";\nimport { VeroModal } from \"shared/components/vero-modal\";\n\nimport { printDollars } from \"shared/utils/dollar-print\";\nimport { initialValues, validationSchema } from \"./config\";\nimport { useEditIncomeModal } from \"./context\";\nimport { Well } from \"./styled\";\n\ninterface EditIncomeModalProps {\n income: number;\n statedIncome: number;\n applicantName: string;\n applicantId: string | number;\n}\n\nexport const EditIncomeModal = ({\n income,\n statedIncome,\n applicantName,\n applicantId,\n}: EditIncomeModalProps) => {\n const state = useEditIncomeModal();\n const { ok$, cancel$ } = state;\n\n return (\n \n ok$.next({ income: formIncome / 100, applicantId: String(applicantId) })\n }\n >\n {({ submitForm }) => (\n \n Edit Income\n \n Enter a new amount in the box below to override the current VEROfied\n Income\n \n\n \n \n {applicantName.toLocaleUpperCase()}\n \n \n VEROfied Income: {printDollars(income)}\n \n \n Stated Income: {printDollars(statedIncome)}\n \n \n\n {/* @ts-ignore */}\n \n\n \n \n cancel$.next()}>Cancel\n \n \n \n )}\n \n );\n};\n","import { createModalContext } from \"shared/components/vero-modal\";\n\nexport const {\n Context: FraudIndicatorsModalContext,\n Provider: FraudIndicatorsModalProvider,\n useModalContext: useFraudIndicatorsModal,\n} = createModalContext();\n","import styled from \"@emotion/styled\";\n\nimport { MEDIA_QUERIES } from \"shared/config/constants\";\n\nconst Attachment = styled(\"div\")((props) => ({\n display: \"flex\",\n ...(!props.disabled && {\n marginBottom: \"12px\",\n }),\n [MEDIA_QUERIES.w.ltSm]: {\n width: \"100%\",\n },\n}));\n\nconst InputContainer = styled(\"div\")({\n [MEDIA_QUERIES.w.ltSm]: {\n flexGrow: 1,\n },\n});\n\nconst DeleteIconContainer = styled(\"div\")({\n display: \"flex\",\n alignItems: \"center\",\n marginLeft: \"8px\",\n});\n\nexport { Attachment, DeleteIconContainer, InputContainer };\n","import styled from \"@emotion/styled\";\n\nimport BaseWell from \"shared/components/Well\";\nimport { COLORS } from \"shared/config/constants\";\n\nexport const FraudIndicatorsNumber = styled.span`\n color: ${COLORS.dangerRed};\n`;\n\nexport const Well = styled(BaseWell)`\n padding: 16px 35px 4px 20px;\n background-color: ${COLORS.backgroundGrey2};\n\n .title {\n gap: 10px;\n color: ${COLORS.lightViolet};\n }\n\n .description {\n color: ${COLORS.lightViolet3};\n margin-left: 24px;\n margin-bottom: 16px;\n }\n`;\n","import React from \"react\";\n\nimport { Field, useFormikContext } from \"formik\";\n\nimport { Input } from \"shared/components/Form\";\nimport Icon from \"shared/components/Icon\";\n\nimport { Attachment, DeleteIconContainer, InputContainer } from \"./styled\";\n\ntype Props = {\n disabled: boolean;\n remove: (index: number) => any;\n index: number;\n errors?: Record;\n // eslint-disable-next-line react/no-unused-prop-types\n name?: string;\n};\n\nconst AddAttachmentsForm = ({ index, remove, disabled, errors }: Props) => {\n const { values } = useFormikContext();\n const attachments = values?.applicants?.[index]?.additionalAttachments;\n\n return (\n <>\n {attachments?.map((_, i) => (\n // @ts-ignore\n \n {i > 0 &&
}\n \n \n \n {attachments?.length > 1 && (\n \n remove(i)}\n data-testid={`delete-icon-${index}-${i}`}\n />\n \n )}\n \n ))}\n >\n );\n};\n\nexport default AddAttachmentsForm;\n","import React from \"react\";\n\nimport { UnderlineLink } from \"shared/components/Links\";\n\nconst AddAttachmentsLink = ({\n addAttachment,\n}: {\n addAttachment: (attachment: string) => void;\n}) => {\n return (\n addAttachment(\"\")} dashed>\n + Attachment\n \n );\n};\n\nexport default AddAttachmentsLink;\n","import React from \"react\";\n\nimport { Field, FieldArray, FormikErrors, useFormikContext } from \"formik\";\n\nimport {\n AddAttachmentsForm,\n AddAttachmentsLink,\n} from \"manager/components/Form/AddAttachmentsForm\";\nimport ErrorList from \"shared/components/ErrorList\";\nimport { Checkbox, TextArea } from \"shared/components/Form\";\n\nimport { Attachments } from \"../styled\";\n\nimport { Form } from \"./types\";\n\ntype Props = {\n index: number;\n};\nconst ConditionallyApproveForm = ({ index }: Props) => {\n const { values, errors } = useFormikContext