From 4d431ade8ec1d563b01abe97193df3e1b1d5fe3e Mon Sep 17 00:00:00 2001 From: Emily Jablonski <65367387+emilyjablonski@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:11:41 -0600 Subject: [PATCH] feat: public account lottery view (#4255) --- shared-helpers/src/locales/es.json | 13 ++ shared-helpers/src/locales/general.json | 13 ++ shared-helpers/src/locales/tl.json | 13 ++ shared-helpers/src/locales/vi.json | 13 ++ shared-helpers/src/locales/zh.json | 13 ++ .../src/scripts/get-machine-translations.ts | 5 +- .../account/ApplicationCards.module.scss | 14 ++ .../components/account/ApplicationCards.tsx | 43 +++++ .../components/account/StatusItem.module.scss | 1 + .../src/components/account/StatusItem.tsx | 10 ++ .../components/account/StatusItemWrapper.tsx | 12 +- .../applications/SubmittedApplicationView.tsx | 22 +-- .../application/{[id].tsx => [id]/index.tsx} | 36 +--- .../application/[id]/lottery-results.tsx | 169 ++++++++++++++++++ .../public/styles/lottery-results.module.scss | 79 ++++++++ 15 files changed, 402 insertions(+), 54 deletions(-) create mode 100644 sites/public/src/components/account/ApplicationCards.module.scss create mode 100644 sites/public/src/components/account/ApplicationCards.tsx rename sites/public/src/pages/account/application/{[id].tsx => [id]/index.tsx} (56%) create mode 100644 sites/public/src/pages/account/application/[id]/lottery-results.tsx create mode 100644 sites/public/styles/lottery-results.module.scss diff --git a/shared-helpers/src/locales/es.json b/shared-helpers/src/locales/es.json index 56ed9f10bf..b269e7c3db 100644 --- a/shared-helpers/src/locales/es.json +++ b/shared-helpers/src/locales/es.json @@ -5,6 +5,19 @@ "account.allMyApplications": "Todas mis aplicaciones", "account.application.confirmation": "Confirmación", "account.application.error": "Error", + "account.application.lottery.applicantList": "De %{applicants} solicitantes en esta lista", + "account.application.lottery.next": "El administrador de la propiedad se comunicará con los solicitantes en orden de preferencia. Comenzarán con la prioridad más alta. Si el administrador de la propiedad se comunica con usted, le pedirá que proporcione documentación para respaldar lo que respondió en la solicitud. Esa documentación podría incluir recibos de sueldo, por ejemplo. También es posible que necesiten recopilar más información pidiéndole que complete una solicitud complementaria.", + "account.application.lottery.nextHeader": "¿Qué pasa después?", + "account.application.lottery.preferences": "Las preferencias de lotería para su solicitud se muestran aquí en orden de prioridad. Si no califica para ninguna preferencia de lotería, formará parte de la categoría de lotería general. La categoría de lotería general es el último grupo procesado.", + "account.application.lottery.preferencesButton": "¿Qué son las preferencias de lotería?", + "account.application.lottery.preferencesHeader": "Sus preferencias de lotería", + "account.application.lottery.preferencesMessage": "Estos resultados se basan en la información que proporcionó en su solicitud. La elegibilidad para la preferencia está sujeta a cambios una vez que se verifique su información.", + "account.application.lottery.rawRank": "La clasificación bruta es el orden aleatorio básico de todas las solicitudes recibidas para la lista antes de que se apliquen las preferencias. Por ejemplo, si se envían 1000 solicitudes, a cada una se le asignará una clasificación bruta de 1 a 1000.", + "account.application.lottery.rawRankButton": "¿Qué es el rango bruto?", + "account.application.lottery.rawRankHeader": "Tu rango bruto", + "account.application.lottery.resultsHeader": "Aquí están tus resultados de lotería", + "account.application.lottery.resultsSubheader": "Se enviaron %{applications} solicitudes para %{units} unidades", + "account.application.lottery.viewResults": "Ver resultados de lotería", "account.application.noAccessError": "Usted no está autorizado para ver esta aplicación", "account.application.noApplicationError": "No existe ninguna aplicación con esa ID", "account.application.return": "Volver a las solicitudes", diff --git a/shared-helpers/src/locales/general.json b/shared-helpers/src/locales/general.json index e8d9f72138..a587030930 100644 --- a/shared-helpers/src/locales/general.json +++ b/shared-helpers/src/locales/general.json @@ -5,6 +5,19 @@ "account.allMyApplications": "All my applications", "account.application.confirmation": "Confirmation", "account.application.error": "Error", + "account.application.lottery.applicantList": "Out of %{applicants} applicants on this list", + "account.application.lottery.next": "The property manager will contact applicants in preference order. They will start with the highest priority preference. If the property manager contacts you, they will ask you to provide documentation to support what you answered in the application. That documentation could include paystubs, for example. They might also need to gather more information by asking you to complete a supplemental application.", + "account.application.lottery.nextHeader": "What happens next?", + "account.application.lottery.preferences": "Lottery preferences for your application are shown here in priority order. If you do not qualify for any lottery preferences, you will be part of the general lottery category. The general lottery category is the last group processed.", + "account.application.lottery.preferencesButton": "What are lottery preferences?", + "account.application.lottery.preferencesHeader": "Your lottery preference(s)", + "account.application.lottery.preferencesMessage": "These results are based on the information you provided in your application. Preference eligibility is subject to change once your information is verified.", + "account.application.lottery.rawRank": "Raw rank is the basic randomized order of all applications received for the listing before the preferences are applied. For example, if 1,000 applications are submitted, each will be assigned a raw rank of 1 to 1,000.", + "account.application.lottery.rawRankButton": "What is raw rank?", + "account.application.lottery.rawRankHeader": "Your raw rank", + "account.application.lottery.resultsHeader": "Here are your lottery results", + "account.application.lottery.resultsSubheader": "%{applications} applications were submitted for %{units} units", + "account.application.lottery.viewResults": "View lottery results", "account.application.noAccessError": "You are unauthorized to view this application", "account.application.noApplicationError": "No application with that ID exists", "account.application.return": "Return to applications", diff --git a/shared-helpers/src/locales/tl.json b/shared-helpers/src/locales/tl.json index 281d043270..8660bb4b05 100644 --- a/shared-helpers/src/locales/tl.json +++ b/shared-helpers/src/locales/tl.json @@ -5,6 +5,19 @@ "account.allMyApplications": "Lahat ng aking mga aplikasyon", "account.application.confirmation": "Kumpirmasyon", "account.application.error": "Error", + "account.application.lottery.applicantList": "Sa %{applicants} na mga aplikante sa listahang ito", + "account.application.lottery.next": "Makikipag-ugnayan ang property manager sa mga aplikante sa preference order. Magsisimula sila sa pinakamataas na priority preference. Kung makikipag-ugnayan sa iyo ang tagapamahala ng ari-arian, hihilingin ka nilang magbigay ng dokumentasyon upang suportahan ang iyong sinagot sa aplikasyon. Maaaring kasama sa dokumentasyong iyon ang mga paystub, halimbawa. Maaaring kailanganin din nilang mangalap ng higit pang impormasyon sa pamamagitan ng paghiling sa iyo na kumpletuhin ang isang karagdagang aplikasyon.", + "account.application.lottery.nextHeader": "Ano ang susunod na mangyayari?", + "account.application.lottery.preferences": "Ang mga kagustuhan sa lottery para sa iyong aplikasyon ay ipinapakita dito sa priority order. Kung hindi ka kwalipikado para sa anumang mga kagustuhan sa lottery, ikaw ay magiging bahagi ng pangkalahatang kategorya ng lottery. Ang pangkalahatang kategorya ng lottery ay ang huling pangkat na naproseso.", + "account.application.lottery.preferencesButton": "Ano ang mga kagustuhan sa lottery?", + "account.application.lottery.preferencesHeader": "Ang iyong (mga) kagustuhan sa lottery", + "account.application.lottery.preferencesMessage": "Ang mga resultang ito ay batay sa impormasyong ibinigay mo sa iyong aplikasyon. Maaaring magbago ang pagiging karapat-dapat sa kagustuhan kapag na-verify na ang iyong impormasyon.", + "account.application.lottery.rawRank": "Ang Raw rank ay ang pangunahing randomized na pagkakasunud-sunod ng lahat ng mga application na natanggap para sa listahan bago ilapat ang mga kagustuhan. Halimbawa, kung 1,000 na aplikasyon ang isinumite, ang bawat isa ay bibigyan ng isang raw na ranggo na 1 hanggang 1,000.", + "account.application.lottery.rawRankButton": "Ano ang hilaw na ranggo?", + "account.application.lottery.rawRankHeader": "Ang ranggo mo raw", + "account.application.lottery.resultsHeader": "Narito ang mga resulta ng iyong lottery", + "account.application.lottery.resultsSubheader": "%{applications} applications ay isinumite para sa %{units} units", + "account.application.lottery.viewResults": "Tingnan ang mga resulta ng lottery", "account.application.noAccessError": "Hindi ka pinapayagang makita ang application na ito", "account.application.noApplicationError": "Walang application gamit ang ID na iyan", "account.application.return": "Balikan ang mga application", diff --git a/shared-helpers/src/locales/vi.json b/shared-helpers/src/locales/vi.json index 1796d7e556..88d79bb884 100644 --- a/shared-helpers/src/locales/vi.json +++ b/shared-helpers/src/locales/vi.json @@ -5,6 +5,19 @@ "account.allMyApplications": "Tất cả các ứng dụng của tôi", "account.application.confirmation": "Xác nhận", "account.application.error": "Lỗi", + "account.application.lottery.applicantList": "Trong số %{applicants} ứng viên trong danh sách này", + "account.application.lottery.next": "Người quản lý bất động sản sẽ liên hệ với người nộp đơn theo thứ tự ưu tiên. Họ sẽ bắt đầu với ưu tiên có mức độ ưu tiên cao nhất. Nếu người quản lý bất động sản liên hệ với bạn, họ sẽ yêu cầu bạn cung cấp tài liệu để hỗ trợ những gì bạn đã trả lời trong đơn. Tài liệu đó có thể bao gồm phiếu lương, ví dụ. Họ cũng có thể cần thu thập thêm thông tin bằng cách yêu cầu bạn hoàn thành đơn bổ sung.", + "account.application.lottery.nextHeader": "Chuyện gì xảy ra tiếp theo?", + "account.application.lottery.preferences": "Các ưu tiên xổ số cho đơn đăng ký của bạn được hiển thị ở đây theo thứ tự ưu tiên. Nếu bạn không đủ điều kiện cho bất kỳ ưu tiên xổ số nào, bạn sẽ thuộc danh mục xổ số chung. Danh mục xổ số chung là nhóm cuối cùng được xử lý.", + "account.application.lottery.preferencesButton": "Sở thích xổ số là gì?", + "account.application.lottery.preferencesHeader": "Sở thích xổ số của bạn", + "account.application.lottery.preferencesMessage": "Những kết quả này dựa trên thông tin bạn cung cấp trong đơn đăng ký. Điều kiện ưu tiên có thể thay đổi sau khi thông tin của bạn được xác minh.", + "account.application.lottery.rawRank": "Xếp hạng thô là thứ tự ngẫu nhiên cơ bản của tất cả các đơn đăng ký nhận được cho danh sách trước khi các ưu tiên được áp dụng. Ví dụ, nếu 1.000 đơn đăng ký được gửi, mỗi đơn sẽ được chỉ định thứ hạng thô từ 1 đến 1.000.", + "account.application.lottery.rawRankButton": "Xếp hạng thô là gì?", + "account.application.lottery.rawRankHeader": "Xếp hạng thô của bạn", + "account.application.lottery.resultsHeader": "Đây là kết quả xổ số của bạn", + "account.application.lottery.resultsSubheader": "%{applications} đơn xin đã được nộp cho %{units} đơn vị", + "account.application.lottery.viewResults": "Xem kết quả xổ số", "account.application.noAccessError": "Quý vị không được phép xem đơn đăng ký này", "account.application.noApplicationError": "Không tồn tại đơn đăng ký nào có ID đó", "account.application.return": "Quay lại đơn đăng ký", diff --git a/shared-helpers/src/locales/zh.json b/shared-helpers/src/locales/zh.json index c67de9bfaf..7e1ddd2923 100644 --- a/shared-helpers/src/locales/zh.json +++ b/shared-helpers/src/locales/zh.json @@ -5,6 +5,19 @@ "account.allMyApplications": "我的所有申请", "account.application.confirmation": "確認", "account.application.error": "錯誤", + "account.application.lottery.applicantList": "此列表中的 %{applicants} 名申请人中", + "account.application.lottery.next": "物业经理将按优先顺序联系申请人。他们将从优先级最高的申请人开始。如果物业经理联系您,他们会要求您提供文件来支持您在申请中回答的内容。例如,该文件可能包括工资单。他们可能还需要通过要求您填写补充申请来收集更多信息。", + "account.application.lottery.nextHeader": "接下来会发生什么?", + "account.application.lottery.preferences": "此处按优先顺序显示您申请的抽签偏好。如果您不符合任何抽签偏好,您将属于一般抽签类别。一般抽签类别是最后处理的组。", + "account.application.lottery.preferencesButton": "彩票偏好是什么?", + "account.application.lottery.preferencesHeader": "您的彩票偏好", + "account.application.lottery.preferencesMessage": "这些结果基于您在申请中提供的信息。您的信息经过验证后,优先资格可能会发生变化。", + "account.application.lottery.rawRank": "原始排名是应用偏好之前收到的所有申请的基本随机顺序。例如,如果提交了 1,000 份申请,则每份申请都会被分配 1 到 1,000 的原始排名。", + "account.application.lottery.rawRankButton": "什么是原始排名?", + "account.application.lottery.rawRankHeader": "您的原始排名", + "account.application.lottery.resultsHeader": "这是您的彩票结果", + "account.application.lottery.resultsSubheader": "已提交 %{applications} 份申请,申请 %{units} 个单位", + "account.application.lottery.viewResults": "查看抽奖结果", "account.application.noAccessError": "您未經授權檢視此申請", "account.application.noApplicationError": "具有該 ID 的申請不存在", "account.application.return": "返回申請", diff --git a/shared-helpers/src/scripts/get-machine-translations.ts b/shared-helpers/src/scripts/get-machine-translations.ts index 5f1da07c04..5cdde144ca 100644 --- a/shared-helpers/src/scripts/get-machine-translations.ts +++ b/shared-helpers/src/scripts/get-machine-translations.ts @@ -1,7 +1,10 @@ /* eslint-disable @typescript-eslint/no-var-requires, import/no-unresolved */ // Takes in a CSV file with two columns (t_key,t_value) with the key being the translation file key and the value being the associated English string, and prints out in the JSON translation file format the "key": "translated string" -// Temporarily update the shared-helpers tsconfig to include `"module": "commonjs"` +// CSV format: +// t_key,t_value +// "key.here","Translation here" +// // example from within this directory, first argument is one of LanguagesEnum and second argument is the formatted CSV filename with keys and english strings, piped to a new file: `ts-node get-machine-translations es english-keys.csv > any-filename-here.json` import fs from "node:fs" import { parse } from "csv-parse/sync" diff --git a/sites/public/src/components/account/ApplicationCards.module.scss b/sites/public/src/components/account/ApplicationCards.module.scss new file mode 100644 index 0000000000..8023e708e7 --- /dev/null +++ b/sites/public/src/components/account/ApplicationCards.module.scss @@ -0,0 +1,14 @@ +.application-card { + p { + color: var(--seeds-text-color); + } + .heading-section { + background-color: var(--seeds-color-primary); + } + + .card-header { + font-weight: var(--seeds-font-weight-bold); + color: var(--seeds-color-white); + font-family: var(--seeds-font-alt-sans); + } +} diff --git a/sites/public/src/components/account/ApplicationCards.tsx b/sites/public/src/components/account/ApplicationCards.tsx new file mode 100644 index 0000000000..180910e251 --- /dev/null +++ b/sites/public/src/components/account/ApplicationCards.tsx @@ -0,0 +1,43 @@ +import React from "react" +import { Card, Button, Heading } from "@bloom-housing/ui-seeds" +import { t } from "@bloom-housing/ui-components" +import styles from "./ApplicationCards.module.scss" + +const ApplicationCard = (props: { children: React.ReactElement; heading: string }) => { + return ( + + + + {props.heading} + + + {props.children} + + ) +} +export const ApplicationError = (props: { error: string }) => { + return ( + + <> +

{props.error}

+ + +
+ ) +} + +export const ApplicationListingCard = (props: { listingName: string; listingId: string }) => { + return ( + +
+ {props.listingId && ( + + )} +
+
+ ) +} diff --git a/sites/public/src/components/account/StatusItem.module.scss b/sites/public/src/components/account/StatusItem.module.scss index 203fab5a0d..8558727db9 100644 --- a/sites/public/src/components/account/StatusItem.module.scss +++ b/sites/public/src/components/account/StatusItem.module.scss @@ -72,6 +72,7 @@ justify-content: flex-start; padding-top: var(--seeds-s4); width: fit-content; + flex-wrap: wrap; @media (max-width: theme("screens.sm")) { flex-direction: column; padding-top: var(--seeds-s6); diff --git a/sites/public/src/components/account/StatusItem.tsx b/sites/public/src/components/account/StatusItem.tsx index 5e8ea5fa8b..377c26f38b 100644 --- a/sites/public/src/components/account/StatusItem.tsx +++ b/sites/public/src/components/account/StatusItem.tsx @@ -11,9 +11,12 @@ interface StatusItemProps { confirmationNumber?: string listingName: string listingURL: string + lotteryResults?: boolean + lotteryURL?: string strings?: { applicationsDeadline?: string edited?: string + lotteryResults?: string seeListing?: string status?: string submittedStatus?: string @@ -62,6 +65,13 @@ const StatusItem = (props: StatusItemProps) => {