diff --git a/shared-helpers/src/locales/es.json b/shared-helpers/src/locales/es.json index 5244778caf..3959f6dabb 100644 --- a/shared-helpers/src/locales/es.json +++ b/shared-helpers/src/locales/es.json @@ -497,6 +497,7 @@ "listings.buildingSelectionCriteria": "Selección de criterios de Edificio", "listings.cc&rDescription": "Los CC&R's explican las reglas de la asociación de propietarios de viviendas, y limitan la manera en que usted puede modificar la propiedad.", "listings.cc&r": "Convenios, Condiciones y Restricciones (CC&R's)", + "listings.chooseALanguage": "Elige un idioma", "listings.closedListings": "Listados cerrados", "listings.closed": "Cerrado", "listings.comingSoon": "Próximamente", @@ -701,6 +702,7 @@ "t.delete": "Borrar", "t.deposit": "Depósito", "t.description": "Ingrese descripción", + "t.download": "Descargar", "t.dragFilesHere": "Arrastre los archivos aquí", "t.dropFilesHere": "Suelta los archivos aquí...", "t.edit": "Editar", diff --git a/shared-helpers/src/locales/general.json b/shared-helpers/src/locales/general.json index e1974e1d04..0dc9fdea05 100644 --- a/shared-helpers/src/locales/general.json +++ b/shared-helpers/src/locales/general.json @@ -641,6 +641,7 @@ "listings.buildingSelectionCriteria": "Building Criteria Selection", "listings.cc&r": "Covenants, Conditions and Restrictions (CC&R's)", "listings.cc&rDescription": "The CC&R's explain the rules of the homeowners' association, and restrict how you can modify the property.", + "listings.chooseALanguage": "Choose a language", "listings.closed": "Closed", "listings.closedListings": "Closed Listings", "listings.comingSoon": "Coming Soon", @@ -885,6 +886,7 @@ "t.delete": "Delete", "t.deposit": "Deposit", "t.description": "Enter Description", + "t.download": "Download", "t.dragFilesHere": "Drag files here", "t.dropFilesHere": "Drop files here…", "t.edit": "Edit", diff --git a/shared-helpers/src/locales/tl.json b/shared-helpers/src/locales/tl.json index d45e4e3645..7b2aa0c372 100644 --- a/shared-helpers/src/locales/tl.json +++ b/shared-helpers/src/locales/tl.json @@ -432,6 +432,7 @@ "listings.buildingSelectionCriteria": "Pagpili sa Criteria ng Gusali", "listings.cc&rDescription": "Ipinapaliwanag ng CC&R ang mga patakaran ng samahan ng mga may-ari ng bahay_ at pinaghihigpitan kung paano mo mababago ang ari-arian.", "listings.cc&r": "Mga Kasunduan_ Kundisyon at Pagbabawal o Covenants_ Conditions and Restrictions (CC&R's)", + "listings.chooseALanguage": "Pumili ng wika", "listings.closedListings": "Sarado nang mga Listahan", "listings.closed": "Sarado na", "listings.comingSoon": "Malapit Na", @@ -571,6 +572,7 @@ "t.delete": "Tanggalin", "t.deposit": "Deposito", "t.description": "Ilagay ang Deskripsyon", + "t.download": "I-download", "t.dragFilesHere": "Hilahin ang mga file dito", "t.dropFilesHere": "I-drop ang mga file dito…", "t.edit": "I-edit", diff --git a/shared-helpers/src/locales/vi.json b/shared-helpers/src/locales/vi.json index 79ccb53b51..1bd65c6291 100644 --- a/shared-helpers/src/locales/vi.json +++ b/shared-helpers/src/locales/vi.json @@ -474,6 +474,7 @@ "listings.buildingSelectionCriteria": "Lựa chọn tiêu chí xây dựng", "listings.cc&rDescription": "CC&R's giải thích các quy tắc của hiệp hội chủ nhà và hạn chế cách quý vị có thể sửa chữa bất động sản.", "listings.cc&r": "Giao ước, Điều kiện và Hạn chế (CC&R's)", + "listings.chooseALanguage": "Chọn một ngôn ngữ", "listings.closedListings": "Các Danh sách nhà đã Đóng", "listings.closed": "Đã đóng", "listings.comingSoon": "Sắp có", @@ -678,6 +679,7 @@ "t.delete": "Xóa", "t.deposit": "Đặt cọc", "t.description": "Nhập mô tả", + "t.download": "Tải xuống", "t.dragFilesHere": "Kéo tệp vào đây", "t.dropFilesHere": "Thả tệp vào đây...", "t.edit": "Hiệu đính", diff --git a/shared-helpers/src/locales/zh.json b/shared-helpers/src/locales/zh.json index 1a4fc4aa7b..e4d1129d8c 100644 --- a/shared-helpers/src/locales/zh.json +++ b/shared-helpers/src/locales/zh.json @@ -479,6 +479,7 @@ "listings.buildingSelectionCriteria": "建物標準選擇", "listings.cc&rDescription": "CC&R's 旨在說明業主協會的規則,以及您可如何改裝物業的限制。", "listings.cc&r": "契約、條件及限制 (Covenants, Conditions and Restrictions,簡稱 CC&R's)", + "listings.chooseALanguage": "选择语言", "listings.closedListings": "已截止申請的上市名單", "listings.closed": "已關閉", "listings.comingSoon": "即將上市!", @@ -683,6 +684,7 @@ "t.delete": "刪除", "t.deposit": "訂金", "t.description": "輸入說明", + "t.download": "下載", "t.dragFilesHere": "拖曳檔案到這裡", "t.dropFilesHere": "將檔案放置在這裡…", "t.edit": "編輯", diff --git a/sites/public/__tests__/components/listing/GetApplication.test.tsx b/sites/public/__tests__/components/listing/GetApplication.test.tsx index 8934748b42..098e9657df 100644 --- a/sites/public/__tests__/components/listing/GetApplication.test.tsx +++ b/sites/public/__tests__/components/listing/GetApplication.test.tsx @@ -26,6 +26,7 @@ describe("", () => { zipCode: "90210", }} preview={false} + listingName={"Listing name"} /> ) expect(getByText("How to Apply")).toBeTruthy() @@ -55,11 +56,12 @@ describe("", () => { zipCode: "90210", }} preview={false} + listingName={"Listing name"} /> ) expect(queryByTestId("get-application-section")).toBeNull() }) - it("disables buttons in preview state", () => { + it("disables apply online button in preview state", () => { const { getByText } = render( ", () => { zipCode: "90210", }} preview={true} + listingName={"Listing name"} /> ) expect(getByText("Apply Online").closest("button")?.disabled).toBe(true) - expect(getByText("Download Application").closest("button")?.disabled).toBe(true) }) it("hides buttons if application is not open", () => { const { getByText, queryByText } = render( @@ -106,6 +108,7 @@ describe("", () => { zipCode: "90210", }} preview={false} + listingName={"Listing name"} /> ) expect(queryByText("Apply Online")).toBe(null) diff --git a/sites/public/src/components/listing/GetApplication.tsx b/sites/public/src/components/listing/GetApplication.tsx index 8243b5a4e5..92099c9d35 100644 --- a/sites/public/src/components/listing/GetApplication.tsx +++ b/sites/public/src/components/listing/GetApplication.tsx @@ -1,5 +1,6 @@ import React, { useState } from "react" import Markdown from "markdown-to-jsx" +import { useForm } from "react-hook-form" import { Button, LinkButton, @@ -9,7 +10,12 @@ import { t, OrDivider, ContactAddress, + Modal, + AppearanceSizeType, + Form, + FieldGroup, } from "@bloom-housing/ui-components" +import { downloadExternalPDF } from "../../lib/helpers" export interface PaperApplication { fileURL: string @@ -25,6 +31,8 @@ export interface ApplicationsProps { applicationsOpen: boolean /** The date applications open */ applicationsOpenDate?: string + /** The name of the listing */ + listingName: string /** The URL for an online applications */ onlineApplicationURL?: string /** Any number of paper application objects, including their URL and language */ @@ -51,8 +59,14 @@ const GetApplication = (props: ApplicationsProps) => { const showSection = props.onlineApplicationURL || (props.applicationsOpen && props.paperMethod && !!props.paperApplications?.length) - const [showDownload, setShowDownload] = useState(false) - const toggleDownload = () => setShowDownload(!showDownload) + const [showDownloadModal, setShowDownloadModal] = useState(false) + + // eslint-disable-next-line @typescript-eslint/unbound-method + const { register, watch } = useForm() + const paperApplicationURL: string = watch( + "paperApplicationLanguage", + props.paperApplications?.length ? props.paperApplications[0].fileURL : undefined + ) if (!showSection) return null @@ -96,29 +110,18 @@ const GetApplication = (props: ApplicationsProps) => { {props.strings?.getAPaperApplication ?? t("listings.apply.getAPaperApplication")} )} - {showDownload && - props.paperApplications?.map((paperApplication: PaperApplication, index: number) => ( -

- - {paperApplication.languageString} - -

- ))} {props.applicationPickUpAddress && ( <> {props.applicationsOpen && (props.onlineApplicationURL || props.paperMethod) && ( @@ -146,6 +149,53 @@ const GetApplication = (props: ApplicationsProps) => { )} )} + setShowDownloadModal(false)} + actions={[ + , + , + ]} + > +
+
+ {t("listings.chooseALanguage")} + ({ + id: app.languageString, + label: app.languageString, + value: app.fileURL, + defaultChecked: index === 0, + }))} + dataTestId={"paper-application-language"} + /> +
+
+
) } diff --git a/sites/public/src/components/listing/ListingView.tsx b/sites/public/src/components/listing/ListingView.tsx index e486060780..0e4e56f16e 100644 --- a/sites/public/src/components/listing/ListingView.tsx +++ b/sites/public/src/components/listing/ListingView.tsx @@ -360,6 +360,7 @@ export const ListingView = (props: ListingProps) => { applicationPickUpAddressOfficeHours={listing.applicationPickUpAddressOfficeHours} applicationPickUpAddress={getAddress(listing.applicationPickUpAddressType, "pickUp")} preview={props.preview} + listingName={listing.name} /> {!( listing.status === ListingStatus.closed || diff --git a/sites/public/src/lib/helpers.tsx b/sites/public/src/lib/helpers.tsx index 8b891ded78..6d3dd6cc4f 100644 --- a/sites/public/src/lib/helpers.tsx +++ b/sites/public/src/lib/helpers.tsx @@ -210,3 +210,27 @@ export const untranslateMultiselectQuestion = ( } }) } + +export const downloadExternalPDF = async (fileURL: string, fileName: string) => { + try { + await fetch(fileURL, { + method: "GET", + headers: { + "Content-Type": "application/pdf", + }, + }) + .then((response) => response.blob()) + .then((blob) => { + const url = window.URL.createObjectURL(new Blob([blob])) + const link = document.createElement("a") + link.href = url + link.setAttribute("download", `${fileName}.pdf`) + + document.body.appendChild(link) + link.click() + link.parentNode.removeChild(link) + }) + } catch (err) { + console.log(err) + } +}