Skip to content

Commit

Permalink
feat: public account lottery view (#4255)
Browse files Browse the repository at this point in the history
  • Loading branch information
emilyjablonski authored Aug 21, 2024
1 parent 54a1429 commit 4d431ad
Show file tree
Hide file tree
Showing 15 changed files with 402 additions and 54 deletions.
13 changes: 13 additions & 0 deletions shared-helpers/src/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
13 changes: 13 additions & 0 deletions shared-helpers/src/locales/general.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
13 changes: 13 additions & 0 deletions shared-helpers/src/locales/tl.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
13 changes: 13 additions & 0 deletions shared-helpers/src/locales/vi.json
Original file line number Diff line number Diff line change
Expand Up @@ -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ý",
Expand Down
13 changes: 13 additions & 0 deletions shared-helpers/src/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "返回申請",
Expand Down
5 changes: 4 additions & 1 deletion shared-helpers/src/scripts/get-machine-translations.ts
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
14 changes: 14 additions & 0 deletions sites/public/src/components/account/ApplicationCards.module.scss
Original file line number Diff line number Diff line change
@@ -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);
}
}
43 changes: 43 additions & 0 deletions sites/public/src/components/account/ApplicationCards.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Card spacing={"sm"} className={`${styles["application-card"]} my-6`}>
<Card.Section className={`${styles["heading-section"]} px-8 py-4`}>
<Heading priority={1} size={"xl"} className={styles["card-header"]}>
{props.heading}
</Heading>
</Card.Section>
<Card.Section className={"px-8"}>{props.children}</Card.Section>
</Card>
)
}
export const ApplicationError = (props: { error: string }) => {
return (
<ApplicationCard heading={t("account.application.error")}>
<>
<p className="mb-5">{props.error}</p>
<Button size="sm" variant="primary-outlined" href={"/account/applications"}>
{t("account.application.return")}
</Button>
</>
</ApplicationCard>
)
}

export const ApplicationListingCard = (props: { listingName: string; listingId: string }) => {
return (
<ApplicationCard heading={props.listingName}>
<div>
{props.listingId && (
<Button size="sm" variant={"text"} href={`/listing/${props.listingId}`}>
{t("application.confirmation.viewOriginalListing")}
</Button>
)}
</div>
</ApplicationCard>
)
}
1 change: 1 addition & 0 deletions sites/public/src/components/account/StatusItem.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
10 changes: 10 additions & 0 deletions sites/public/src/components/account/StatusItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -62,6 +65,13 @@ const StatusItem = (props: StatusItemProps) => {
</section>

<footer className={styles["status-item__footer"]}>
{props.lotteryResults && (
<div>
<Button href={props.lotteryURL} variant="primary-outlined" size="sm">
{props.strings?.lotteryResults ?? t("account.application.lottery.viewResults")}
</Button>
</div>
)}
<div>
<Button href={props.applicationURL} variant="primary-outlined" size="sm">
{props.strings?.viewApplication ?? t("application.viewApplication")}
Expand Down
12 changes: 10 additions & 2 deletions sites/public/src/components/account/StatusItemWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import React from "react"
import dayjs from "dayjs"
import { StatusItem } from "./StatusItem"
import { Application, Listing } from "@bloom-housing/shared-helpers/src/types/backend-swagger"
import {
Application,
Listing,
LotteryStatusEnum,
} from "@bloom-housing/shared-helpers/src/types/backend-swagger"

export interface AppWithListing extends Application {
fullListing?: Listing
Expand All @@ -16,12 +20,16 @@ const StatusItemWrapper = (props: StatusItemWrapperProps) => {
return (
<StatusItem
applicationDueDate={applicationDueDate && dayjs(applicationDueDate).format("MMMM D, YYYY")}
applicationURL={`application/${props.application?.id}`}
applicationURL={`/account/application/${props.application?.id}`}
applicationUpdatedAt={dayjs(props.application?.updatedAt).format("MMMM D, YYYY")}
confirmationNumber={props.application?.confirmationCode || props.application?.id}
listingName={props.application?.fullListing?.name}
listingURL={`/listing/${props.application?.fullListing?.id}/${props.application?.fullListing?.urlSlug}`}
key={props.application?.id}
lotteryResults={
props.application?.fullListing?.lotteryStatus === LotteryStatusEnum.publishedToPublic
}
lotteryURL={`/account/application/${props.application?.id}/lottery-results`}
/>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { useMemo } from "react"
import { DATE_FORMAT } from "../../lib/constants"
import dayjs from "dayjs"
import { ApplicationListingCard } from "../account/ApplicationCards"

interface SubmittedApplicationViewProps {
application: Application
Expand All @@ -28,26 +29,7 @@ const SubmittedApplicationView = ({

return (
<>
<Card spacing={"sm"} className={"my-6"}>
<Card.Section className={"bg-primary px-8 py-4"}>
<Heading priority={1} size="xl" className={"font-bold font-alt-sans text-white"}>
{listing?.name}
</Heading>
</Card.Section>
<Card.Section className={"px-8"}>
<div>
{listing && (
<Button
size="sm"
variant={"text"}
href={`/listing/${listing.id}/${listing?.urlSlug}`}
>
{t("application.confirmation.viewOriginalListing")}
</Button>
)}
</div>
</Card.Section>
</Card>
<ApplicationListingCard listingName={listing?.name} listingId={listing?.id} />
<Card spacing={"lg"} className={"mb-6"}>
<Card.Section divider={"inset"}>
<Button
Expand Down
Loading

0 comments on commit 4d431ad

Please sign in to comment.