@bloom-housing/ui-components 2.0.0-pre-tailwind

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.
Files changed (223) hide show
  1. package/.jest/setup-tests.js +24 -0
  2. package/CHANGELOG.md +20 -0
  3. package/README.md +195 -0
  4. package/index.ts +148 -0
  5. package/jest.config.js +41 -0
  6. package/package.json +98 -0
  7. package/public/images/alameda-logo-white.svg +1 -0
  8. package/public/images/arrow-down.png +0 -0
  9. package/public/images/arrow-down.svg +1 -0
  10. package/public/images/check.png +0 -0
  11. package/public/images/check.svg +11 -0
  12. package/public/images/eho-logo-white.svg +1 -0
  13. package/public/images/eho-logo.svg +1 -0
  14. package/public/images/logo_glyph.svg +11 -0
  15. package/src/actions/Button.scss +157 -0
  16. package/src/actions/Button.tsx +80 -0
  17. package/src/actions/ExpandableContent.tsx +29 -0
  18. package/src/actions/ExpandableText.scss +18 -0
  19. package/src/actions/ExpandableText.tsx +52 -0
  20. package/src/actions/LinkButton.tsx +30 -0
  21. package/src/actions/LocalizedLink.tsx +11 -0
  22. package/src/authentication/AuthContext.ts +327 -0
  23. package/src/authentication/RequireLogin.tsx +62 -0
  24. package/src/authentication/index.ts +5 -0
  25. package/src/authentication/timeout.tsx +127 -0
  26. package/src/authentication/token.ts +17 -0
  27. package/src/authentication/useRequireLoggedInUser.ts +19 -0
  28. package/src/blocks/ActionBlock.scss +108 -0
  29. package/src/blocks/ActionBlock.tsx +51 -0
  30. package/src/blocks/AppStatusItem.scss +140 -0
  31. package/src/blocks/AppStatusItem.tsx +75 -0
  32. package/src/blocks/DashBlock.tsx +42 -0
  33. package/src/blocks/DashBlocks.scss +56 -0
  34. package/src/blocks/DashBlocks.tsx +7 -0
  35. package/src/blocks/FormCard.scss +201 -0
  36. package/src/blocks/FormCard.tsx +29 -0
  37. package/src/blocks/HousingCounselor.tsx +51 -0
  38. package/src/blocks/ImageCard.scss +91 -0
  39. package/src/blocks/ImageCard.tsx +77 -0
  40. package/src/blocks/InfoCard.scss +42 -0
  41. package/src/blocks/InfoCard.tsx +44 -0
  42. package/src/blocks/StatusBar.scss +30 -0
  43. package/src/blocks/StatusBar.tsx +31 -0
  44. package/src/blocks/ViewItem.scss +59 -0
  45. package/src/blocks/ViewItem.tsx +32 -0
  46. package/src/config/ConfigContext.tsx +36 -0
  47. package/src/config/NavigationContext.tsx +54 -0
  48. package/src/config/index.ts +2 -0
  49. package/src/footers/ExygyFooter.tsx +12 -0
  50. package/src/footers/SiteFooter.scss +28 -0
  51. package/src/footers/SiteFooter.tsx +10 -0
  52. package/src/forms/CloudinaryUpload.ts +50 -0
  53. package/src/forms/DOBField.tsx +132 -0
  54. package/src/forms/DateField.tsx +120 -0
  55. package/src/forms/Dropzone.scss +17 -0
  56. package/src/forms/Dropzone.tsx +67 -0
  57. package/src/forms/Field.tsx +115 -0
  58. package/src/forms/FieldGroup.tsx +82 -0
  59. package/src/forms/Form.tsx +22 -0
  60. package/src/forms/HouseholdMemberForm.tsx +41 -0
  61. package/src/forms/HouseholdSizeField.tsx +74 -0
  62. package/src/forms/PhoneField.tsx +69 -0
  63. package/src/forms/PhoneMask.tsx +24 -0
  64. package/src/forms/Select.tsx +80 -0
  65. package/src/forms/Textarea.scss +40 -0
  66. package/src/forms/Textarea.tsx +64 -0
  67. package/src/forms/TimeField.tsx +176 -0
  68. package/src/global/AppearanceTypes.ts +46 -0
  69. package/src/global/ApplicationStatusType.ts +6 -0
  70. package/src/global/accordion.scss +4 -0
  71. package/src/global/blocks.scss +137 -0
  72. package/src/global/custom_counter.scss +50 -0
  73. package/src/global/forms.scss +362 -0
  74. package/src/global/headers.scss +89 -0
  75. package/src/global/homepage.scss +8 -0
  76. package/src/global/index.scss +72 -0
  77. package/src/global/lists.scss +21 -0
  78. package/src/global/markdown.scss +33 -0
  79. package/src/global/mixins.scss +175 -0
  80. package/src/global/navbar.scss +280 -0
  81. package/src/global/print.scss +59 -0
  82. package/src/global/tables.scss +197 -0
  83. package/src/global/text.scss +141 -0
  84. package/src/global/vendor/AgPagination.tsx +133 -0
  85. package/src/global/vendor/_setup_bulma.scss +31 -0
  86. package/src/global/vendor/ag_grid.scss +140 -0
  87. package/src/headers/Hero.scss +56 -0
  88. package/src/headers/Hero.tsx +76 -0
  89. package/src/headers/PageHeader.scss +31 -0
  90. package/src/headers/PageHeader.tsx +39 -0
  91. package/src/headers/SiteHeader.tsx +136 -0
  92. package/src/helpers/address.tsx +46 -0
  93. package/src/helpers/blankApplication.ts +108 -0
  94. package/src/helpers/capitalize.tsx +7 -0
  95. package/src/helpers/dateToString.ts +11 -0
  96. package/src/helpers/debounce.ts +12 -0
  97. package/src/helpers/formOptions.tsx +229 -0
  98. package/src/helpers/formatYesNoLabel.ts +9 -0
  99. package/src/helpers/getTranslationWithArguments.ts +14 -0
  100. package/src/helpers/links.ts +7 -0
  101. package/src/helpers/localeRoute.tsx +13 -0
  102. package/src/helpers/mergeDeep.ts +12 -0
  103. package/src/helpers/nextjs.ts +7 -0
  104. package/src/helpers/numberOrdinal.ts +17 -0
  105. package/src/helpers/occupancyFormatting.tsx +46 -0
  106. package/src/helpers/pdfs.ts +19 -0
  107. package/src/helpers/photos.ts +19 -0
  108. package/src/helpers/preferences.tsx +426 -0
  109. package/src/helpers/resolveObject.ts +5 -0
  110. package/src/helpers/state.tsx +7 -0
  111. package/src/helpers/tableSummaries.tsx +80 -0
  112. package/src/helpers/translator.tsx +37 -0
  113. package/src/helpers/useKeyPress.ts +17 -0
  114. package/src/helpers/useMutate.ts +40 -0
  115. package/src/helpers/useOutsideClick.ts +25 -0
  116. package/src/helpers/validators.ts +3 -0
  117. package/src/icons/HeaderBadge.scss +29 -0
  118. package/src/icons/HeaderBadge.tsx +38 -0
  119. package/src/icons/Icon.scss +76 -0
  120. package/src/icons/Icon.tsx +145 -0
  121. package/src/icons/Icons.tsx +556 -0
  122. package/src/lists/PreferencesList.scss +72 -0
  123. package/src/lists/PreferencesList.tsx +60 -0
  124. package/src/locales/es.json +745 -0
  125. package/src/locales/general.json +1307 -0
  126. package/src/locales/general_OLD.json +868 -0
  127. package/src/locales/vi.json +745 -0
  128. package/src/locales/zh.json +745 -0
  129. package/src/navigation/Breadcrumbs.scss +25 -0
  130. package/src/navigation/Breadcrumbs.tsx +27 -0
  131. package/src/navigation/FooterNav.scss +47 -0
  132. package/src/navigation/FooterNav.tsx +19 -0
  133. package/src/navigation/LanguageNav.scss +32 -0
  134. package/src/navigation/LanguageNav.tsx +53 -0
  135. package/src/navigation/ProgressNav.scss +102 -0
  136. package/src/navigation/ProgressNav.tsx +50 -0
  137. package/src/navigation/TabNav.scss +38 -0
  138. package/src/navigation/TabNav.tsx +69 -0
  139. package/src/navigation/Tabs.scss +65 -0
  140. package/src/navigation/Tabs.tsx +93 -0
  141. package/src/navigation/UserNav.tsx +37 -0
  142. package/src/notifications/AlertBox.scss +78 -0
  143. package/src/notifications/AlertBox.tsx +79 -0
  144. package/src/notifications/AlertNotice.scss +58 -0
  145. package/src/notifications/AlertNotice.tsx +37 -0
  146. package/src/notifications/ApplicationStatus.scss +10 -0
  147. package/src/notifications/ApplicationStatus.tsx +64 -0
  148. package/src/notifications/ErrorMessage.tsx +15 -0
  149. package/src/notifications/SiteAlert.tsx +54 -0
  150. package/src/notifications/StatusAside.scss +11 -0
  151. package/src/notifications/StatusAside.tsx +25 -0
  152. package/src/notifications/StatusMessage.scss +25 -0
  153. package/src/notifications/StatusMessage.tsx +59 -0
  154. package/src/notifications/alertTypes.ts +7 -0
  155. package/src/notifications/index.ts +4 -0
  156. package/src/overlays/Drawer.scss +105 -0
  157. package/src/overlays/Drawer.tsx +51 -0
  158. package/src/overlays/LoadingOverlay.scss +25 -0
  159. package/src/overlays/LoadingOverlay.tsx +29 -0
  160. package/src/overlays/Modal.scss +55 -0
  161. package/src/overlays/Modal.tsx +61 -0
  162. package/src/overlays/Overlay.scss +50 -0
  163. package/src/overlays/Overlay.tsx +100 -0
  164. package/src/page_components/listing/AdditionalFees.tsx +56 -0
  165. package/src/page_components/listing/ListingCard.scss +47 -0
  166. package/src/page_components/listing/ListingCard.tsx +34 -0
  167. package/src/page_components/listing/ListingDetailHeader.tsx +25 -0
  168. package/src/page_components/listing/ListingDetails.tsx +29 -0
  169. package/src/page_components/listing/ListingMap.scss +36 -0
  170. package/src/page_components/listing/ListingMap.tsx +138 -0
  171. package/src/page_components/listing/ListingsGroup.scss +65 -0
  172. package/src/page_components/listing/ListingsGroup.tsx +49 -0
  173. package/src/page_components/listing/UnitTables.tsx +111 -0
  174. package/src/page_components/listing/listing_sidebar/ApplicationSection.tsx +49 -0
  175. package/src/page_components/listing/listing_sidebar/Apply.tsx +225 -0
  176. package/src/page_components/listing/listing_sidebar/LeasingAgent.tsx +77 -0
  177. package/src/page_components/listing/listing_sidebar/ListingUpdated.tsx +20 -0
  178. package/src/page_components/listing/listing_sidebar/ReferralApplication.tsx +28 -0
  179. package/src/page_components/listing/listing_sidebar/SidebarAddress.tsx +56 -0
  180. package/src/page_components/listing/listing_sidebar/Waitlist.tsx +94 -0
  181. package/src/page_components/listing/listing_sidebar/WhatToExpect.tsx +22 -0
  182. package/src/page_components/listing/listing_sidebar/events/DownloadLotteryResults.tsx +34 -0
  183. package/src/page_components/listing/listing_sidebar/events/EventDateSection.tsx +24 -0
  184. package/src/page_components/listing/listing_sidebar/events/LotteryResultsEvent.tsx +26 -0
  185. package/src/page_components/listing/listing_sidebar/events/OpenHouseEvent.tsx +27 -0
  186. package/src/page_components/listing/listing_sidebar/events/PublicLotteryEvent.tsx +22 -0
  187. package/src/prototypes/AppCard.scss +64 -0
  188. package/src/prototypes/Back.scss +19 -0
  189. package/src/prototypes/ButtonGroup.scss +6 -0
  190. package/src/prototypes/ButtonPager.scss +22 -0
  191. package/src/prototypes/FieldSection.scss +35 -0
  192. package/src/prototypes/FieldSection.tsx +31 -0
  193. package/src/prototypes/GridItem.tsx +15 -0
  194. package/src/prototypes/SideNav.scss +32 -0
  195. package/src/prototypes/SideNav.tsx +14 -0
  196. package/src/prototypes/SummaryCard.scss +34 -0
  197. package/src/sections/ContentSection.scss +15 -0
  198. package/src/sections/ContentSection.tsx +25 -0
  199. package/src/sections/FooterSection.scss +6 -0
  200. package/src/sections/FooterSection.tsx +16 -0
  201. package/src/sections/GridSection.scss +72 -0
  202. package/src/sections/GridSection.tsx +82 -0
  203. package/src/sections/InfoCardGrid.scss +45 -0
  204. package/src/sections/InfoCardGrid.tsx +20 -0
  205. package/src/sections/ListSection.scss +7 -0
  206. package/src/sections/ListSection.tsx +23 -0
  207. package/src/sections/MarkdownSection.scss +13 -0
  208. package/src/sections/MarkdownSection.tsx +21 -0
  209. package/src/sections/ResponsiveContentList.tsx +67 -0
  210. package/src/sections/ResponsiveWrappers.tsx +23 -0
  211. package/src/tables/GroupedTable.tsx +86 -0
  212. package/src/tables/MinimalTable.tsx +32 -0
  213. package/src/tables/ResponsiveTable.tsx +24 -0
  214. package/src/tables/StandardTable.tsx +229 -0
  215. package/src/text/Description.scss +52 -0
  216. package/src/text/Description.tsx +24 -0
  217. package/src/text/Message.scss +16 -0
  218. package/src/text/Message.tsx +16 -0
  219. package/src/text/Tag.scss +94 -0
  220. package/src/text/Tag.tsx +22 -0
  221. package/tailwind.config.js +128 -0
  222. package/tailwind.tosass.js +29 -0
  223. package/tsconfig.json +31 -0
@@ -0,0 +1,75 @@
1
+ import React from "react"
2
+ import "./AppStatusItem.scss"
3
+ import moment from "moment"
4
+ import { Application, Listing } from "@bloom-housing/backend-core/types"
5
+ import { LocalizedLink } from "../actions/LocalizedLink"
6
+ import { t } from "../helpers/translator"
7
+
8
+ interface AppStatusItemProps {
9
+ application: Application
10
+ listing: Listing
11
+ }
12
+
13
+ const AppStatusItem = (props: AppStatusItemProps) => {
14
+ const { application, listing } = props
15
+
16
+ const applicationDueDate = moment(listing.applicationDueDate)
17
+ const editDate = moment(application.updatedAt)
18
+
19
+ return (
20
+ <article className="status-item is-editable animated-fade">
21
+ <div className="status-item__inner">
22
+ <header className="status-item__header">
23
+ <h3 className="status-item__title">{listing.name}</h3>
24
+ <p className="status-item__due">
25
+ {t("listings.applicationDeadline")}: {applicationDueDate.format("MMMM D, YYYY")}
26
+ </p>
27
+ </header>
28
+
29
+ <section className="status-item__content">
30
+ <div className="status-item__details">
31
+ {application.id && (
32
+ <>
33
+ <span className="status-item__confirm-text">
34
+ {t("application.yourLotteryNumber")}:
35
+ </span>
36
+ <br />
37
+ <span className="status-item__confirm-number">{application.id}</span>
38
+ </>
39
+ )}
40
+ </div>
41
+
42
+ <div className="status-item__action">
43
+ <p className="status-item__status">
44
+ <span className={"status-item__label"}>
45
+ {t("application.status")}: {t("application.statuses.submitted")}
46
+ </span>
47
+ </p>
48
+ <a href={`application/${application.id}`} className="button is-small">
49
+ {t("application.viewApplication")}
50
+ </a>
51
+ </div>
52
+ </section>
53
+
54
+ <footer className="status-item__footer">
55
+ <div className="status-item_links">
56
+ <LocalizedLink
57
+ className="status-item__link lined"
58
+ href={`/listing/${listing.id}/${listing.urlSlug}`}
59
+ >
60
+ {t("t.seeListing")}
61
+ </LocalizedLink>
62
+ </div>
63
+
64
+ <div className="status-item__meta">
65
+ <p className="status-item__date">
66
+ {t("application.edited")}: {editDate.format("MMMM D, YYYY")}
67
+ </p>
68
+ </div>
69
+ </footer>
70
+ </div>
71
+ </article>
72
+ )
73
+ }
74
+
75
+ export { AppStatusItem as default, AppStatusItem }
@@ -0,0 +1,42 @@
1
+ import React from "react"
2
+ import "./DashBlocks.scss"
3
+
4
+ interface DashBlockProps {
5
+ href?: string
6
+ title: string
7
+ subtitle?: string
8
+ icon: React.ReactNode
9
+ children?: React.ReactNode
10
+ }
11
+ const DashBlock = (props: DashBlockProps) => {
12
+ const { href, title, subtitle, icon, children } = props
13
+ let content, wrapper
14
+ if (children) {
15
+ content = <div className="dash-item__content">{children}</div>
16
+ }
17
+ const header = (
18
+ <>
19
+ <span className="dash-item__badge">{icon}</span>
20
+ <h2 className="dash-item__name">{title}</h2>
21
+ {subtitle && <p>{subtitle}</p>}
22
+ </>
23
+ )
24
+ if (href) {
25
+ wrapper = (
26
+ <a href={href} className="dash-item">
27
+ {header}
28
+ </a>
29
+ )
30
+ } else {
31
+ wrapper = (
32
+ <>
33
+ <div className="dash-item">
34
+ <div className="pb-4">{header}</div>
35
+ {content}
36
+ </div>
37
+ </>
38
+ )
39
+ }
40
+ return <div className="dash-block">{wrapper}</div>
41
+ }
42
+ export { DashBlock as default, DashBlock }
@@ -0,0 +1,56 @@
1
+ .dash-blocks {
2
+ @apply w-full;
3
+
4
+ @screen md {
5
+ @apply flex;
6
+ @apply flex-wrap;
7
+ }
8
+ }
9
+
10
+ .dash-block {
11
+ @screen md {
12
+ @apply px-2;
13
+ flex: 50%;
14
+ }
15
+ }
16
+
17
+ .dash-item {
18
+ @apply text-gray-800;
19
+ @apply border-solid;
20
+ @apply border-b;
21
+ @apply border-gray-450;
22
+ @apply text-center;
23
+ @apply block;
24
+ @apply bg-white;
25
+ @apply p-4;
26
+ @apply pt-8;
27
+ @apply text-tiny;
28
+
29
+ @screen md {
30
+ @apply rounded-lg;
31
+ @apply border;
32
+ @apply p-8;
33
+ @apply mb-8;
34
+ }
35
+
36
+ p {
37
+ @apply mb-0;
38
+ }
39
+
40
+ .dash-item__content {
41
+ @apply border-t;
42
+ @apply border-gray-450;
43
+ @apply -mx-8;
44
+ @apply -mb-8;
45
+ @apply background-grey-300
46
+ @screen md {
47
+ @apply rounded-b-lg;
48
+ @apply border-t;
49
+ }
50
+ }
51
+ }
52
+
53
+ .dash-item__name {
54
+ @apply text-2xl;
55
+ @apply mb-3;
56
+ }
@@ -0,0 +1,7 @@
1
+ import React from "react"
2
+ import "./DashBlocks.scss"
3
+
4
+ const DashBlocks = (props: { children: React.ReactNode }) => (
5
+ <div className="dash-blocks">{props.children}</div>
6
+ )
7
+ export { DashBlocks as default, DashBlocks }
@@ -0,0 +1,201 @@
1
+ .form-card {
2
+ @apply bg-white;
3
+
4
+ @screen md {
5
+ @apply mb-6;
6
+ @apply border;
7
+ @apply border-gray-450;
8
+ @apply rounded-lg;
9
+ }
10
+
11
+ @screen print {
12
+ @apply border-0;
13
+ }
14
+
15
+ hr,
16
+ .border-b {
17
+ @apply border-gray-450;
18
+ }
19
+
20
+ .hr {
21
+ @apply my-6;
22
+ }
23
+ }
24
+
25
+ .form-card__title {
26
+ @apply text-center;
27
+ width: fit-content;
28
+ @apply mt-4;
29
+ @apply mx-auto;
30
+ @apply pt-4;
31
+ @apply px-3;
32
+ @apply border-t-4;
33
+ @apply border-primary;
34
+ @apply leading-tight;
35
+
36
+ @screen md {
37
+ @apply mx-auto;
38
+ @apply px-0;
39
+ }
40
+
41
+ &.is-borderless {
42
+ @apply pt-0;
43
+ @apply mt-0;
44
+ @apply border-t-0;
45
+ }
46
+ }
47
+
48
+ .form-card__back {
49
+ @apply ml-8;
50
+ @apply -mb-5;
51
+
52
+ @screen md {
53
+ @apply mt-5;
54
+ }
55
+
56
+ a {
57
+ @apply underline;
58
+ }
59
+ }
60
+
61
+ .form-card__lead,
62
+ .form-card__group {
63
+ @apply py-8;
64
+ @apply px-6;
65
+
66
+ @screen md {
67
+ @apply mx-8;
68
+ }
69
+
70
+ @screen print {
71
+ @apply py-2;
72
+ @apply px-0;
73
+ }
74
+ }
75
+
76
+ .form-card__lead {
77
+ @apply pt-12;
78
+ @apply pb-8;
79
+
80
+ @screen md {
81
+ @apply px-0;
82
+ }
83
+
84
+ @screen print {
85
+ @apply py-2;
86
+ }
87
+ }
88
+
89
+ .form-card__group {
90
+ @screen md {
91
+ @apply px-8;
92
+ }
93
+
94
+ @screen print {
95
+ @apply px-0;
96
+ }
97
+ }
98
+
99
+ .form-card__header {
100
+ @apply text-white;
101
+ @apply text-center;
102
+
103
+ @screen md {
104
+ @apply rounded-b-lg;
105
+ }
106
+ }
107
+
108
+ .form-card__header_group {
109
+ @apply bg-primary;
110
+ @apply p-4;
111
+
112
+ @screen md {
113
+ @apply rounded-t-lg;
114
+ }
115
+
116
+ @screen print {
117
+ @apply py-0;
118
+ }
119
+ }
120
+
121
+ .form-card__header_title {
122
+ @apply text-lg;
123
+ @apply font-alt-sans;
124
+ @apply font-bold;
125
+ @apply uppercase;
126
+ @apply mb-0;
127
+ }
128
+
129
+ .form-card__header_nav {
130
+ @apply py-4;
131
+ @apply bg-white;
132
+ @apply rounded-b-lg;
133
+ @apply overflow-auto;
134
+
135
+ @screen md {
136
+ @apply p-4;
137
+ }
138
+
139
+ @screen print {
140
+ @apply py-0;
141
+ }
142
+ }
143
+
144
+ .form-card__pager {
145
+ @apply text-center;
146
+
147
+ button,
148
+ .button {
149
+ @apply mb-0;
150
+ }
151
+ }
152
+
153
+ .form-card__pager-row {
154
+ @apply px-8;
155
+ @apply py-4;
156
+
157
+ &.primary {
158
+ @apply bg-primary-lighter;
159
+ @apply py-8;
160
+ }
161
+
162
+ &.border-t,
163
+ &.border-b {
164
+ @apply border-gray-450;
165
+ }
166
+ }
167
+
168
+ .form--card__sub-header {
169
+ @apply py-4;
170
+ @apply px-8;
171
+ @apply bg-gray-300;
172
+ @apply flex;
173
+ @apply justify-between;
174
+ @apply border-solid;
175
+ @apply border-t;
176
+ @apply border-gray-450;
177
+
178
+ .edit-link {
179
+ @apply self-center;
180
+ }
181
+
182
+ @screen print {
183
+ @apply px-0;
184
+ @apply py-1;
185
+ }
186
+ }
187
+
188
+ .form-card__sub-title {
189
+ @apply mb-0;
190
+ }
191
+
192
+ .form-card__paragraph-title {
193
+ @apply uppercase;
194
+ @apply text-gray-750;
195
+ @apply tracking-widest;
196
+ @apply font-semibold;
197
+ @apply font-sans;
198
+ @apply text-tiny;
199
+ @apply mb-2;
200
+ @apply inline-block;
201
+ }
@@ -0,0 +1,29 @@
1
+ import * as React from "react"
2
+ import "./FormCard.scss"
3
+
4
+ export interface FormCardProps {
5
+ header?: string
6
+ children: React.ReactNode
7
+ className?: string
8
+ }
9
+
10
+ const FormCard = (props: FormCardProps) => {
11
+ const classNames = props.className ? `${props.className} form-card` : "form-card"
12
+ if (props.header) {
13
+ return (
14
+ <article className={classNames}>
15
+ <div className="form-card__header">
16
+ <header className="form-card__header_group">
17
+ <h5 className="form-card__header_title">{props.header}</h5>
18
+ </header>
19
+
20
+ <div className="form-card__header_nav">{props.children}</div>
21
+ </div>
22
+ </article>
23
+ )
24
+ }
25
+
26
+ return <article className={classNames}>{props.children}</article>
27
+ }
28
+
29
+ export { FormCard as default, FormCard }
@@ -0,0 +1,51 @@
1
+ import * as React from "react"
2
+ import { Icon, IconFillColors } from "../icons/Icon"
3
+ import { t } from "../helpers/translator"
4
+
5
+ export interface HousingCounselorProps {
6
+ addressCityState?: string
7
+ addressStreet?: string
8
+ languages: string[]
9
+ name: string
10
+ phone?: string
11
+ website?: string
12
+ }
13
+
14
+ const LanguageLabel = (language: string) => {
15
+ return (
16
+ <span className="pill" key={language}>
17
+ {language}
18
+ </span>
19
+ )
20
+ }
21
+
22
+ const HousingCounselor = (props: HousingCounselorProps) => {
23
+ return (
24
+ <div className="resource-item text-base">
25
+ <h3 className="font-sans text-lg">{props.name}</h3>
26
+ <p className="text-sm text-gray-800 pb-2">
27
+ {t("housingCounselors.languageServices")}
28
+ {props.languages.map((language) => LanguageLabel(language))}
29
+ </p>
30
+ {props.addressStreet && (
31
+ <p className="icon-item pb-2">
32
+ {props.addressStreet} <br /> {props.addressCityState}
33
+ </p>
34
+ )}
35
+ {props.phone && (
36
+ <a className="icon-item pb-1" href={`tel:+1${props.phone}`}>
37
+ <Icon symbol="phone" size="medium" fill={IconFillColors.primary} />
38
+ {` ${t("housingCounselors.call", { number: props.phone })}`}
39
+ </a>
40
+ )}
41
+ {props.website && (
42
+ <a className="icon-item" href={props.website}>
43
+ <Icon symbol="globe" size="medium" fill={IconFillColors.primary} />
44
+ {` ${t("t.website")}`}
45
+ </a>
46
+ )}
47
+ </div>
48
+ )
49
+ }
50
+
51
+ export { HousingCounselor as default, HousingCounselor }