@stokr/components-library 3.0.31 → 3.0.33

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 (40) hide show
  1. package/README.md +72 -287
  2. package/dist/analytics/index.js +2 -1
  3. package/dist/components/2FA/Connect2FA.js +11 -1
  4. package/dist/components/2FA/EnterCode.js +13 -2
  5. package/dist/components/2FA/InstallAuthApp.js +4 -0
  6. package/dist/components/2FA/ResetCode.js +2 -1
  7. package/dist/components/2FA/Sucess2FA.js +14 -2
  8. package/dist/components/2FA/disable-2fa-flow.js +15 -2
  9. package/dist/components/2FA/enable-2fa-flow.js +5 -0
  10. package/dist/components/2FA/login-with-otp-flow.js +2 -2
  11. package/dist/components/2FA/main-flow.js +3 -0
  12. package/dist/components/Button/GlareButton.js +273 -0
  13. package/dist/components/ConfirmModal/ConfirmModal.js +21 -2
  14. package/dist/components/FAQ/FAQ.js +37 -23
  15. package/dist/components/ForgotPasswordModal/ForgotPasswordModal.js +24 -3
  16. package/dist/components/Header/Header.js +1 -1
  17. package/dist/components/Input/InputPassword.js +27 -12
  18. package/dist/components/Input/OtpInput.js +21 -7
  19. package/dist/components/Input/Select.js +11 -2
  20. package/dist/components/Input/TableFilterDropdown.js +23 -7
  21. package/dist/components/Layout/Layout.js +6 -3
  22. package/dist/components/LoginModal/LoginModal.js +7 -4
  23. package/dist/components/Modal/Modal.styles.js +10 -2
  24. package/dist/components/Modal/NewVentureModal/NewVentureModal.js +21 -6
  25. package/dist/components/Modal/PaymentModal.js +16 -16
  26. package/dist/components/RegisterConfirmModal/RegisterConfirmModal.js +1 -1
  27. package/dist/components/RegisterModal/RegisterModal.js +30 -5
  28. package/dist/components/ResetConfirmModal/ResetConfirmModal.js +1 -1
  29. package/dist/components/ResetPasswordModal/ResetPasswordModal.js +16 -4
  30. package/dist/components/StepController/StepControllerProgress.js +1 -0
  31. package/dist/components/Switch/Switch.js +5 -3
  32. package/dist/components/ToDoList/ToDoListTask.js +1 -0
  33. package/dist/components/VerifyEmailModal/VerifyEmailModal.js +14 -2
  34. package/dist/components/headerHo/HeaderHo.js +2 -0
  35. package/dist/components/taxId/complete.js +23 -2
  36. package/dist/components/taxId/flow.js +11 -1
  37. package/dist/components/taxId/register-taxid.js +25 -4
  38. package/dist/index.js +2 -0
  39. package/dist/utils/formatCurrencyValue.js +4 -2
  40. package/package.json +1 -1
@@ -80,6 +80,10 @@ const ClearAllOption = styled.div`
80
80
  background-color: ${colors.grey};
81
81
  }
82
82
  `;
83
+ function slugForDataCy(text) {
84
+ if (text == null || text === "") return "";
85
+ return String(text).toLowerCase().trim().replace(/\s+/g, "-").replace(/[^a-z0-9_-]/g, "");
86
+ }
83
87
  const TableFilterDropdown = ({
84
88
  label,
85
89
  options,
@@ -93,8 +97,10 @@ const TableFilterDropdown = ({
93
97
  menuTop = 8,
94
98
  showClearAll = false,
95
99
  clearAllText = "Clear all",
100
+ dataCy,
96
101
  ...props
97
102
  }) => {
103
+ const triggerDataCy = dataCy ?? (label ? `table-filter-${slugForDataCy(label)}` : "table-filter-dropdown");
98
104
  const [isOpen, setIsOpen] = useState(false);
99
105
  const [menuPosition, setMenuPosition] = useState({ top: 0, left: 0 });
100
106
  const containerRef = useRef(null);
@@ -191,19 +197,27 @@ const TableFilterDropdown = ({
191
197
  children: [
192
198
  /* @__PURE__ */ jsx(OptionsList, { children: options.map((option) => {
193
199
  const isSelected = value.includes(option.value);
194
- return /* @__PURE__ */ jsxs(CheckboxWrapperDiv, { onClick: (e) => handleOptionClick(option.value, e), children: [
195
- /* @__PURE__ */ jsx(CheckboxDiv, { isSelected, children: /* @__PURE__ */ jsx(SvgCheckIcon, {}) }),
196
- /* @__PURE__ */ jsx(OptionLabel, { children: option.label })
197
- ] }, option.value);
200
+ return /* @__PURE__ */ jsxs(
201
+ CheckboxWrapperDiv,
202
+ {
203
+ "data-cy": `${triggerDataCy}-option-${slugForDataCy(option.value)}`,
204
+ onClick: (e) => handleOptionClick(option.value, e),
205
+ children: [
206
+ /* @__PURE__ */ jsx(CheckboxDiv, { isSelected, children: /* @__PURE__ */ jsx(SvgCheckIcon, {}) }),
207
+ /* @__PURE__ */ jsx(OptionLabel, { children: option.label })
208
+ ]
209
+ },
210
+ option.value
211
+ );
198
212
  }) }),
199
- showClearAll && hasActiveFilters && /* @__PURE__ */ jsx(ClearAllOption, { onClick: handleClearAll, children: clearAllText })
213
+ showClearAll && hasActiveFilters && /* @__PURE__ */ jsx(ClearAllOption, { "data-cy": `${triggerDataCy}-clear-all`, onClick: handleClearAll, children: clearAllText })
200
214
  ]
201
215
  }
202
216
  );
203
217
  return createPortal(menu, document.body);
204
218
  };
205
219
  return /* @__PURE__ */ jsxs(DropdownContainer, { ref: containerRef, ...props, children: [
206
- /* @__PURE__ */ jsxs(TriggerContainer, { ref: triggerRef, onClick: handleTriggerClick, "data-clickable": "true", children: [
220
+ /* @__PURE__ */ jsxs(TriggerContainer, { ref: triggerRef, onClick: handleTriggerClick, "data-cy": triggerDataCy, "data-clickable": "true", children: [
207
221
  label && /* @__PURE__ */ jsx("span", { children: label }),
208
222
  /* @__PURE__ */ jsxs(IconWrapper, { children: [
209
223
  /* @__PURE__ */ jsx(IconComponent, {}),
@@ -240,7 +254,9 @@ TableFilterDropdown.propTypes = {
240
254
  /** Show "Clear all" option at the bottom of the list */
241
255
  showClearAll: PropTypes.bool,
242
256
  /** Custom text for the "Clear all" option */
243
- clearAllText: PropTypes.string
257
+ clearAllText: PropTypes.string,
258
+ /** Override default `table-filter-{label}` data-cy on trigger */
259
+ dataCy: PropTypes.string
244
260
  };
245
261
  export {
246
262
  TableFilterDropdown
@@ -26,7 +26,8 @@ class Layout extends React__default.PureComponent {
26
26
  footerColor = "red",
27
27
  noFooter,
28
28
  noHeader,
29
- noLogout
29
+ noLogout,
30
+ useRelativePathForMenu = false
30
31
  } = this.props;
31
32
  return /* @__PURE__ */ jsx(ThemeProvider, { theme: { ...theme }, children: /* @__PURE__ */ jsxs(PageWrapper, { children: [
32
33
  /* @__PURE__ */ jsx(GlobalStyle, {}),
@@ -38,7 +39,8 @@ class Layout extends React__default.PureComponent {
38
39
  loginHandler,
39
40
  signupHandler,
40
41
  siteTitle: title,
41
- noLogout
42
+ noLogout,
43
+ useRelativePathForMenu
42
44
  }
43
45
  ),
44
46
  /* @__PURE__ */ jsx(
@@ -61,7 +63,8 @@ Layout.propTypes = {
61
63
  signupHandler: PropTypes.func,
62
64
  progress: PropTypes.bool,
63
65
  footerColor: PropTypes.string,
64
- children: PropTypes.node.isRequired
66
+ children: PropTypes.node.isRequired,
67
+ useRelativePathForMenu: PropTypes.bool
65
68
  };
66
69
  ProgressStatusContext.Consumer;
67
70
  export {
@@ -49,7 +49,7 @@ const LoginModal = (props) => {
49
49
  ] }) }),
50
50
  /* @__PURE__ */ jsx(ModalInner, { modalBot: true, children: /* @__PURE__ */ jsxs(ModalLinkWrap, { children: [
51
51
  "Don't have an account yet? ",
52
- /* @__PURE__ */ jsx(ModalLink, { type: "button", to: "#", as: "button", onClick: onModalSwitch, children: "Sign up" })
52
+ /* @__PURE__ */ jsx(ModalLink, { type: "button", to: "#", as: "button", "data-cy": "login-modal-switch-to-signup", onClick: onModalSwitch, children: "Sign up" })
53
53
  ] }) })
54
54
  ] }),
55
55
  /* @__PURE__ */ jsx(Column, { part: 8, children: /* @__PURE__ */ jsx(ModalInner, { children: /* @__PURE__ */ jsx(
@@ -79,7 +79,8 @@ const LoginModal = (props) => {
79
79
  error: !!errors.email,
80
80
  touched: !!touched.email,
81
81
  autoComplete: "email",
82
- autoFocus: true
82
+ autoFocus: true,
83
+ "data-cy": "login-modal-email-input"
83
84
  }
84
85
  ),
85
86
  /* @__PURE__ */ jsx(FormError, { show: errors.email && touched.email, children: errors.email })
@@ -97,18 +98,20 @@ const LoginModal = (props) => {
97
98
  onBlur: handleBlur,
98
99
  error: !!errors.password,
99
100
  touched: !!touched.password,
100
- autoComplete: "current-password"
101
+ autoComplete: "current-password",
102
+ "data-cy": "login-modal-password-input"
101
103
  }
102
104
  ),
103
105
  /* @__PURE__ */ jsx(FormError, { show: errors.password && touched.password, children: errors.password })
104
106
  ] }) }),
105
- /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingBottom: true, noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(Button, { type: "submit", id: "login-submit-btn", fluid: true, disabled: submitDisabled, children: isActionLoading === "login" ? "Logging in" : "Login" }) }),
107
+ /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingBottom: true, noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(Button, { type: "submit", id: "login-submit-btn", "data-cy": "login-modal-submit", fluid: true, disabled: submitDisabled, children: isActionLoading === "login" ? "Logging in" : "Login" }) }),
106
108
  /* @__PURE__ */ jsx(ComponentWrapper, { paddingVeticalHalf: true, noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(FormError, { show: popupError.popup === "login", children: popupError.message }) }),
107
109
  /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingBottom: true, noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(
108
110
  TextLink,
109
111
  {
110
112
  type: "button",
111
113
  as: "button",
114
+ "data-cy": "login-modal-forgot-password",
112
115
  onClick: (...args) => {
113
116
  values.password = "";
114
117
  onForgotPassword(...args);
@@ -225,7 +225,11 @@ const ModalInner = styled.div.withConfig({
225
225
  `}
226
226
  `;
227
227
  const ModalClose = styled.i.attrs({
228
- className: "ion ion-md-close"
228
+ className: "ion ion-md-close",
229
+ role: "button",
230
+ tabIndex: 0,
231
+ "aria-label": "Close dialog",
232
+ "data-cy": "modal-close"
229
233
  })`
230
234
  z-index: 4;
231
235
  position: absolute;
@@ -275,7 +279,11 @@ const ModalClose = styled.i.attrs({
275
279
  const ModalBack = styled.i.withConfig({
276
280
  shouldForwardProp: (props) => !["hide"].includes(props)
277
281
  }).attrs({
278
- className: "ion ion-ios-arrow-back"
282
+ className: "ion ion-ios-arrow-back",
283
+ role: "button",
284
+ tabIndex: 0,
285
+ "aria-label": "Back",
286
+ "data-cy": "modal-back"
279
287
  })`
280
288
  z-index: 4;
281
289
  position: absolute;
@@ -94,6 +94,7 @@ const NewVentureModal = (props) => {
94
94
  {
95
95
  fluid: true,
96
96
  id: "private-investor-success-button",
97
+ "data-cy": "new-venture-modal-success-continue",
97
98
  onClick: () => {
98
99
  if (onSuccessMessageBtnClick) {
99
100
  onSuccessMessageBtnClick();
@@ -169,7 +170,8 @@ const NewVentureModal = (props) => {
169
170
  onChange: onChangeWithTouch,
170
171
  onBlur: handleBlur,
171
172
  error: !!errors.email,
172
- touched: !!touched.email
173
+ touched: !!touched.email,
174
+ "data-cy": "new-venture-modal-email-input"
173
175
  }
174
176
  ),
175
177
  /* @__PURE__ */ jsx(FormError, { show: touched.email && errors.email, children: errors.email }),
@@ -185,7 +187,8 @@ const NewVentureModal = (props) => {
185
187
  onChange: onChangeWithTouch,
186
188
  onBlur: handleBlur,
187
189
  error: !!errors.name,
188
- touched: !!touched.name
190
+ touched: !!touched.name,
191
+ "data-cy": "new-venture-modal-name-input"
189
192
  }
190
193
  ),
191
194
  /* @__PURE__ */ jsx(FormError, { show: touched.name && errors.name, children: errors.name })
@@ -200,7 +203,8 @@ const NewVentureModal = (props) => {
200
203
  checked: values.privateInvestorList,
201
204
  disabled: privateInvestorListDisabled,
202
205
  onChange: handleCheckboxChange,
203
- onBlur: handleBlur
206
+ onBlur: handleBlur,
207
+ "data-cy": "new-venture-modal-private-investor-checkbox"
204
208
  }
205
209
  ) }),
206
210
  /* @__PURE__ */ jsx(FormField, { style: { marginTop: "2rem", marginBottom: -5 }, children: /* @__PURE__ */ jsx(
@@ -212,7 +216,8 @@ const NewVentureModal = (props) => {
212
216
  checked: values.mailingList,
213
217
  disabled: mailingListDisabled,
214
218
  onChange: handleCheckboxChange,
215
- onBlur: handleBlur
219
+ onBlur: handleBlur,
220
+ "data-cy": "new-venture-modal-mailing-list-checkbox"
216
221
  }
217
222
  ) }),
218
223
  optionalCheckBox && /* @__PURE__ */ jsx(FormField, { style: { marginTop: "2rem", marginBottom: -5 }, children: /* @__PURE__ */ jsx(
@@ -224,7 +229,8 @@ const NewVentureModal = (props) => {
224
229
  value: values.optionalCheckBoxChecked,
225
230
  checked: values.optionalCheckBoxChecked,
226
231
  onChange: handleChange,
227
- onBlur: handleBlur
232
+ onBlur: handleBlur,
233
+ "data-cy": "new-venture-modal-optional-checkbox"
228
234
  }
229
235
  ) }),
230
236
  project.type === ProjectTypes.FUND && /* @__PURE__ */ jsx(FormField, { style: { marginTop: "2rem", marginBottom: -5 }, children: /* @__PURE__ */ jsx(
@@ -238,7 +244,16 @@ const NewVentureModal = (props) => {
238
244
  }
239
245
  ) })
240
246
  ] }) }),
241
- /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingBottom: true, noPaddingHorizontal: true, center: true, children: /* @__PURE__ */ jsx(Button, { type: "submit", id: "private-investor-subscribe-button", disabled: submitDisabled, children: "register" }) }),
247
+ /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingBottom: true, noPaddingHorizontal: true, center: true, children: /* @__PURE__ */ jsx(
248
+ Button,
249
+ {
250
+ type: "submit",
251
+ id: "private-investor-subscribe-button",
252
+ "data-cy": "new-venture-modal-register-submit",
253
+ disabled: submitDisabled,
254
+ children: "register"
255
+ }
256
+ ) }),
242
257
  /* @__PURE__ */ jsx(ComponentWrapper, { paddingVeticalHalf: true, noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(FormError, { show: popupError, children: popupError }) })
243
258
  ] });
244
259
  }
@@ -1,5 +1,5 @@
1
1
  import { jsx, Fragment, jsxs } from "react/jsx-runtime";
2
- import "react";
2
+ import React__default from "react";
3
3
  import { QRCodeSVG } from "qrcode.react";
4
4
  import { formatInTimeZone } from "date-fns-tz";
5
5
  import { Modal } from "./Modal.js";
@@ -53,14 +53,22 @@ const PaymentModal = ({
53
53
  " to the treasury wallet below."
54
54
  ] }),
55
55
  numberOfSecuritiesText = "Redeem securities",
56
- formatAmountInLink = true
56
+ formatAmountInLink = true,
57
+ transactionCostMessage,
58
+ paymentLink: paymentLinkProp,
59
+ showKYCWarningBox = true,
60
+ ...props
57
61
  }) => {
58
62
  const { projectData, tokenAmount, tokenSymbol, createdAt, tokenDecimals = 2, GAID, currencyType } = data;
59
63
  let newTokenAmount = tokenAmount;
60
64
  if (formatAmountInLink) {
61
65
  newTokenAmount = (tokenAmount * Math.pow(10, tokenDecimals - 8)).toFixed(8);
62
66
  }
63
- var paymentlink = `liquidnetwork:${projectData?.companyWallet}?amount=${newTokenAmount}&assetid=${projectData?.secondaryAssetId}`;
67
+ const defaultPaymentLink = `liquidnetwork:${projectData?.companyWallet}?amount=${newTokenAmount}&assetid=${projectData?.secondaryAssetId}`;
68
+ const resolvedPaymentLink = paymentLinkProp ?? defaultPaymentLink;
69
+ const txCostParagraphStyle = {
70
+ color: txTextInRed ? theme.cWarning : "inherit"
71
+ };
64
72
  const isKYCVerified = user?.kyc_status === "Accepted";
65
73
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Modal, { isOpen: isModalOpen, onClose: onModalClose, children: /* @__PURE__ */ jsxs(ModalInner, { children: [
66
74
  /* @__PURE__ */ jsx(Text, { children: /* @__PURE__ */ jsx("h3", { children: modalTitle }) }),
@@ -101,20 +109,12 @@ const PaymentModal = ({
101
109
  formatInTimeZone(new Date(secondsRemaining * 1e3), "UTC", "mm:ss"),
102
110
  " Waiting for payment..."
103
111
  ] }) }) }),
104
- !noCTA && /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(Button, { onClick: onCTAClick, children: CTAText }) })
112
+ !noCTA && /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(Button, { "data-cy": "payment-modal-cta", onClick: onCTAClick, children: CTAText }) })
105
113
  ] }),
106
114
  /* @__PURE__ */ jsx(Column, { part: 8, children: error ? error : /* @__PURE__ */ jsxs(Text, { children: [
107
115
  sendTokenTextRight,
108
- /* @__PURE__ */ jsx(
109
- "p",
110
- {
111
- style: {
112
- color: txTextInRed ? theme.cWarning : "inherit"
113
- },
114
- children: "We have transfered 0.00002 LBTC to cover your transaction costs."
115
- }
116
- ),
117
- isKYCVerified ? /* @__PURE__ */ jsxs(Fragment, { children: [
116
+ transactionCostMessage != null && transactionCostMessage !== false && (React__default.isValidElement(transactionCostMessage) ? transactionCostMessage : /* @__PURE__ */ jsx("p", { style: txCostParagraphStyle, children: transactionCostMessage })),
117
+ isKYCVerified || !showKYCWarningBox ? /* @__PURE__ */ jsxs(Fragment, { children: [
118
118
  /* @__PURE__ */ jsx(
119
119
  stdin_default,
120
120
  {
@@ -127,7 +127,7 @@ const PaymentModal = ({
127
127
  fontSize: 16
128
128
  }
129
129
  ),
130
- /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingHorizontal: true, noPaddingBottom: true, children: /* @__PURE__ */ jsx(QRCodeSVG, { value: paymentlink, size: 150 }) })
130
+ /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingHorizontal: true, noPaddingBottom: true, children: /* @__PURE__ */ jsx(QRCodeSVG, { value: resolvedPaymentLink, size: 150 }) })
131
131
  ] }) : /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
132
132
  /* @__PURE__ */ jsxs(WarningBox, { children: [
133
133
  /* @__PURE__ */ jsx(Icon, { icon: iconsMap.warning, size: 32, color: "white" }),
@@ -137,7 +137,7 @@ const PaymentModal = ({
137
137
  /* @__PURE__ */ jsx("a", { href: "mailto:compliance@stokr.io", style: { color: "inherit" }, children: "compliance@stokr.io" })
138
138
  ] })
139
139
  ] }),
140
- /* @__PURE__ */ jsx(BlurBox, { children: /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingHorizontal: true, noPaddingBottom: true, children: /* @__PURE__ */ jsx(QRCodeSVG, { value: paymentlink, size: 150 }) }) })
140
+ /* @__PURE__ */ jsx(BlurBox, { children: /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingHorizontal: true, noPaddingBottom: true, children: /* @__PURE__ */ jsx(QRCodeSVG, { value: resolvedPaymentLink, size: 150 }) }) })
141
141
  ] }),
142
142
  additionalInfoRight && additionalInfoRight
143
143
  ] }) })
@@ -45,7 +45,7 @@ const RegisterConfirmModal = ({
45
45
  "Email didn't arrive?",
46
46
  /* @__PURE__ */ jsx("br", {})
47
47
  ] }),
48
- /* @__PURE__ */ jsx(TextLink, { to: "", onClick: onResend, disabled: cooldown?.isDisabled, children: isActionLoading === "resend" ? "Resending email" : "Resend email" }),
48
+ /* @__PURE__ */ jsx(TextLink, { to: "", "data-cy": "register-confirm-modal-resend-email", onClick: onResend, disabled: cooldown?.isDisabled, children: isActionLoading === "resend" ? "Resending email" : "Resend email" }),
49
49
  /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingVertical: true, noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(FormError, { show: popupError.popup === "resend", children: popupError.message }) }),
50
50
  /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingVertical: true, noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(FormError, { show: popupSuccess.popup === "resend", children: popupSuccess.message }) }),
51
51
  /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingBottom: true, noPaddingHorizontal: true, children: cooldown?.isDisabled && /* @__PURE__ */ jsx(FormError, { show: cooldown?.isDisabled, children: `You can resend email in ${cooldown?.secondsRemaining} seconds` }) })
@@ -93,7 +93,17 @@ const RegisterModal = (props) => {
93
93
  /* @__PURE__ */ jsx(ModalInner, { modalBot: true, children: /* @__PURE__ */ jsxs(ModalLinkWrap, { children: [
94
94
  "Already have an account?",
95
95
  " ",
96
- /* @__PURE__ */ jsx(ModalLink, { to: "#", as: "button", type: "button", onClick: onModalSwitch, children: "Log in" })
96
+ /* @__PURE__ */ jsx(
97
+ ModalLink,
98
+ {
99
+ to: "#",
100
+ as: "button",
101
+ type: "button",
102
+ "data-cy": "register-modal-switch-to-login",
103
+ onClick: onModalSwitch,
104
+ children: "Log in"
105
+ }
106
+ )
97
107
  ] }) })
98
108
  ] }),
99
109
  /* @__PURE__ */ jsx(Column, { part: 8, children: /* @__PURE__ */ jsx(ModalInner, { children: /* @__PURE__ */ jsx(
@@ -148,7 +158,8 @@ const RegisterModal = (props) => {
148
158
  error: !!errors.email,
149
159
  touched: !!touched.email,
150
160
  readOnly: email ? true : false,
151
- autoComplete: "email"
161
+ autoComplete: "email",
162
+ "data-cy": "register-modal-email-input"
152
163
  }
153
164
  ),
154
165
  /* @__PURE__ */ jsx(FormError, { show: errors.email && touched.email, children: errors.email })
@@ -167,7 +178,8 @@ const RegisterModal = (props) => {
167
178
  error: !!errors.password,
168
179
  touched: !!touched.password,
169
180
  info: "For a stronger password, try a mix of lowercase, capitals, numbers and special characters.",
170
- autoComplete: "new-password"
181
+ autoComplete: "new-password",
182
+ "data-cy": "register-modal-password-input"
171
183
  }
172
184
  ),
173
185
  /* @__PURE__ */ jsx(FormError, { show: errors.password && touched.password, children: errors.password }),
@@ -187,7 +199,8 @@ const RegisterModal = (props) => {
187
199
  onChange: handleChange,
188
200
  onBlur: handleBlur,
189
201
  error: !!errors.newsletter,
190
- touched: !!touched.newsletter
202
+ touched: !!touched.newsletter,
203
+ "data-cy": "register-modal-newsletter-checkbox"
191
204
  }
192
205
  ),
193
206
  /* @__PURE__ */ jsx(FormError, { show: errors.newsletter && touched.newsletter, children: errors.newsletter })
@@ -198,12 +211,14 @@ const RegisterModal = (props) => {
198
211
  {
199
212
  id: privacyTermsCheckbox.title,
200
213
  name: "terms",
214
+ "data-cy": "register-modal-terms-checkbox",
201
215
  text: parse(privacyTermsCheckbox.agreementText, {
202
216
  replace: (domNode) => {
203
217
  if (domNode.type === "tag" && domNode.name === "u") {
204
218
  return /* @__PURE__ */ jsx(
205
219
  TermsStyled,
206
220
  {
221
+ "data-cy": "register-modal-privacy-terms-link",
207
222
  onClick: (e) => {
208
223
  e.stopPropagation();
209
224
  e.preventDefault();
@@ -227,7 +242,17 @@ const RegisterModal = (props) => {
227
242
  /* @__PURE__ */ jsx(FormError, { show: errors.terms && touched.terms, withMarginLeft: true, children: errors.terms })
228
243
  ] })
229
244
  ] }),
230
- /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingBottom: true, noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(Button, { type: "submit", fluid: true, disabled: submitDisabled, id: "signup-button", children: isActionLoading === "signUp" ? "Creating account" : "Create account" }) }),
245
+ /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingBottom: true, noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(
246
+ Button,
247
+ {
248
+ type: "submit",
249
+ fluid: true,
250
+ disabled: submitDisabled,
251
+ id: "signup-button",
252
+ "data-cy": "register-modal-submit",
253
+ children: isActionLoading === "signUp" ? "Creating account" : "Create account"
254
+ }
255
+ ) }),
231
256
  /* @__PURE__ */ jsx(ComponentWrapper, { paddingVeticalHalf: true, noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(FormError, { show: popupError.popup === "register", children: popupError.message }) })
232
257
  ] });
233
258
  }
@@ -29,7 +29,7 @@ const ResetConfirmModal = ({ isModalOpen, onModalClose, onModalSwitch }) => /* @
29
29
  ] }),
30
30
  /* @__PURE__ */ jsx("br", {}),
31
31
  /* @__PURE__ */ jsx("br", {}),
32
- /* @__PURE__ */ jsx(Button, { onClick: onModalSwitch, children: "Login" })
32
+ /* @__PURE__ */ jsx(Button, { "data-cy": "reset-confirm-modal-login", onClick: onModalSwitch, children: "Login" })
33
33
  ] }) }) }) }),
34
34
  /* @__PURE__ */ jsx(RedBar, {})
35
35
  ] });
@@ -40,7 +40,7 @@ const ResetPasswordModal = ({
40
40
  ] }) }),
41
41
  /* @__PURE__ */ jsx(ModalInner, { modalBot: true, children: /* @__PURE__ */ jsxs(ModalLinkWrap, { children: [
42
42
  "Remember your password? ",
43
- /* @__PURE__ */ jsx(ModalLink, { to: "#", onClick: onModalSwitch, children: "Log in" })
43
+ /* @__PURE__ */ jsx(ModalLink, { "data-cy": "reset-password-modal-switch-to-login", to: "#", onClick: onModalSwitch, children: "Log in" })
44
44
  ] }) })
45
45
  ] }),
46
46
  /* @__PURE__ */ jsx(Column, { part: 8, children: /* @__PURE__ */ jsx(ModalInner, { children: /* @__PURE__ */ jsx(
@@ -75,7 +75,8 @@ const ResetPasswordModal = ({
75
75
  error: !!errors.password,
76
76
  touched: !!touched.password,
77
77
  info: "For a stronger password, try a mix of lowercase, capitals, numbers and special characters.",
78
- autoComplete: "new-password"
78
+ autoComplete: "new-password",
79
+ "data-cy": "reset-password-modal-password-input"
79
80
  }
80
81
  ),
81
82
  /* @__PURE__ */ jsx(FormError, { show: errors.password && touched.password, children: errors.password }),
@@ -101,12 +102,23 @@ const ResetPasswordModal = ({
101
102
  onBlur: handleBlur,
102
103
  error: !!errors.confirmPassword,
103
104
  touched: !!touched.confirmPassword,
104
- autoComplete: "new-password"
105
+ autoComplete: "new-password",
106
+ "data-cy": "reset-password-modal-confirm-password-input"
105
107
  }
106
108
  ),
107
109
  /* @__PURE__ */ jsx(FormError, { show: errors.confirmPassword && touched.confirmPassword, children: errors.confirmPassword })
108
110
  ] }) }),
109
- /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingBottom: true, noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(Button, { type: "submit", id: "reset-password-submit-btn", fluid: true, disabled: submitDisabled, children: isActionLoading === "resetPassword" ? "Resetting" : "Reset" }) }),
111
+ /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingBottom: true, noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(
112
+ Button,
113
+ {
114
+ type: "submit",
115
+ id: "reset-password-submit-btn",
116
+ "data-cy": "reset-password-modal-submit",
117
+ fluid: true,
118
+ disabled: submitDisabled,
119
+ children: isActionLoading === "resetPassword" ? "Resetting" : "Reset"
120
+ }
121
+ ) }),
110
122
  /* @__PURE__ */ jsx(ComponentWrapper, { paddingVeticalHalf: true, noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(
111
123
  FormError,
112
124
  {
@@ -17,6 +17,7 @@ const StepControllerProgress = ({
17
17
  return /* @__PURE__ */ jsx(Container, { children: /* @__PURE__ */ jsx(Wrap, { children: /* @__PURE__ */ jsx(Items, { children: stepsProgressList.map((item, key) => /* @__PURE__ */ jsx(
18
18
  Item,
19
19
  {
20
+ "data-cy": item.dataCy ?? `step-progress-${item.id}`,
20
21
  isDone: doneStepsIndexes.includes(key),
21
22
  isActive: key === activeStepIndex,
22
23
  onClick: () => handleItemClick(item, key)
@@ -13,7 +13,8 @@ const Switch = (props) => {
13
13
  value1Color,
14
14
  value2Color,
15
15
  hideValues = false,
16
- indicatorStyle
16
+ indicatorStyle,
17
+ dataCy
17
18
  } = props;
18
19
  const [value, setValue] = useState();
19
20
  useEffect(() => {
@@ -29,7 +30,7 @@ const Switch = (props) => {
29
30
  }, 1e3);
30
31
  }
31
32
  };
32
- return /* @__PURE__ */ jsxs(Container, { mobile, children: [
33
+ return /* @__PURE__ */ jsxs(Container, { mobile, "data-cy": dataCy, children: [
33
34
  !hideValues && /* @__PURE__ */ jsx(Value, { active: value === value1, onClick: () => setValue(value1), dark, children: value1 }),
34
35
  /* @__PURE__ */ jsx(
35
36
  Indicator,
@@ -54,7 +55,8 @@ Switch.propTypes = {
54
55
  mobile: PropTypes.bool,
55
56
  dark: PropTypes.bool,
56
57
  hideValues: PropTypes.bool,
57
- indicatorStyle: PropTypes.object
58
+ indicatorStyle: PropTypes.object,
59
+ dataCy: PropTypes.string
58
60
  };
59
61
  var stdin_default = Switch;
60
62
  export {
@@ -8,6 +8,7 @@ import setRedirectCookie from "../../utils/set-redirect-cookie.js";
8
8
  import { AuthProvider } from "../../context/AuthContext.js";
9
9
  import { ToDoModal } from "./ToDoList.js";
10
10
  import "react-router-dom";
11
+ import "mixpanel-browser";
11
12
  import "../Text/Text.styles.js";
12
13
  import "yup";
13
14
  import "formik";
@@ -32,6 +32,8 @@ import { emailRegex } from "../../constants/globalVariables.js";
32
32
  const renderSuccessModal = (continueUrl) => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
33
33
  stdin_default$1,
34
34
  {
35
+ continueButtonId: "verify-email-success-continue-btn",
36
+ continueButtonDataCy: "verify-email-success-continue",
35
37
  onClick: () => {
36
38
  window.open(continueUrl, "_self");
37
39
  },
@@ -87,12 +89,22 @@ const RenderErrorModal = (props) => {
87
89
  onChange: handleChange,
88
90
  onBlur: handleBlur,
89
91
  error: !!errors.email,
90
- touched: !!touched.email
92
+ touched: !!touched.email,
93
+ "data-cy": "verify-email-modal-email-input"
91
94
  }
92
95
  ),
93
96
  /* @__PURE__ */ jsx(FormError, { show: errors.email && touched.email, children: errors.email })
94
97
  ] }) }),
95
- /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingBottom: true, noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(Button, { type: "submit", id: "verify-email-submit-btn", disabled: submitDisabled, children: isActionLoading === "resend" ? "Resending email" : "Resend email" }) }),
98
+ /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingBottom: true, noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(
99
+ Button,
100
+ {
101
+ type: "submit",
102
+ id: "verify-email-submit-btn",
103
+ "data-cy": "verify-email-modal-resend-submit",
104
+ disabled: submitDisabled,
105
+ children: isActionLoading === "resend" ? "Resending email" : "Resend email"
106
+ }
107
+ ) }),
96
108
  /* @__PURE__ */ jsx(ComponentWrapper, { paddingVeticalHalf: true, noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(FormError, { show: popupError.popup === "resend", children: popupError.message }) }),
97
109
  isDisabled && /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingVertical: true, noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(FormError, { show: isDisabled, children: `You can try again in ${secondsRemaining} seconds` }) })
98
110
  ] });
@@ -40,6 +40,7 @@ import fetchDataPublic from "../../api/fetchDataPublic.js";
40
40
  import { withRouter } from "../../utils/withRouter.js";
41
41
  import { checkActionCode } from "firebase/auth";
42
42
  import { auth } from "../../firebase-config.js";
43
+ import { track } from "../../analytics/index.js";
43
44
  const Outer = styled.div.withConfig({
44
45
  shouldForwardProp: (props) => !["fixed"].includes(props)
45
46
  })`
@@ -454,6 +455,7 @@ const _HeaderHoClass = class _HeaderHoClass extends Component {
454
455
  listName: "newsletter"
455
456
  });
456
457
  }
458
+ track("signup_account_created", { newsletter_opt_in: !!_userInfo.newsletter });
457
459
  this.setUserInfo(_userInfo);
458
460
  this.switchOpenModal("signUp", "confirm");
459
461
  this.setIsActionLoading(void 0);
@@ -1,5 +1,6 @@
1
1
  import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
2
  import "react";
3
+ import { track } from "../../analytics/index.js";
3
4
  import { Text } from "../Text/Text.styles.js";
4
5
  import { useNavigate } from "react-router-dom";
5
6
  import { ComponentWrapper } from "../ComponentWrapper/ComponentWrapper.styles.js";
@@ -10,12 +11,32 @@ const noop = () => {
10
11
  const RegisterTaxIdComplete = ({ showBackButton, onClick = noop }) => {
11
12
  let navigate = useNavigate();
12
13
  return /* @__PURE__ */ jsxs(Fragment, { children: [
13
- showBackButton && /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingVertical: true, children: /* @__PURE__ */ jsx(TextButton, { onClick: () => navigate("/verify-identity"), children: "Back to verify identity" }) }),
14
+ showBackButton && /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingVertical: true, children: /* @__PURE__ */ jsx(
15
+ TextButton,
16
+ {
17
+ "data-cy": "tax-id-complete-back-button",
18
+ onClick: () => {
19
+ track("tax_id_back_clicked", { surface: "tax_id_complete" });
20
+ navigate("/verify-identity");
21
+ },
22
+ children: "Back to verify identity"
23
+ }
24
+ ) }),
14
25
  /* @__PURE__ */ jsx(ComponentWrapper, { children: /* @__PURE__ */ jsxs(Text, { children: [
15
26
  /* @__PURE__ */ jsx("h1", { children: "Your Tax Id has been submitted" }),
16
27
  /* @__PURE__ */ jsx("p", { children: "You have successfully submitted your Tax ID information. You will be ready to invest once you have completed all required steps on your checklist. Please continue!" })
17
28
  ] }) }),
18
- /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingTop: true, children: /* @__PURE__ */ jsx(Button, { onClick, children: "Continue" }) })
29
+ /* @__PURE__ */ jsx(ComponentWrapper, { noPaddingTop: true, children: /* @__PURE__ */ jsx(
30
+ Button,
31
+ {
32
+ "data-cy": "tax-id-complete-continue-button",
33
+ onClick: () => {
34
+ track("tax_id_complete_continue_clicked");
35
+ onClick();
36
+ },
37
+ children: "Continue"
38
+ }
39
+ ) })
19
40
  ] });
20
41
  };
21
42
  var stdin_default = RegisterTaxIdComplete;
@@ -1,5 +1,6 @@
1
1
  import { jsx, Fragment } from "react/jsx-runtime";
2
2
  import { useState, useEffect, useRef } from "react";
3
+ import { track } from "../../analytics/index.js";
3
4
  import { Modal } from "../Modal/Modal.js";
4
5
  import stdin_default$3 from "./register-taxid.js";
5
6
  import stdin_default$1 from "../ComponentScroll/ComponentScroll.js";
@@ -20,13 +21,22 @@ const RegisterTaxIdFlow = ({
20
21
  onComplete();
21
22
  }
22
23
  }, [showComplete]);
24
+ useEffect(() => {
25
+ if (showFlow) {
26
+ track("tax_id_modal_opened");
27
+ }
28
+ }, [showFlow]);
29
+ const handleClose = () => {
30
+ track("tax_id_modal_closed", { flow_step: showComplete ? "complete" : "form" });
31
+ setShowFlow(false);
32
+ };
23
33
  const scrollRef = useRef();
24
34
  const handleScroll = (values, ref) => {
25
35
  if (ref) {
26
36
  scrollRef.current = ref;
27
37
  }
28
38
  };
29
- return /* @__PURE__ */ jsx(Modal, { fullscreen: true, isOpen: showFlow, onClose: () => setShowFlow(false), children: /* @__PURE__ */ jsx(ModalInner, { noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(stdin_default$1, { handleScroll, fullHeight: true, children: showComplete ? /* @__PURE__ */ jsx(
39
+ return /* @__PURE__ */ jsx(Modal, { fullscreen: true, isOpen: showFlow, onClose: handleClose, children: /* @__PURE__ */ jsx(ModalInner, { noPaddingHorizontal: true, children: /* @__PURE__ */ jsx(stdin_default$1, { handleScroll, fullHeight: true, children: showComplete ? /* @__PURE__ */ jsx(
30
40
  stdin_default$2,
31
41
  {
32
42
  showBackButton,