@bloom-housing/ui-components 4.0.0 → 4.0.1-alpha.0

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,33 @@
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.0](https://github.com/seanmalbert/bloom/compare/@bloom-housing/ui-components@4.0.0...@bloom-housing/ui-components@4.0.1-alpha.0) (2021-12-23)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * make numbered list breakpoint match config ([326df54](https://github.com/seanmalbert/bloom/commit/326df5404d2a967f1a36f8ba7635d4cb92d37742))
12
+ * make primary buttons primary background ([1b44435](https://github.com/seanmalbert/bloom/commit/1b44435aef22d814a0b511d7d63129d73a7b78ac))
13
+ * Update hardcoded translations ([c58bf25](https://github.com/seanmalbert/bloom/commit/c58bf25bb7243ea357e208aef88e74af4a968e97)), closes [#1927](https://github.com/seanmalbert/bloom/issues/1927)
14
+ * Update translation ([f8d2604](https://github.com/seanmalbert/bloom/commit/f8d2604b5244ca9c5bc92665d056f5e58d32f978))
15
+
16
+
17
+ * 2227/lock login attempts frontend (#2260) ([281ea43](https://github.com/seanmalbert/bloom/commit/281ea435e618a73a73f233a7a494f961fbac8fa2)), closes [#2260](https://github.com/seanmalbert/bloom/issues/2260) [#1927](https://github.com/seanmalbert/bloom/issues/1927) [#1927](https://github.com/seanmalbert/bloom/issues/1927) [#1927](https://github.com/seanmalbert/bloom/issues/1927) [#1927](https://github.com/seanmalbert/bloom/issues/1927) [#1927](https://github.com/seanmalbert/bloom/issues/1927) [#1927](https://github.com/seanmalbert/bloom/issues/1927) [#1927](https://github.com/seanmalbert/bloom/issues/1927) [#1927](https://github.com/seanmalbert/bloom/issues/1927) [#1927](https://github.com/seanmalbert/bloom/issues/1927) [#1927](https://github.com/seanmalbert/bloom/issues/1927) [#1927](https://github.com/seanmalbert/bloom/issues/1927) [#1927](https://github.com/seanmalbert/bloom/issues/1927) [#1927](https://github.com/seanmalbert/bloom/issues/1927)
18
+
19
+
20
+ ### Features
21
+
22
+ * add matched style to ApplicationStatus ([a54fb97](https://github.com/seanmalbert/bloom/commit/a54fb9769b68c9362e5f312a1021f5d0ba3d17a7))
23
+
24
+
25
+ ### BREAKING CHANGES
26
+
27
+ * sign-in pages have been updated
28
+
29
+
30
+
31
+
32
+
6
33
  # [4.0.0](https://github.com/seanmalbert/bloom/compare/@bloom-housing/ui-components@3.0.1-alpha.48...@bloom-housing/ui-components@4.0.0) (2021-12-22)
7
34
 
8
35
 
package/index.ts CHANGED
@@ -119,6 +119,7 @@ export * from "./src/page_components/listing/listing_sidebar/events/OpenHouseEve
119
119
  export * from "./src/page_components/listing/listing_sidebar/events/LotteryResultsEvent"
120
120
  export * from "./src/page_components/listing/listing_sidebar/events/PublicLotteryEvent"
121
121
  export * from "./src/page_components/listing/listing_sidebar/events/EventDateSection"
122
+ export * from "./src/page_components/sign-in/FormSignIn"
122
123
 
123
124
  /* Responsive Wrappers */
124
125
  export * from "./src/sections/ResponsiveWrappers"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bloom-housing/ui-components",
3
- "version": "4.0.0",
3
+ "version": "4.0.1-alpha.0",
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.1",
72
+ "@bloom-housing/backend-core": "^3.0.2-alpha.0",
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": "7f017f5b74d996eb9385d767825a2a842f5456ac"
103
+ "gitHead": "02379da7dc3cf07b4476a19d5406abddefb47164"
104
104
  }
@@ -3,4 +3,5 @@ export enum ApplicationStatusType {
3
3
  Closed,
4
4
  PreLottery,
5
5
  PostLottery,
6
+ Matched,
6
7
  }
@@ -48,7 +48,7 @@
48
48
  .numbered-list li:last-of-type {
49
49
  margin-bottom: 0.5rem;
50
50
  }
51
- @media only screen and (min-width: 60.0625em) {
51
+ @screen md {
52
52
  .numbered-list li {
53
53
  margin: 0 0 1.5rem 2.5rem;
54
54
  }
@@ -66,13 +66,13 @@
66
66
 
67
67
  @mixin filled-appearances() {
68
68
  &.is-primary {
69
- @apply bg-primary-dark;
70
- @apply border-primary-dark;
69
+ @apply bg-primary;
70
+ @apply border-primary;
71
71
  @apply text-white;
72
72
 
73
73
  &:hover {
74
- @apply bg-primary-darker;
75
- @apply border-primary-darker;
74
+ @apply bg-primary-dark;
75
+ @apply border-primary-dark;
76
76
  }
77
77
  }
78
78
 
@@ -831,7 +831,15 @@
831
831
  "error": "There was an error signing you in",
832
832
  "errorGenericMessage": "Please try again, or contact support for help.",
833
833
  "forgotPassword": "Forgot password?",
834
- "success": "Welcome back, %{name}!"
834
+ "success": "Welcome back, %{name}!",
835
+ "accountHasBeenLocked": "For security reasons, this account has been locked.",
836
+ "youHaveToWait": "You’ll have to wait 30 minutes since the last failed attempt before trying again.",
837
+ "enterValidEmailAndPassword": "Please enter a valid email and password.",
838
+ "afterFailedAttempts": "For security reasons, after 5 failed attempts, you’ll have to wait 30 minutes before trying again.",
839
+ "partnersSignIn": "Partners Sign In",
840
+ "dontHaveAccount": "Don't have an account",
841
+ "enterLoginPassword": "Please enter your login password",
842
+ "enterLoginEmail": "Please enter your login email"
835
843
  },
836
844
  "createAccount": {
837
845
  "accountConfirmed": "Your account was successfully confirmed.",
@@ -62,6 +62,15 @@
62
62
  }
63
63
  }
64
64
 
65
+ .alert-box__head {
66
+ @apply flex justify-between;
67
+ @apply w-full;
68
+ }
69
+
70
+ .alert-box__title {
71
+ @apply flex justify-between;
72
+ }
73
+
65
74
  .alert-box__body {
66
75
  @apply ml-2;
67
76
  @apply font-semibold;
@@ -45,24 +45,29 @@ const AlertBox = (props: AlertBoxProps) => {
45
45
 
46
46
  let innerSection = (
47
47
  <>
48
- <span className="alert-box__icon">
49
- <Icon
50
- size="medium"
51
- symbol={icons[props.type || "alert"]}
52
- fill={props.inverted ? IconFillColors.white : undefined}
53
- />
54
- </span>
55
- <span className="alert-box__body">
56
- {typeof props.children === "string" ? <p>{props.children}</p> : props.children}
57
- </span>
58
- {closeable && (
59
- <button
60
- className={`alert-box__close ${props.inverted ? "text-white" : ""}`}
61
- onClick={onClose}
62
- >
63
- &times;
64
- </button>
65
- )}
48
+ <div className="alert-box__head">
49
+ <div className="alert-box__title">
50
+ <span className="alert-box__icon">
51
+ <Icon
52
+ size="medium"
53
+ symbol={icons[props.type || "alert"]}
54
+ fill={props.inverted ? IconFillColors.white : undefined}
55
+ />
56
+ </span>
57
+ <span className="alert-box__body">
58
+ {typeof props.children === "string" ? <p>{props.children}</p> : props.children}
59
+ </span>
60
+ </div>
61
+
62
+ {closeable && (
63
+ <button
64
+ className={`alert-box__close ${props.inverted ? "text-white" : ""}`}
65
+ onClick={onClose}
66
+ >
67
+ &times;
68
+ </button>
69
+ )}
70
+ </div>
66
71
  </>
67
72
  )
68
73
  if (props.boundToLayoutWidth) {
@@ -7,7 +7,7 @@ import "./AlertNotice.scss"
7
7
  export interface AlertNoticeProps {
8
8
  type?: AlertTypes
9
9
  inverted?: boolean
10
- title: ReactNode
10
+ title?: ReactNode
11
11
  children: ReactNode
12
12
  className?: string
13
13
  }
@@ -23,9 +23,11 @@ const AlertNotice = (props: AlertNoticeProps) => {
23
23
 
24
24
  return (
25
25
  <div className={classNames}>
26
- <div className={`alert-notice__title ${colorClass}`}>
27
- {typeof props.title === "string" ? <p>{props.title}</p> : props.title}
28
- </div>
26
+ {props.title && (
27
+ <div className={`alert-notice__title ${colorClass}`}>
28
+ {typeof props.title === "string" ? <p>{props.title}</p> : props.title}
29
+ </div>
30
+ )}
29
31
 
30
32
  <div className="alert-notice__body">
31
33
  {typeof props.children === "string" ? <p>{props.children}</p> : props.children}
@@ -1,5 +1,5 @@
1
1
  import * as React from "react"
2
- import { Icon, IconFillColors } from "../icons/Icon"
2
+ import { Icon, IconFillColors, IconTypes } from "../icons/Icon"
3
3
  import { ApplicationStatusType } from "../global/ApplicationStatusType"
4
4
  import "./ApplicationStatus.scss"
5
5
 
@@ -9,6 +9,7 @@ export interface ApplicationStatusProps {
9
9
  status?: ApplicationStatusType
10
10
  vivid?: boolean
11
11
  withIcon?: boolean
12
+ iconType?: IconTypes
12
13
  }
13
14
 
14
15
  const ApplicationStatus = (props: ApplicationStatusProps) => {
@@ -21,13 +22,15 @@ const ApplicationStatus = (props: ApplicationStatusProps) => {
21
22
  const status = props.status || ApplicationStatusType.Open
22
23
  const content = props.content
23
24
  const withIcon = props.withIcon ?? true
25
+ const iconType = props.iconType ?? "clock"
24
26
 
25
27
  let icon
26
28
 
27
29
  if (withIcon) {
28
30
  icon = (
29
31
  <span>
30
- <Icon size="medium" symbol="clock" fill={vivid ? IconFillColors.white : undefined} /> &nbsp;
32
+ <Icon size="medium" symbol={iconType} fill={vivid ? IconFillColors.white : undefined} />{" "}
33
+ &nbsp;
31
34
  </span>
32
35
  )
33
36
  }
@@ -43,6 +46,10 @@ const ApplicationStatus = (props: ApplicationStatusProps) => {
43
46
  bgColor = "bg-gray-850"
44
47
  textColor = "text-white"
45
48
  break
49
+ case ApplicationStatusType.Matched:
50
+ bgColor = "bg-green-700"
51
+ textColor = "text-white"
52
+ break
46
53
  default:
47
54
  bgColor = "bg-primary"
48
55
  }
@@ -0,0 +1,128 @@
1
+ import React from "react"
2
+ import Link from "next/link"
3
+ import {
4
+ AppearanceStyleType,
5
+ Button,
6
+ Field,
7
+ Form,
8
+ FormCard,
9
+ Icon,
10
+ LinkButton,
11
+ t,
12
+ AlertBox,
13
+ SiteAlert,
14
+ AlertNotice,
15
+ ErrorMessage,
16
+ } from "@bloom-housing/ui-components"
17
+ import type { UseFormMethods } from "react-hook-form"
18
+ import type { NetworkErrorValue, NetworkErrorReset } from "@bloom-housing/shared-helpers"
19
+
20
+ export type FormSignInProps = {
21
+ control: FormSignInControl
22
+ onSubmit: (data: FormSignInValues) => void
23
+ networkError: FormSignInNetworkError
24
+ showRegisterBtn?: boolean
25
+ }
26
+
27
+ export type FormSignInNetworkError = {
28
+ error: NetworkErrorValue
29
+ reset: NetworkErrorReset
30
+ }
31
+
32
+ export type FormSignInControl = {
33
+ errors: UseFormMethods["errors"]
34
+ handleSubmit: UseFormMethods["handleSubmit"]
35
+ register: UseFormMethods["register"]
36
+ }
37
+
38
+ export type FormSignInValues = {
39
+ email: string
40
+ password: string
41
+ }
42
+
43
+ const FormSignIn = ({
44
+ onSubmit,
45
+ networkError,
46
+ showRegisterBtn,
47
+ control: { errors, register, handleSubmit },
48
+ }: FormSignInProps) => {
49
+ const onError = () => {
50
+ window.scrollTo(0, 0)
51
+ }
52
+
53
+ return (
54
+ <FormCard>
55
+ <div className="form-card__lead text-center border-b mx-0">
56
+ <Icon size="2xl" symbol="profile" />
57
+ <h2 className="form-card__title">{t(`nav.signIn`)}</h2>
58
+ </div>
59
+
60
+ {Object.entries(errors).length > 0 && !networkError.error && (
61
+ <AlertBox type="alert" inverted closeable>
62
+ {errors.authentication ? errors.authentication.message : t("errors.errorsToResolve")}
63
+ </AlertBox>
64
+ )}
65
+
66
+ {!!networkError.error && Object.entries(errors).length === 0 && (
67
+ <ErrorMessage id={"householdsize-error"} error={!!networkError.error}>
68
+ <AlertBox type="alert" inverted onClose={() => networkError.reset()}>
69
+ {networkError.error.title}
70
+ </AlertBox>
71
+
72
+ <AlertNotice title="" type="alert" inverted>
73
+ {networkError.error.content}
74
+ </AlertNotice>
75
+ </ErrorMessage>
76
+ )}
77
+
78
+ <SiteAlert type="notice" dismissable />
79
+ <div className="form-card__group pt-0 border-b">
80
+ <Form id="sign-in" className="mt-10" onSubmit={handleSubmit(onSubmit, onError)}>
81
+ <Field
82
+ caps={true}
83
+ name="email"
84
+ label={t("t.email")}
85
+ validation={{ required: true }}
86
+ error={errors.email}
87
+ errorMessage={t("authentication.signIn.enterLoginEmail")}
88
+ register={register}
89
+ dataTestId="sign-in-email-field"
90
+ />
91
+
92
+ <aside className="float-right text-tiny font-semibold">
93
+ <Link href="/forgot-password">
94
+ <a>{t("authentication.signIn.forgotPassword")}</a>
95
+ </Link>
96
+ </aside>
97
+
98
+ <Field
99
+ caps={true}
100
+ name="password"
101
+ label={t("authentication.createAccount.password")}
102
+ validation={{ required: true }}
103
+ error={errors.password}
104
+ errorMessage={t("authentication.signIn.enterLoginPassword")}
105
+ register={register}
106
+ type="password"
107
+ dataTestId="sign-in-password-field"
108
+ />
109
+
110
+ <div className="text-center mt-6">
111
+ <Button styleType={AppearanceStyleType.primary} data-test-id="sign-in-button">
112
+ {t("nav.signIn")}
113
+ </Button>
114
+ </div>
115
+ </Form>
116
+ </div>
117
+ {showRegisterBtn && (
118
+ <div className="form-card__group text-center">
119
+ <h2 className="mb-6">{t("authentication.createAccount.noAccount")}</h2>
120
+
121
+ <LinkButton href="/create-account">{t("account.createAccount")}</LinkButton>
122
+ </div>
123
+ )}
124
+ </FormCard>
125
+ )
126
+ }
127
+
128
+ export { FormSignIn as default, FormSignIn }