From 161fef54761b347f6b82a9bcedb1fe38d2f1b337 Mon Sep 17 00:00:00 2001 From: Emily Jablonski <65367387+emilyjablonski@users.noreply.github.com> Date: Wed, 24 Jul 2024 09:09:47 -0600 Subject: [PATCH] feat: export with terms for partners (#4218) --- .../__tests__/pages/listings/lottery.test.tsx | 48 +++++++++++++++ .../locale_overrides/general.json | 2 + .../src/pages/listings/[id]/lottery.tsx | 60 ++++++++++++++++++- sites/partners/styles/lottery.module.scss | 6 ++ 4 files changed, 115 insertions(+), 1 deletion(-) diff --git a/sites/partners/__tests__/pages/listings/lottery.test.tsx b/sites/partners/__tests__/pages/listings/lottery.test.tsx index f7a4931ce8..34e440029c 100644 --- a/sites/partners/__tests__/pages/listings/lottery.test.tsx +++ b/sites/partners/__tests__/pages/listings/lottery.test.tsx @@ -558,6 +558,54 @@ describe("lottery", () => { expect(getAllByText("Export")).toHaveLength(2) }) + it("should show export with terms modal if user is a partner", async () => { + mockNextRouter({ id: "Uvbk5qurpB2WI9V6WnNdH" }) + document.cookie = "access-token-available=True" + server.use( + rest.get("http://localhost/api/adapter/user", (_req, res, ctx) => { + return res( + ctx.json({ + id: "user1", + userRoles: { isAdmin: false, isPartner: true }, + listings: [{ id: "Uvbk5qurpB2WI9V6WnNdH" }], + }) + ) + }), + rest.post("http://localhost:3100/auth/token", (_req, res, ctx) => { + return res(ctx.json("")) + }), + rest.get("http://localhost/api/adapter/applicationFlaggedSets/meta", (_req, res, ctx) => { + return res(ctx.json({ totalCount: 5, totalPendingCount: 5 })) + }) + ) + + const updatedListing = { + ...listing, + lotteryLastRunAt: new Date("September 6, 2025 8:15:00"), + lotteryStatus: LotteryStatusEnum.publishedToPublic, + } + const { getByText, findByText, findAllByText, getAllByText } = render( + + ) + + const header = await findByText("Partners Portal") + expect(header).toBeInTheDocument() + + fireEvent.click(getByText("Export")) + expect(await findAllByText("Export lottery data")).toHaveLength(2) + + expect( + getByText("This data was generated from the lottery that was run on 09/06/2025 at 8:15 am.", { + exact: false, + }) + ).toBeInTheDocument() + expect( + getByText("You must accept the Terms of Use before exporting this data.") + ).toBeInTheDocument() + + expect(getAllByText("Export")).toHaveLength(2) + }) + it("should show no lottery released state as a partner", async () => { mockNextRouter({ id: "Uvbk5qurpB2WI9V6WnNdH" }) document.cookie = "access-token-available=True" diff --git a/sites/partners/page_content/locale_overrides/general.json b/sites/partners/page_content/locale_overrides/general.json index 0f774c34a2..7a7e9a91e4 100644 --- a/sites/partners/page_content/locale_overrides/general.json +++ b/sites/partners/page_content/locale_overrides/general.json @@ -257,6 +257,8 @@ "listings.lottery.runLottery": "Run lottery", "listings.lottery.runLotteryContent": "Make sure to add all paper applications before running the lottery.", "listings.lottery.runLotteryDuplicates": "Run lottery without resolving duplicates", + "listings.lottery.terms": "I acknowledge that downloading and using the information contained in the Application(s), Excel or CSV files is subject to the Terms of Use, and further, the use, storage, possession and retention of personal identifiable information contained in the Application is subject to state and federal privacy laws. I agree on behalf of the Local Government or Professional Partner that such Professional Partner or Local Government will comply with the Terms of Use and applicable state and federal privacy laws in viewing, using, storing and possessing the Application and the information contained therein. I warrant that I am authorized to enter into agreements such as the Terms of Use on behalf of such Professional Partner or Local Government. I agree to review for accuracy the spreadsheet(s) I download, per the guidance in the Partners Manual, and to notify staff of any errors within 30 days of the close of the listing, or if a lottery will be conducted, at least three working days before the lottery is scheduled to be conducted.", + "listings.lottery.termsAccept": "You must accept the Terms of Use before exporting this data.", "listings.lotteryDateNotes": "Lottery Date Notes", "listings.lotteryDateQuestion": "When will the lottery be run?", "listings.lotteryEndTime": "Lottery End Time", diff --git a/sites/partners/src/pages/listings/[id]/lottery.tsx b/sites/partners/src/pages/listings/[id]/lottery.tsx index a22280978b..291a94ba3a 100644 --- a/sites/partners/src/pages/listings/[id]/lottery.tsx +++ b/sites/partners/src/pages/listings/[id]/lottery.tsx @@ -5,6 +5,7 @@ import dayjs from "dayjs" import Ticket from "@heroicons/react/24/solid/TicketIcon" import Download from "@heroicons/react/24/solid/ArrowDownTrayIcon" import ExclamationCirleIcon from "@heroicons/react/24/solid/ExclamationCircleIcon" +import Markdown from "markdown-to-jsx" import { t, Breadcrumbs, BreadcrumbLink } from "@bloom-housing/ui-components" import { Button, Card, Dialog, Heading, Icon, Message } from "@bloom-housing/ui-seeds" import { CardHeader, CardSection } from "@bloom-housing/ui-seeds/src/blocks/Card" @@ -37,6 +38,7 @@ const Lottery = (props: { listing: Listing }) => { const [reRunModal, setReRunModal] = useState(false) const [releaseModal, setReleaseModal] = useState(false) const [exportModal, setExportModal] = useState(false) + const [termsExportModal, setTermsExportModal] = useState(false) const [publishModal, setPublishModal] = useState(false) const [retractModal, setRetractModal] = useState(false) const [newApplicationsModal, setNewApplicationsModal] = useState(false) @@ -82,7 +84,16 @@ const Lottery = (props: { listing: Listing }) => { : t("listings.lottery.exportFileNoPreferences")}
-
@@ -597,6 +608,53 @@ const Lottery = (props: { listing: Listing }) => { + setTermsExportModal(false)} + > + + {t("listings.lottery.export")} + + +

+ {listing.listingMultiselectQuestions.length + ? t("listings.lottery.exportFile") + : t("listings.lottery.exportFileNoPreferences")}{" "} + {t("listings.lottery.exportContentTimestamp", { + date: dayjs(listing.lotteryLastRunAt).format("MM/DD/YYYY"), + time: dayjs(listing.lotteryLastRunAt).format("h:mm a"), + })} +

+

{t("listings.lottery.termsAccept")}

+

+ {t("authentication.terms.termsOfUse")} +

+ {t("listings.lottery.terms")} +
+ + + + +