@bloom-housing/ui-components 4.0.1-alpha.20 → 4.0.1-alpha.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,52 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [4.0.1-alpha.24](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@4.0.1-alpha.23...@bloom-housing/ui-components@4.0.1-alpha.24) (2022-01-20)
7
+
8
+
9
+ ### Features
10
+
11
+ * listing card takes optional children ([#2407](https://github.com/bloom-housing/bloom/issues/2407)) ([3c73a11](https://github.com/bloom-housing/bloom/commit/3c73a1144748fca6d50e5e0b220230eb8bf48dc6))
12
+
13
+
14
+
15
+
16
+
17
+ ## [4.0.1-alpha.23](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@4.0.1-alpha.22...@bloom-housing/ui-components@4.0.1-alpha.23) (2022-01-14)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * patches translations for preferences ([#2410](https://github.com/bloom-housing/bloom/issues/2410)) ([7906e6b](https://github.com/bloom-housing/bloom/commit/7906e6bc035fab4deea79ea51833a0ef29926d45))
23
+
24
+
25
+
26
+
27
+
28
+ ## [4.0.1-alpha.22](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@4.0.1-alpha.21...@bloom-housing/ui-components@4.0.1-alpha.22) (2022-01-13)
29
+
30
+ **Note:** Version bump only for package @bloom-housing/ui-components
31
+
32
+
33
+
34
+
35
+
36
+ ## [4.0.1-alpha.21](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@4.0.1-alpha.20...@bloom-housing/ui-components@4.0.1-alpha.21) (2022-01-13)
37
+
38
+
39
+ ### Bug Fixes
40
+
41
+ * dates showing as invalid in send by mail section ([#2362](https://github.com/bloom-housing/bloom/issues/2362)) ([3567388](https://github.com/bloom-housing/bloom/commit/35673882d87e2b524b2c94d1fb7b40c9d777f0a3))
42
+
43
+
44
+ ### BREAKING CHANGES
45
+
46
+ * remove applicationDueTime field and consolidated into applicationDueDate
47
+
48
+
49
+
50
+
51
+
6
52
  ## [4.0.1-alpha.20](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@4.0.1-alpha.19...@bloom-housing/ui-components@4.0.1-alpha.20) (2022-01-13)
7
53
 
8
54
  **Note:** Version bump only for package @bloom-housing/ui-components
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bloom-housing/ui-components",
3
- "version": "4.0.1-alpha.20",
3
+ "version": "4.0.1-alpha.24",
4
4
  "author": "Sean Albert <sean.albert@exygy.com>",
5
5
  "description": "Shared user interface components for Bloom affordable housing system",
6
6
  "homepage": "https://github.com/bloom-housing/bloom/tree/master/shared/ui-components",
@@ -69,7 +69,7 @@
69
69
  "webpack": "^4.44.2"
70
70
  },
71
71
  "dependencies": {
72
- "@bloom-housing/backend-core": "^3.0.2-alpha.12",
72
+ "@bloom-housing/backend-core": "^3.0.2-alpha.15",
73
73
  "@mapbox/mapbox-sdk": "^0.13.0",
74
74
  "@types/body-scroll-lock": "^2.6.1",
75
75
  "@types/jwt-decode": "^2.2.1",
@@ -100,5 +100,5 @@
100
100
  "tailwindcss": "2.2.10",
101
101
  "typesafe-actions": "^5.1.0"
102
102
  },
103
- "gitHead": "4c8409db235ba764d41a83cd63462413a5b14926"
103
+ "gitHead": "4b36cd9d6f9e07b1061b6e843d7c672d878f6f1a"
104
104
  }
@@ -70,7 +70,6 @@ const Button = (props: ButtonProps) => {
70
70
 
71
71
  return (
72
72
  <button
73
- {...props}
74
73
  id={props.id}
75
74
  type={props.type}
76
75
  className={buttonClasses.join(" ")}
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo } from "react"
2
2
  import { ErrorMessage } from "../notifications/ErrorMessage"
3
- import { UseFormMethods } from "react-hook-form"
3
+ import { UseFormMethods, RegisterOptions } from "react-hook-form"
4
4
 
5
5
  export interface FieldProps {
6
6
  error?: boolean
@@ -17,12 +17,12 @@ export interface FieldProps {
17
17
  subNote?: string
18
18
  label?: string
19
19
  defaultValue?: string | number
20
- onDrop?: (e: any) => boolean
21
- onPaste?: (e: any) => boolean
20
+ onDrop?: (e: React.DragEvent<HTMLElement>) => boolean
21
+ onPaste?: (e: React.ClipboardEvent) => boolean
22
22
  onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void
23
23
  placeholder?: string
24
24
  register?: UseFormMethods["register"]
25
- validation?: Record<string, any>
25
+ validation?: RegisterOptions
26
26
  disabled?: boolean
27
27
  prepend?: string
28
28
  inputProps?: Record<string, unknown>
@@ -95,7 +95,6 @@ const Field = (props: FieldProps) => {
95
95
  <div className={controlClasses.join(" ")}>
96
96
  {props.prepend && <span className="prepend">{props.prepend}</span>}
97
97
  <input
98
- {...props}
99
98
  aria-describedby={props.describedBy ? props.describedBy : `${idOrName}`}
100
99
  aria-invalid={!!props.error || false}
101
100
  className="input"
@@ -1,7 +1,7 @@
1
1
  import React, { useState, useEffect } from "react"
2
2
  import { ExpandableContent } from "../actions/ExpandableContent"
3
3
  import { ErrorMessage } from "../notifications/ErrorMessage"
4
- import { UseFormMethods } from "react-hook-form"
4
+ import { UseFormMethods, RegisterOptions } from "react-hook-form"
5
5
  import { Field } from "./Field"
6
6
  import { t } from "../helpers/translator"
7
7
 
@@ -29,7 +29,7 @@ interface FieldGroupProps {
29
29
  groupNote?: string
30
30
  groupSubNote?: string
31
31
  register: UseFormMethods["register"]
32
- validation?: Record<string, unknown>
32
+ validation?: RegisterOptions
33
33
  fieldGroupClassName?: string
34
34
  fieldClassName?: string
35
35
  fieldLabelClassName?: string
@@ -1,7 +1,7 @@
1
1
  import React from "react"
2
2
  import { ErrorMessage } from "../notifications/ErrorMessage"
3
3
  import { FormOptions } from "../helpers/formOptions"
4
- import { UseFormMethods } from "react-hook-form"
4
+ import { UseFormMethods, RegisterOptions } from "react-hook-form"
5
5
 
6
6
  export interface SelectOption {
7
7
  value: string
@@ -21,7 +21,7 @@ interface SelectProps {
21
21
  defaultValue?: string
22
22
  placeholder?: string
23
23
  register?: UseFormMethods["register"]
24
- validation?: Record<string, unknown>
24
+ validation?: RegisterOptions
25
25
  disabled?: boolean
26
26
  options: (string | SelectOption)[]
27
27
  keyPrefix?: string
@@ -252,6 +252,20 @@
252
252
  "general": {
253
253
  "title": "En base a la información que usted ingresó, su hogar no ha solicitado ninguna preferencia de vivienda.",
254
254
  "preamble": "Estará en el grupo general de solicitantes."
255
+ },
256
+ "rosefieldLive": {
257
+ "title": "Anterior Residentes de Rosefield Village reubicados fuera de la ciudad de Alameda",
258
+ "yes": {
259
+ "label": "Al menos un miembro de mi hogar fue residente anterior de Rosefield Village",
260
+ "description": "Al menos un miembro de mi hogar fue residente anterior de Rosefield Village"
261
+ }
262
+ },
263
+ "rosefieldAUSD": {
264
+ "title": "Empleado(a) del Distrito Escolar Unificado Alameda (AUSD)",
265
+ "yes": {
266
+ "label": "Al menos un miembro de mi hogar es empleado del Distrito Escolar Unificado de Alameda",
267
+ "description": "Al menos un miembro de mi hogar es empleado del Distrito Escolar Unificado de Alameda"
268
+ }
255
269
  }
256
270
  },
257
271
  "review": {
@@ -477,7 +491,7 @@
477
491
  "howToApply": "Cómo presentar una Solicitud",
478
492
  "paperApplicationsMustBeMailed": "Las solicitudes impresas deben ser enviadas a través del Servicio Postal de los EE.UU. y no pueden ser entregadas en persona.",
479
493
  "pickUpAnApplication": "Recoja una solicitud.",
480
- "postmarkedApplicationsMustBeReceivedByDate": "Las solicitudes deben recibirse para la fecha límite. Si envía la solicitud a través del Servicio Postal de los EE.UU., la solicitud debe llevar el matasellos a más tardar del %{applicationDueDate} y ser recibida por correo a más tardar el %{postmarkReceivedByDate}. Las solicitudes recibidas por correo después del %{postmarkReceivedByDate} no serán aceptadas incluso si el matasellos lleva una fecha de a más tardar el %{applicationDueDate}. %{developer} no es responsable de correo extraviado o demorado.",
494
+ "submitPaperDueDatePostMark": "Las solicitudes deben recibirse para la fecha límite. Si envía la solicitud a través del Servicio Postal de los EE.UU., la solicitud debe llevar el matasellos a más tardar del %{applicationDueDate} y ser recibida por correo a más tardar el %{postmarkReceivedByDate}. Las solicitudes recibidas por correo después del %{postmarkReceivedByDate} no serán aceptadas incluso si el matasellos lleva una fecha de a más tardar el %{applicationDueDate}. %{developer} no es responsable de correo extraviado o demorado.",
481
495
  "sendByUsMail": "Enviar la Solicitud a través del Servicio Postal de los EE.UU.",
482
496
  "submitAPaperApplication": "Envíe una Solicitud impresa"
483
497
  },
@@ -1016,7 +1016,6 @@
1016
1016
  "applicationsClosed": "Applications Closed",
1017
1017
  "applicationDropOffQuestion": "Can applications be dropped off?",
1018
1018
  "apply": {
1019
- "applicationsMustBeReceivedByDeadline": "Applications must be received by the deadline and postmarks will not be considered.",
1020
1019
  "applicationWillBeAvailableOn": "Application will be available for download and pick up on %{openDate}",
1021
1020
  "applyOnline": "Apply Online",
1022
1021
  "downloadApplication": "Download Application",
@@ -1026,9 +1025,12 @@
1026
1025
  "howToApply": "How to Apply",
1027
1026
  "paperApplicationsMustBeMailed": "Paper applications must be sent by US Mail and cannot be submitted in person.",
1028
1027
  "pickUpAnApplication": "Pick up an application",
1029
- "postmarkedApplicationsMustBeReceivedByDate": "Applications must be received by the deadline. If sending by U.S. Mail, the application must be postmarked by %{applicationDueDate} and received by mail no later than %{postmarkReceivedByDate}. Applications received after %{postmarkReceivedByDate} via mail will not be accepted even if they are postmarked by %{applicationDueDate}. %{developer} is not responsible for lost or delayed mail.",
1030
1028
  "sendByUsMail": "Send Application by US Mail",
1031
- "submitAPaperApplication": "Submit a Paper Application"
1029
+ "submitAPaperApplication": "Submit a Paper Application",
1030
+ "submitPaperDueDateNoPostMark": "Applications must be received by the deadline. If sending by U.S. Mail, the application must be postmarked by %{applicationDueDate}. %{developer} is not responsible for lost or delayed mail.",
1031
+ "submitPaperDueDatePostMark": "Applications must be received by the deadline. If sending by U.S. Mail, the application must be postmarked by %{applicationDueDate} and received by mail no later than %{postmarkReceivedByDate}. Applications received after %{postmarkReceivedByDate} via mail will not be accepted even if they are postmarked by %{applicationDueDate}. %{developer} is not responsible for lost or delayed mail.",
1032
+ "submitPaperNoDueDateNoPostMark": "%{developer} is not responsible for lost or delayed mail.",
1033
+ "submitPaperNoDueDatePostMark": "Applications must be received by the deadline. If sending by U.S. Mail, the application must be received by mail no later than %{postmarkReceivedByDate}. Applications received after %{postmarkReceivedByDate} via mail will not be accepted. %{developer} is not responsible for lost or delayed mail."
1032
1034
  },
1033
1035
  "atAnotherAddress": "At another address",
1034
1036
  "atLeasingAgentAddress": "At the leasing agent address",
@@ -1123,6 +1125,8 @@
1123
1125
  "pickupAddress": "Pickup Address",
1124
1126
  "postmarkByDate": "Postmark by Date",
1125
1127
  "postmarkByTime": "Postmark by Time",
1128
+ "receivedByDate": "Received by Date",
1129
+ "receivedByTime": "Received by Time",
1126
1130
  "postmarksConsideredQuestion": "Are postmarks considered?",
1127
1131
  "priorityUnits": "Priority Units",
1128
1132
  "priorityUnitsDescription": "This building has units set aside if any of the following apply to you or someone in your household:",
@@ -249,6 +249,20 @@
249
249
  "general": {
250
250
  "title": "Dựa trên thông tin quý vị đã nhập, hộ gia đình của quý vị chưa yêu cầu bất kỳ lựa chọn ưu tiên nhà ở nào.",
251
251
  "preamble": "Quý vị sẽ thuộc nhóm các ứng viên chung."
252
+ },
253
+ "rosefieldLive": {
254
+ "title": "Cư dân trước đây của Làng Rosefield đã tái định cư bên ngoài Thành phố Alameda",
255
+ "yes": {
256
+ "label": "Ít nhất một thành viên trong gia đình tôi là cư dân trước đây của Làng Rosefield",
257
+ "description": "Ít nhất một thành viên trong gia đình tôi là cư dân trước đây của Làng Rosefield"
258
+ }
259
+ },
260
+ "rosefieldAUSD": {
261
+ "title": "Nhân viên của Học khu Thống nhất Alameda (AUSD)",
262
+ "yes": {
263
+ "label": "Ít nhất một thành viên trong gia đình tôi là nhân viên của Học khu Thống nhất Alameda",
264
+ "description": "Ít nhất một thành viên trong gia đình tôi là nhân viên của Học khu Thống nhất Alameda"
265
+ }
252
266
  }
253
267
  },
254
268
  "review": {
@@ -476,7 +490,7 @@
476
490
  "howToApply": "Cách Ghi danh",
477
491
  "paperApplicationsMustBeMailed": "Mẫu đơn ghi danh Giấy phải được gửi thư bưu điện Hoa Kỳ và không thể nộp trực tiếp.",
478
492
  "pickUpAnApplication": "Nhận đơn ghi danh",
479
- "postmarkedApplicationsMustBeReceivedByDate": "Đơn ghi danh phải được nhận trước thời hạn. Nếu gửi qua đường bưu điện U.S Mail, đơn ghi danh phải được đóng dấu bưu điện trước %{applicationDueDate} và nhận qua thư trước ngày %{postmarkReceiveByDate}. Các đơn ghi danh nhận được sau %{postmarkReceiveByDate} qua đường bưu điện sẽ không được chấp nhận ngay cả khi chúng được đóng dấu bưu điện trước %{applicationDueDate}. %{developer} không chịu trách nhiệm về thư bị thất lạc hoặc bị trễ.",
493
+ "submitPaperDueDatePostMark": "Đơn ghi danh phải được nhận trước thời hạn. Nếu gửi qua đường bưu điện U.S Mail, đơn ghi danh phải được đóng dấu bưu điện trước %{applicationDueDate} và nhận qua thư trước ngày %{postmarkReceiveByDate}. Các đơn ghi danh nhận được sau %{postmarkReceiveByDate} qua đường bưu điện sẽ không được chấp nhận ngay cả khi chúng được đóng dấu bưu điện trước %{applicationDueDate}. %{developer} không chịu trách nhiệm về thư bị thất lạc hoặc bị trễ.",
480
494
  "sendByUsMail": "Gửi Đơn ghi danh qua đường bưu điện US Mail",
481
495
  "submitAPaperApplication": "Gửi Giấy ghi danh"
482
496
  },
@@ -249,6 +249,20 @@
249
249
  "general": {
250
250
  "title": "根據您填寫的資料,您的家庭沒有要求任何住房優先權。",
251
251
  "preamble": "您將被分配到一般申請人組別。"
252
+ },
253
+ "rosefieldLive": {
254
+ "title": "罗斯菲尔德村以前的居民搬迁到阿拉米达市外",
255
+ "yes": {
256
+ "label": "我的至少一名家庭成员曾是罗斯菲尔德村的居民",
257
+ "description": "我的至少一名家庭成员曾是罗斯菲尔德村的居民"
258
+ }
259
+ },
260
+ "rosefieldAUSD": {
261
+ "title": "阿拉米达联合学区 (AUSD) 员工",
262
+ "yes": {
263
+ "label": "我的至少一名家庭成员是阿拉米达联合学区的雇员",
264
+ "description": "我的至少一名家庭成员是阿拉米达联合学区的雇员"
265
+ }
252
266
  }
253
267
  },
254
268
  "review": {
@@ -476,7 +490,7 @@
476
490
  "howToApply": "如何申請",
477
491
  "paperApplicationsMustBeMailed": "紙本申請表必須經由美國郵政寄回,並且不能親自提交。",
478
492
  "pickUpAnApplication": "領取申請表",
479
- "postmarkedApplicationsMustBeReceivedByDate": "申請表必須在截止日期前收到。如果經由美國郵政寄送,則申請表上的郵戳日期必須在 %{applicationDueDate} 前,郵件最遲要在 %{postmarkReceivedByDate} 前寄達。我們不會受理在 %{postmarkReceivedByDate} 之後郵寄送達的申請表,即使郵戳日期在 %{applicationDueDate} 之前也一樣。若郵件有任何遺失或延誤,%{developer} 概不負責。",
493
+ "submitPaperDueDatePostMark": "申請表必須在截止日期前收到。如果經由美國郵政寄送,則申請表上的郵戳日期必須在 %{applicationDueDate} 前,郵件最遲要在 %{postmarkReceivedByDate} 前寄達。我們不會受理在 %{postmarkReceivedByDate} 之後郵寄送達的申請表,即使郵戳日期在 %{applicationDueDate} 之前也一樣。若郵件有任何遺失或延誤,%{developer} 概不負責。",
480
494
  "sendByUsMail": "用美國郵政寄送申請表",
481
495
  "submitAPaperApplication": "提交紙本申請表"
482
496
  },
@@ -18,14 +18,39 @@ export interface ListingCardHeaderProps {
18
18
  }
19
19
  export interface ListingCardProps {
20
20
  imageCardProps: ImageCardProps
21
+ children?: React.ReactElement
21
22
  seeDetailsLink?: string
22
23
  tableHeaderProps?: ListingCardHeaderProps
23
- tableProps: ListingCardTableProps
24
+ tableProps?: ListingCardTableProps
24
25
  detailsLinkClass?: string
25
26
  }
26
27
 
27
28
  const ListingCard = (props: ListingCardProps) => {
28
- const { imageCardProps, tableProps, detailsLinkClass, tableHeaderProps } = props
29
+ const { imageCardProps, tableProps, detailsLinkClass, tableHeaderProps, children } = props
30
+
31
+ const tableHeader = () => {
32
+ return (
33
+ <h3
34
+ className={`listings-row_title ${
35
+ tableHeaderProps?.tableHeaderClass && tableHeaderProps?.tableHeaderClass
36
+ }`}
37
+ >
38
+ {tableHeaderProps?.tableHeader}
39
+ </h3>
40
+ )
41
+ }
42
+
43
+ const tableSubHeader = () => {
44
+ return (
45
+ <h4
46
+ className={`listings-row_subtitle ${
47
+ tableHeaderProps?.tableSubHeaderClass && tableHeaderProps?.tableSubHeaderClass
48
+ }`}
49
+ >
50
+ {tableHeaderProps?.tableSubHeader}
51
+ </h4>
52
+ )
53
+ }
29
54
 
30
55
  return (
31
56
  <article className="listings-row" data-test-id={"listing-card-component"}>
@@ -33,26 +58,11 @@ const ListingCard = (props: ListingCardProps) => {
33
58
  <ImageCard {...imageCardProps} />
34
59
  </div>
35
60
  <div className="listings-row_content">
36
- {tableHeaderProps?.tableHeader && (
37
- <h3
38
- className={`listings-row_title ${
39
- tableHeaderProps.tableHeaderClass && tableHeaderProps.tableHeaderClass
40
- }`}
41
- >
42
- {tableHeaderProps?.tableHeader}
43
- </h3>
44
- )}
45
- {tableHeaderProps?.tableSubHeader && (
46
- <h4
47
- className={`listings-row_subtitle ${
48
- tableHeaderProps.tableSubHeaderClass && tableHeaderProps.tableSubHeaderClass
49
- }`}
50
- >
51
- {tableHeaderProps?.tableSubHeader}
52
- </h4>
53
- )}
61
+ {tableHeaderProps?.tableHeader && tableHeader()}
62
+ {tableHeaderProps?.tableSubHeader && tableSubHeader()}
54
63
  <div className="listings-row_table">
55
- {(tableProps.data || tableProps.stackedData) && (
64
+ {children && children}
65
+ {tableProps && (tableProps.data || tableProps.stackedData) && (
56
66
  <>
57
67
  {tableHeaderProps?.stackedTable ? (
58
68
  <StackedTable {...(tableProps as StackedTableProps)} />
@@ -5,7 +5,6 @@ import { LinkButton } from "../../../actions/LinkButton"
5
5
  import { AppearanceStyleType } from "../../../global/AppearanceTypes"
6
6
  import { Address } from "../../../helpers/address"
7
7
  import { SidebarAddress } from "./SidebarAddress"
8
- import { NumberedHeader } from "./NumberedHeader"
9
8
  import { OrDivider } from "./OrDivider"
10
9
  import { ListingStatus } from "@bloom-housing/backend-core/types"
11
10
 
@@ -16,7 +15,6 @@ export interface PaperApplication {
16
15
 
17
16
  export interface ApplicationsProps {
18
17
  onlineApplicationURL?: string
19
- applicationsDueDate?: string
20
18
  applicationsOpen: boolean
21
19
  applicationsOpenDate?: string
22
20
  paperApplications?: PaperApplication[]
@@ -67,7 +65,7 @@ const GetApplication = (props: ApplicationsProps) => {
67
65
  {props.applicationsOpen && props.paperMethod && (
68
66
  <>
69
67
  {props.onlineApplicationURL && <OrDivider bgColor="white" />}
70
- <NumberedHeader num={1} text={t("listings.apply.getAPaperApplication")} />
68
+ <div className="text-serif-lg">{t("listings.apply.getAPaperApplication")}</div>
71
69
  <Button
72
70
  styleType={
73
71
  !props.preview && props.onlineApplicationURL ? AppearanceStyleType.primary : undefined
@@ -2,14 +2,13 @@ import * as React from "react"
2
2
  import { t } from "../../../helpers/translator"
3
3
  import { Address } from "../../../helpers/address"
4
4
  import { SidebarAddress } from "./SidebarAddress"
5
- import { NumberedHeader } from "./NumberedHeader"
6
5
  import { OrDivider } from "./OrDivider"
7
6
  import { ListingStatus } from "@bloom-housing/backend-core/types"
8
7
 
9
8
  export interface PostmarkedApplication {
10
- postmarkedApplicationsReceivedByDate: string
9
+ postmarkedApplicationsReceivedByDate: string | null
11
10
  developer: string
12
- applicationsDueDate: string
11
+ applicationsDueDate: string | null
13
12
  }
14
13
 
15
14
  export interface ApplicationAddressesProps {
@@ -22,50 +21,61 @@ export interface ApplicationAddressesProps {
22
21
  }
23
22
 
24
23
  const SubmitApplication = (props: ApplicationAddressesProps) => {
25
- if (props.listingStatus === ListingStatus.closed) {
24
+ if (
25
+ props.listingStatus === ListingStatus.closed ||
26
+ !(props.applicationMailingAddress || props.applicationDropOffAddress)
27
+ ) {
26
28
  return null
27
29
  }
28
30
 
31
+ const getPostmarkString = () => {
32
+ const applicationDueDate = props.postmarkedApplicationData?.applicationsDueDate
33
+ const postmarkReceivedByDate =
34
+ props.postmarkedApplicationData?.postmarkedApplicationsReceivedByDate
35
+ const developer = props.postmarkedApplicationData?.developer
36
+ if (applicationDueDate) {
37
+ return postmarkReceivedByDate
38
+ ? t("listings.apply.submitPaperDueDatePostMark", {
39
+ applicationDueDate,
40
+ postmarkReceivedByDate,
41
+ developer,
42
+ })
43
+ : t("listings.apply.submitPaperDueDateNoPostMark", {
44
+ applicationDueDate,
45
+ developer,
46
+ })
47
+ } else {
48
+ return postmarkReceivedByDate
49
+ ? t("listings.apply.submitPaperNoDueDatePostMark", { postmarkReceivedByDate, developer })
50
+ : t("listings.apply.submitPaperNoDueDateNoPostMark", { developer })
51
+ }
52
+ }
53
+
29
54
  return (
30
55
  <>
31
- {(props.applicationMailingAddress ||
32
- props.applicationDropOffAddress ||
33
- props.postmarkedApplicationData) && (
34
- <section className="aside-block is-tinted bg-gray-100">
35
- <NumberedHeader num={2} text={t("listings.apply.submitAPaperApplication")} />
36
- {(props.applicationMailingAddress || props.postmarkedApplicationData) && (
56
+ <section className="aside-block is-tinted bg-gray-100">
57
+ <div className="text-serif-lg">{t("listings.apply.submitAPaperApplication")}</div>
58
+ {props.applicationMailingAddress && (
59
+ <>
60
+ <h3 className="text-caps-tiny">{t("listings.apply.sendByUsMail")}</h3>
37
61
  <>
38
- <h3 className="text-caps-tiny">{t("listings.apply.sendByUsMail")}</h3>
39
62
  <p className="text-gray-700">{props.applicationOrganization}</p>
40
- {props.applicationMailingAddress && (
41
- <SidebarAddress address={props.applicationMailingAddress} />
42
- )}
43
- <p className="mt-4 text-tiny text-gray-750">
44
- {props.postmarkedApplicationData?.postmarkedApplicationsReceivedByDate
45
- ? t("listings.apply.postmarkedApplicationsMustBeReceivedByDate", {
46
- applicationDueDate: props.postmarkedApplicationData?.applicationsDueDate,
47
- postmarkReceivedByDate:
48
- props.postmarkedApplicationData?.postmarkedApplicationsReceivedByDate,
49
- developer: props.postmarkedApplicationData?.developer,
50
- })
51
- : t("listings.apply.applicationsMustBeReceivedByDeadline")}
52
- </p>
53
- </>
54
- )}
55
- {props.applicationMailingAddress && props.applicationDropOffAddress && (
56
- <OrDivider bgColor="gray-100" />
57
- )}
58
- {props.applicationDropOffAddress && (
59
- <>
60
- <h3 className="text-caps-tiny">{t("listings.apply.dropOffApplication")}</h3>
61
- <SidebarAddress
62
- address={props.applicationDropOffAddress}
63
- officeHours={props.applicationDropOffAddressOfficeHours}
64
- />
63
+ <SidebarAddress address={props.applicationMailingAddress} />
65
64
  </>
66
- )}
67
- </section>
68
- )}
65
+ <p className="mt-4 text-tiny text-gray-750">{getPostmarkString()}</p>
66
+ </>
67
+ )}
68
+ {props.applicationDropOffAddress && (
69
+ <>
70
+ {props.applicationMailingAddress && <OrDivider bgColor="gray-100" />}
71
+ <h3 className="text-caps-tiny">{t("listings.apply.dropOffApplication")}</h3>
72
+ <SidebarAddress
73
+ address={props.applicationDropOffAddress}
74
+ officeHours={props.applicationDropOffAddressOfficeHours}
75
+ />
76
+ </>
77
+ )}
78
+ </section>
69
79
  </>
70
80
  )
71
81
  }
@@ -3,6 +3,11 @@ import { ListingEvent } from "@bloom-housing/backend-core/types"
3
3
  import dayjs from "dayjs"
4
4
 
5
5
  const EventDateSection = (props: { event: ListingEvent }) => {
6
+ const getRangeString = () => {
7
+ const startTime = dayjs(props.event.startTime).format("hh:mma")
8
+ const endTime = dayjs(props.event.endTime).format("hh:mma")
9
+ return startTime === endTime ? startTime : `${startTime} - ${endTime}`
10
+ }
6
11
  return (
7
12
  <>
8
13
  {props.event.startTime && (
@@ -10,11 +15,7 @@ const EventDateSection = (props: { event: ListingEvent }) => {
10
15
  <span className="inline-block text-tiny uppercase">
11
16
  {dayjs(props.event.startTime).format("MMMM D, YYYY")}
12
17
  </span>
13
- <span className="inline-block text-sm font-bold">
14
- {dayjs(props.event.startTime).format("hh:mma") +
15
- "-" +
16
- dayjs(props.event.endTime).format("hh:mma")}
17
- </span>
18
+ <span className="inline-block text-sm font-bold">{getRangeString()}</span>
18
19
  </p>
19
20
  )}
20
21
  </>