@thecb/components 3.4.1 → 3.4.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thecb/components",
3
- "version": "3.4.1",
3
+ "version": "3.4.2",
4
4
  "description": "Common lib for CityBase react components",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.esm.js",
@@ -0,0 +1,28 @@
1
+ import React from "react";
2
+ import { fallbackValues } from "./Icons.theme";
3
+ import { themeComponent } from "../../../util/themeUtils";
4
+
5
+ const AutopayOnIcon = ({ themeValues }) => (
6
+ <svg
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ width="12"
9
+ height="13"
10
+ viewBox="0 0 12 13"
11
+ >
12
+ <g fill="none" fillRule="evenodd" stroke="none" strokeWidth="1">
13
+ <path
14
+ className="autopayIcon"
15
+ fill={themeValues.primaryColor}
16
+ fillRule="nonzero"
17
+ d="M1.898 5.75c.079 0 .141-.02.188-.059a.281.281 0 00.094-.152 3.825 3.825 0 011.394-2.144A3.838 3.838 0 016 2.563c.5 0 .98.09 1.441.27.461.179.88.44 1.254.784l-.984.985A.542.542 0 007.547 5c0 .156.055.29.164.398.11.11.242.165.398.165h3.141c.156 0 .289-.055.398-.165A.542.542 0 0011.812 5V1.86a.542.542 0 00-.164-.399.542.542 0 00-.398-.164.542.542 0 00-.398.164l-.844.844A5.699 5.699 0 006 .688c-.938 0-1.809.207-2.613.62-.805.415-1.48.981-2.028 1.7A5.726 5.726 0 00.281 5.422a.265.265 0 00.059.223c.055.07.129.105.222.105h1.336zM6 12.312c.937 0 1.809-.207 2.613-.62a5.919 5.919 0 002.028-1.7 5.726 5.726 0 001.078-2.414.265.265 0 00-.059-.223.267.267 0 00-.223-.105h-1.335c-.079 0-.141.02-.188.059a.281.281 0 00-.094.152 3.825 3.825 0 01-1.394 2.144c-.711.555-1.52.833-2.426.833-.5 0-.98-.09-1.441-.27a3.985 3.985 0 01-1.254-.785l.984-.985A.542.542 0 004.453 8a.542.542 0 00-.164-.398.542.542 0 00-.398-.164H.75a.542.542 0 00-.398.164A.542.542 0 00.187 8v3.14c0 .157.055.29.165.4.109.108.242.163.398.163.156 0 .29-.055.398-.164l.844-.844A5.699 5.699 0 006 12.312z"
18
+ ></path>
19
+ </g>
20
+ </svg>
21
+ );
22
+
23
+ export default themeComponent(
24
+ AutopayOnIcon,
25
+ "Icons",
26
+ fallbackValues,
27
+ "primary"
28
+ );
@@ -20,7 +20,8 @@ import {
20
20
  CheckmarkIcon,
21
21
  BankIcon,
22
22
  GenericCard,
23
- PaymentIcon
23
+ PaymentIcon,
24
+ AutopayOnIcon
24
25
  } from "./index";
25
26
 
26
27
  const story = page({
@@ -48,3 +49,4 @@ export const checkmarkIcon = () => <CheckmarkIcon />;
48
49
  export const bankIcon = () => <BankIcon />;
49
50
  export const genericCard = () => <GenericCard />;
50
51
  export const paymentIco = () => <PaymentIcon />;
52
+ export const autopayOnIcon = () => <AutopayOnIcon />;
@@ -18,6 +18,7 @@ import BankIcon from "./BankIcon";
18
18
  import GenericCard from "./GenericCard";
19
19
  import PaymentIcon from "./PaymentIcon";
20
20
  import IconAdd from "./IconAdd";
21
+ import AutopayOnIcon from "./AutopayOnIcon";
21
22
 
22
23
  export {
23
24
  AccountsIcon,
@@ -39,5 +40,6 @@ export {
39
40
  BankIcon,
40
41
  GenericCard,
41
42
  PaymentIcon,
42
- IconAdd
43
+ IconAdd,
44
+ AutopayOnIcon
43
45
  };
@@ -13,22 +13,32 @@ const Obligation = ({
13
13
  obligations,
14
14
  actions,
15
15
  autoPayEnabled,
16
+ autoPayAvailable,
17
+ handleAutopayAction,
18
+ deactivatePaymentSchedule,
19
+ autoPaySchedule,
20
+ navigateToSettings,
16
21
  isMobile
17
22
  }) => {
18
23
  const obligation = obligations[0];
19
24
  const { customAttributes } = obligation;
20
25
  return (
21
26
  <Box
22
- background={WHITE}
27
+ padding="0"
23
28
  borderRadius="4px"
24
29
  boxShadow={`0px 0px 5px 0px ${GHOST_GREY}`}
25
30
  >
26
- <Stack childGap="14px">
27
- <Box key={`${obligations[0].id}-top`} padding="0 8px" minWidth="100%">
28
- <Cluster justify="space-between" align="center" childGap="4px" nowrap>
29
- <Box padding="0">
30
- <Cluster justify="flex-start" align="center">
31
- {!isMobile && (
31
+ <Box background={WHITE}>
32
+ <Stack childGap="14px">
33
+ <Box key={`${obligations[0].id}-top`} padding="0 8px" minWidth="100%">
34
+ <Cluster
35
+ justify="space-between"
36
+ align="center"
37
+ childGap="4px"
38
+ nowrap
39
+ >
40
+ <Box padding="0">
41
+ <Cluster justify="flex-start" align="center">
32
42
  <IconModule
33
43
  icon={config.icon}
34
44
  iconDefault={config.iconDefault}
@@ -36,32 +46,59 @@ const Obligation = ({
36
46
  iconValue={config.iconValue}
37
47
  customAttributes={customAttributes}
38
48
  />
39
- )}
40
- <TitleModule
41
- title={obligation.description}
42
- subtitle={obligation.subDescription}
43
- titleColor={BRIGHT_GREY}
49
+ <TitleModule
50
+ title={obligation.description}
51
+ subtitle={obligation.subDescription}
52
+ titleColor={BRIGHT_GREY}
53
+ isMobile={isMobile}
54
+ />
55
+ </Cluster>
56
+ </Box>
57
+ {!isMobile && (
58
+ <AmountModule
59
+ totalAmountDue={obligations.reduce(
60
+ (acc, curr) => acc + curr.amountDue,
61
+ 0
62
+ )}
63
+ autoPayEnabled={autoPayEnabled}
44
64
  isMobile={isMobile}
65
+ deactivatePaymentSchedule={deactivatePaymentSchedule}
66
+ navigateToSettings={navigateToSettings}
67
+ autoPaySchedule={autoPaySchedule}
45
68
  />
46
- </Cluster>
47
- </Box>
48
- <AmountModule
49
- totalAmountDue={obligations.reduce(
50
- (acc, curr) => acc + curr.amountDue,
51
- 0
52
69
  )}
70
+ </Cluster>
71
+ </Box>
72
+ {!isMobile && (
73
+ <PaymentDetailsActions
74
+ obligations={obligations}
53
75
  autoPayEnabled={autoPayEnabled}
76
+ autoPayAvailable={autoPayAvailable}
77
+ handleAutopayAction={handleAutopayAction}
78
+ deactivatePaymentSchedule={deactivatePaymentSchedule}
79
+ autoPaySchedule={autoPaySchedule}
80
+ navigateToSettings={navigateToSettings}
81
+ config={config}
82
+ actions={actions}
54
83
  isMobile={isMobile}
55
84
  />
56
- </Cluster>
57
- </Box>
85
+ )}
86
+ </Stack>
87
+ </Box>
88
+ {isMobile && (
58
89
  <PaymentDetailsActions
59
90
  obligations={obligations}
91
+ autoPayEnabled={autoPayEnabled}
92
+ autoPayAvailable={autoPayAvailable}
93
+ handleAutopayAction={handleAutopayAction}
94
+ deactivatePaymentSchedule={deactivatePaymentSchedule}
95
+ autoPaySchedule={autoPaySchedule}
96
+ navigateToSettings={navigateToSettings}
60
97
  config={config}
61
98
  actions={actions}
62
99
  isMobile={isMobile}
63
100
  />
64
- </Stack>
101
+ )}
65
102
  </Box>
66
103
  );
67
104
  };
@@ -1,40 +1,48 @@
1
- import React from "react";
1
+ import React, { useState } from "react";
2
2
  import Text from "../../../atoms/text";
3
3
  import AmountCallout from "../../../atoms/amount-callout";
4
4
  import { Box, Stack } from "../../../atoms/layouts";
5
- import {
6
- FONT_WEIGHT_SEMIBOLD,
7
- FONT_WEIGHT_REGULAR
8
- } from "../../../../constants/style_constants";
9
- import { REGENT_GREY } from "../../../../constants/colors";
5
+ import { FONT_WEIGHT_SEMIBOLD } from "../../../../constants/style_constants";
10
6
  import { displayCurrency } from "../../../../util/general";
7
+ import { AutopayModalModule } from "./AutopayModalModule";
11
8
 
12
- const AmountModule = ({ totalAmountDue, autoPayEnabled, isMobile }) => (
13
- <Box padding="0 0.25rem 0 0">
14
- <Stack childGap="0">
15
- <Text
16
- variant="pS"
17
- weight={FONT_WEIGHT_SEMIBOLD}
18
- extraStyles={`text-align: right;`}
19
- >
20
- {isMobile ? "Total Due" : "Total Amount Due"}
21
- </Text>
22
- <AmountCallout
23
- amount={displayCurrency(totalAmountDue)}
24
- textAlign="right"
25
- />
26
- {autoPayEnabled && (
9
+ const AmountModule = ({
10
+ totalAmountDue,
11
+ autoPayEnabled,
12
+ isMobile,
13
+ deactivatePaymentSchedule,
14
+ navigateToSettings,
15
+ autoPaySchedule
16
+ }) => {
17
+ const [modalOpen, toggleModal] = useState(false);
18
+ return (
19
+ <Box padding="0 0.25rem 0 0">
20
+ <Stack childGap="0">
27
21
  <Text
28
- variant="p"
29
- weight={FONT_WEIGHT_REGULAR}
30
- color={REGENT_GREY}
31
- extraStyles={`font-style: italic; text-align: right;`}
22
+ variant="pS"
23
+ weight={FONT_WEIGHT_SEMIBOLD}
24
+ extraStyles={isMobile ? `text-align: left;` : `text-align: right;`}
32
25
  >
33
- {isMobile ? "Autopay On" : "Autopay Enabled"}
26
+ {isMobile ? "Total Due" : "Total Amount Due"}
34
27
  </Text>
35
- )}
36
- </Stack>
37
- </Box>
38
- );
28
+ <AmountCallout
29
+ amount={displayCurrency(totalAmountDue)}
30
+ textAlign={isMobile ? "left" : "right"}
31
+ />
32
+ {autoPayEnabled && (
33
+ <AutopayModalModule
34
+ autoPayActive={autoPayEnabled}
35
+ autoPaySchedule={autoPaySchedule}
36
+ toggleModal={toggleModal}
37
+ modalOpen={modalOpen}
38
+ navigateToSettings={navigateToSettings}
39
+ deactivatePaymentSchedule={deactivatePaymentSchedule}
40
+ isMobile={isMobile}
41
+ />
42
+ )}
43
+ </Stack>
44
+ </Box>
45
+ );
46
+ };
39
47
 
40
48
  export default AmountModule;
@@ -0,0 +1,99 @@
1
+ import React from "react";
2
+ import Modal from "../../modal";
3
+ import ButtonWithAction from "../../../atoms/button-with-action";
4
+ import { AutopayOnIcon } from "../../../atoms/icons";
5
+ import { Box, Cluster } from "../../../atoms/layouts";
6
+ import { fallbackValues } from "./AutopayModalModule.theme";
7
+ import { themeComponent } from "../../../../util/themeUtils";
8
+
9
+ const AutopayModal = ({
10
+ autoPayActive,
11
+ autoPaySchedule,
12
+ toggleModal,
13
+ modalOpen,
14
+ deactivatePaymentSchedule,
15
+ navigateToSettings,
16
+ buttonLinkType,
17
+ isMobile,
18
+ themeValues
19
+ }) => {
20
+ const modalExtraProps = {
21
+ modalHeaderText: autoPayActive ? "Deactivate Autopay" : "Set Up Autopay",
22
+ modalBodyText: autoPayActive
23
+ ? "Are you sure you want to deactivate autopay? You will need to manually make your next payment."
24
+ : "To set up autopay you must save a payment method and address in your profile. Do you want to save these now?",
25
+ continueButtonText: autoPayActive ? "Disable Autopay" : "Add to Profile",
26
+ useDangerButton: autoPayActive,
27
+ continueAction: autoPayActive
28
+ ? () => {
29
+ deactivatePaymentSchedule(autoPaySchedule);
30
+ toggleModal(false);
31
+ }
32
+ : navigateToSettings
33
+ };
34
+
35
+ const hoverStyles = `
36
+ &:hover {
37
+ .autopayIcon { fill: ${themeValues.hoverColor}; text-decoration: underline; }
38
+ }`;
39
+
40
+ const activeStyles = `
41
+ &:active {
42
+ .autopayIcon { fill: ${themeValues.activeColor}; text-decoration: underline; }
43
+ }`;
44
+
45
+ const defaultStyles = `
46
+ .autopayIcon { fill: ${themeValues.color}; text-decoration: underline; }
47
+ `;
48
+ return (
49
+ <Modal
50
+ ModalLink={() =>
51
+ buttonLinkType ? (
52
+ <ButtonWithAction
53
+ text={autoPayActive ? "Manage Autopay" : "Set Up Autopay"}
54
+ variant="tertiary"
55
+ action={() => {
56
+ toggleModal(true);
57
+ }}
58
+ dataQa="Manage Autopay"
59
+ extraStyles={isMobile && `flex-grow: 1; width: 100%;`}
60
+ />
61
+ ) : (
62
+ <Box
63
+ padding="0"
64
+ onClick={() => {
65
+ toggleModal(true);
66
+ }}
67
+ hoverStyles={hoverStyles}
68
+ activeStyles={activeStyles}
69
+ extraStyles={defaultStyles}
70
+ >
71
+ <Cluster
72
+ justify={isMobile ? "flex-start" : "flex-end"}
73
+ align="center"
74
+ >
75
+ <AutopayOnIcon />
76
+ <ButtonWithAction
77
+ text="Autopay On"
78
+ variant="smallGhost"
79
+ dataQa="Autopay On"
80
+ textExtraStyles={`font-size: 0.875rem; `}
81
+ extraStyles={`min-width: auto; padding: 0 0 0 6px;`}
82
+ />
83
+ </Cluster>
84
+ </Box>
85
+ )
86
+ }
87
+ showModal={() => toggleModal(true)}
88
+ hideModal={() => toggleModal(false)}
89
+ modalOpen={modalOpen}
90
+ {...modalExtraProps}
91
+ />
92
+ );
93
+ };
94
+
95
+ export const AutopayModalModule = themeComponent(
96
+ AutopayModal,
97
+ "AutopayModal",
98
+ fallbackValues
99
+ );
@@ -0,0 +1,9 @@
1
+ const color = "#15749D";
2
+ const hoverColor = "#116285";
3
+ const activeColor = "#0E506D";
4
+
5
+ export const fallbackValues = {
6
+ color,
7
+ hoverColor,
8
+ activeColor
9
+ };
@@ -1,10 +1,24 @@
1
1
  import React, { useState } from "react";
2
2
  import { Box, Cluster } from "../../../atoms/layouts";
3
3
  import ButtonWithAction from "../../../atoms/button-with-action";
4
+ import { AutopayModalModule } from "./AutopayModalModule";
4
5
  import { GHOST_GREY } from "../../../../constants/colors";
6
+ import AmountModule from "./AmountModule";
5
7
 
6
- const PaymentDetailsActions = ({ isMobile, obligations, config, actions }) => {
8
+ const PaymentDetailsActions = ({
9
+ isMobile,
10
+ obligations,
11
+ config,
12
+ actions,
13
+ autoPayEnabled,
14
+ autoPayAvailable,
15
+ handleAutopayAction,
16
+ deactivatePaymentSchedule,
17
+ navigateToSettings,
18
+ autoPaySchedule
19
+ }) => {
7
20
  const [isLoading, setIsLoading] = useState(false);
21
+ const [modalOpen, toggleModal] = useState(false);
8
22
  const { obligationSlug } = config;
9
23
  const { createPaymentFromProfile, setDetailedObligation } = actions;
10
24
  const detailsSlug =
@@ -20,46 +34,111 @@ const PaymentDetailsActions = ({ isMobile, obligations, config, actions }) => {
20
34
  };
21
35
  return (
22
36
  <Box
23
- padding="16px 0 0"
37
+ padding={isMobile ? "0" : "16px 0 0"}
24
38
  minWidth="100%"
25
39
  borderSize="1px"
26
40
  borderColor={GHOST_GREY}
27
41
  borderWidthOverride="1px 0 0 0"
28
42
  key={`${obligations[0].id}-actions`}
29
43
  >
30
- <Cluster
31
- justify={isMobile ? "center" : "flex-end"}
32
- align="center"
33
- childGap="0"
34
- >
44
+ {isMobile && (
35
45
  <Box
36
- padding={isMobile ? "0 8px 0 0" : "8px"}
37
- extraStyles={isMobile && `flex-grow: 1;`}
46
+ padding="16px 24px"
47
+ borderSize="1px"
48
+ borderColor={GHOST_GREY}
49
+ borderWidthOverride="0 0 1px 0"
38
50
  >
39
- <ButtonWithAction
40
- variant={isMobile ? "smallSecondary" : "secondary"}
41
- text={
42
- config.type === "ACCOUNT" ? "Account Details" : "Property Details"
43
- }
44
- action={handleDetailsClick}
45
- dataQa="Account Details"
46
- extraStyles={isMobile && `flex-grow: 1; width: 100%;`}
47
- />
51
+ <Cluster justify="space-between" align="center" nowrap>
52
+ <Box padding="0" width="100%">
53
+ <AmountModule
54
+ totalAmountDue={obligations.reduce(
55
+ (acc, curr) => acc + curr.amountDue,
56
+ 0
57
+ )}
58
+ autoPayEnabled={autoPayEnabled}
59
+ isMobile={isMobile}
60
+ deactivatePaymentSchedule={deactivatePaymentSchedule}
61
+ navigateToSettings={navigateToSettings}
62
+ autoPaySchedule={autoPaySchedule}
63
+ />
64
+ </Box>
65
+ <Box padding="0" width="100%">
66
+ <ButtonWithAction
67
+ isLoading={isLoading}
68
+ action={() => handleClick(obligations)}
69
+ text="Pay Now"
70
+ variant={isMobile ? "smallSecondary" : "secondary"}
71
+ dataQa="Pay Now"
72
+ extraStyles={isMobile && `flex-grow: 1; width: 100%;`}
73
+ />
74
+ </Box>
75
+ </Cluster>
48
76
  </Box>
49
- <Box
50
- padding={isMobile ? "0 0 0 8px" : "8px"}
51
- extraStyles={isMobile && `flex-grow: 1;`}
77
+ )}
78
+ <Box padding={isMobile ? "16px" : "0"}>
79
+ <Cluster
80
+ justify={isMobile ? "center" : "flex-end"}
81
+ align="center"
82
+ childGap="0"
52
83
  >
53
- <ButtonWithAction
54
- isLoading={isLoading}
55
- action={() => handleClick(obligations)}
56
- text="Make Payment"
57
- variant={isMobile ? "smallPrimary" : "primary"}
58
- dataQa="Make Payment"
59
- extraStyles={isMobile && `flex-grow: 1; width: 100%;`}
60
- />
61
- </Box>
62
- </Cluster>
84
+ <Box
85
+ padding={isMobile ? "0 8px 0 0" : "8px"}
86
+ extraStyles={isMobile && `flex-grow: 1;`}
87
+ >
88
+ <ButtonWithAction
89
+ variant="tertiary"
90
+ text={
91
+ config.type === "ACCOUNT"
92
+ ? "Account Details"
93
+ : "Property Details"
94
+ }
95
+ action={handleDetailsClick}
96
+ dataQa="Account Details"
97
+ extraStyles={isMobile && `flex-grow: 1; width: 100%;`}
98
+ />
99
+ </Box>
100
+ <Box
101
+ padding={isMobile ? "0 8px 0 0" : "8px"}
102
+ extraStyles={isMobile && `flex-grow: 1;`}
103
+ >
104
+ {autoPayAvailable && !autoPayEnabled ? (
105
+ <ButtonWithAction
106
+ variant="tertiary"
107
+ text="Set Up Autopay"
108
+ action={handleAutopayAction}
109
+ dataQa="Set Up Autopay"
110
+ extraStyles={isMobile && `flex-grow: 1; width: 100%;`}
111
+ />
112
+ ) : (
113
+ <AutopayModalModule
114
+ autoPayActive={autoPayEnabled}
115
+ autoPaySchedule={autoPaySchedule}
116
+ toggleModal={toggleModal}
117
+ modalOpen={modalOpen}
118
+ navigateToSettings={navigateToSettings}
119
+ deactivatePaymentSchedule={deactivatePaymentSchedule}
120
+ buttonLinkType
121
+ isMobile={isMobile}
122
+ />
123
+ )}
124
+ </Box>
125
+ {!isMobile && (
126
+ <Box
127
+ padding={isMobile ? "0 0 0 8px" : "8px"}
128
+ extraStyles={isMobile && `flex-grow: 1;`}
129
+ >
130
+ <ButtonWithAction
131
+ isLoading={isLoading}
132
+ action={() => handleClick(obligations)}
133
+ text="Pay Now"
134
+ variant={isMobile ? "smallSecondary" : "secondary"}
135
+ dataQa="Pay Now"
136
+ extraStyles={isMobile && `flex-grow: 1; width: 100%;`}
137
+ />
138
+ </Box>
139
+ )}
140
+ </Cluster>
141
+ </Box>
63
142
  </Box>
64
143
  );
65
144
  };