contentoh-components-library 21.0.26 → 21.0.29

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 (51) hide show
  1. package/dist/components/atoms/Loading/Loading.stories.js +28 -0
  2. package/dist/components/atoms/Loading/index.js +27 -0
  3. package/dist/components/atoms/Loading/styles.js +18 -0
  4. package/dist/components/molecules/EmailResetPasswordLogin/EmailResetPasswordLogin.stories.js +28 -0
  5. package/dist/components/molecules/EmailResetPasswordLogin/index.js +155 -0
  6. package/dist/components/molecules/EmailResetPasswordLogin/styles.js +20 -0
  7. package/dist/components/molecules/RegistrationFirstStep/RegistrationFirstStep.stories.js +28 -0
  8. package/dist/components/molecules/RegistrationFirstStep/index.js +336 -0
  9. package/dist/components/molecules/RegistrationFirstStep/styles.js +20 -0
  10. package/dist/components/molecules/RegistrationSecondStep/RegistrationSecondStep.stories.js +28 -0
  11. package/dist/components/molecules/RegistrationSecondStep/index.js +156 -0
  12. package/dist/components/molecules/RegistrationSecondStep/styles.js +20 -0
  13. package/dist/components/molecules/RegistrationThirdStep/RegistrationThirdStep.stories.js +28 -0
  14. package/dist/components/molecules/RegistrationThirdStep/index.js +161 -0
  15. package/dist/components/molecules/RegistrationThirdStep/styles.js +20 -0
  16. package/dist/components/molecules/SignInLogin/index.js +217 -67
  17. package/dist/components/molecules/SignInLogin/styles.js +1 -1
  18. package/dist/components/molecules/VerificationCodeResetPasswordLogin/VerificationCodeResetPasswordLogin.stories.js +28 -0
  19. package/dist/components/molecules/VerificationCodeResetPasswordLogin/index.js +104 -0
  20. package/dist/components/molecules/VerificationCodeResetPasswordLogin/styles.js +20 -0
  21. package/dist/components/molecules/VerificationCodeResetPasswordLogin/utils.js +69 -0
  22. package/dist/components/organisms/ChangePassword/ChangePassword.stories.js +28 -0
  23. package/dist/components/organisms/ChangePassword/index.js +113 -0
  24. package/dist/components/organisms/ChangePassword/styles.js +18 -0
  25. package/dist/index.js +138 -47
  26. package/package.json +5 -2
  27. package/src/components/atoms/Loading/Loading.stories.js +10 -0
  28. package/src/components/atoms/Loading/index.js +13 -0
  29. package/src/components/atoms/Loading/styles.js +57 -0
  30. package/src/components/molecules/EmailResetPasswordLogin/EmailResetPasswordLogin.stories.js +11 -0
  31. package/src/components/molecules/EmailResetPasswordLogin/index.js +86 -0
  32. package/src/components/molecules/EmailResetPasswordLogin/styles.js +23 -0
  33. package/src/components/molecules/RegistrationFirstStep/RegistrationFirstStep.stories.js +11 -0
  34. package/src/components/molecules/RegistrationFirstStep/index.js +242 -0
  35. package/src/components/molecules/RegistrationFirstStep/styles.js +81 -0
  36. package/src/components/molecules/RegistrationSecondStep/RegistrationSecondStep.stories.js +11 -0
  37. package/src/components/molecules/RegistrationSecondStep/index.js +97 -0
  38. package/src/components/molecules/RegistrationSecondStep/styles.js +59 -0
  39. package/src/components/molecules/RegistrationThirdStep/RegistrationThirdStep.stories.js +11 -0
  40. package/src/components/molecules/RegistrationThirdStep/index.js +109 -0
  41. package/src/components/molecules/RegistrationThirdStep/styles.js +44 -0
  42. package/src/components/molecules/SignInLogin/index.js +181 -55
  43. package/src/components/molecules/SignInLogin/styles.js +1 -0
  44. package/src/components/molecules/VerificationCodeResetPasswordLogin/VerificationCodeResetPasswordLogin.stories.js +11 -0
  45. package/src/components/molecules/VerificationCodeResetPasswordLogin/index.js +78 -0
  46. package/src/components/molecules/VerificationCodeResetPasswordLogin/styles.js +49 -0
  47. package/src/components/molecules/VerificationCodeResetPasswordLogin/utils.js +56 -0
  48. package/src/components/organisms/ChangePassword/ChangePassword.stories.js +11 -0
  49. package/src/components/organisms/ChangePassword/index.js +63 -0
  50. package/src/components/organisms/ChangePassword/styles.js +16 -0
  51. package/src/index.js +7 -0
@@ -0,0 +1,109 @@
1
+ import { Container } from "./styles";
2
+ import { GradientPanel } from "../../atoms/GradientPanel";
3
+ import { useState } from "react";
4
+ import { LogoImage } from "../../atoms/LogoImage";
5
+ import { ScreenHeader } from "../../atoms/ScreenHeader";
6
+ import { GlobalColors, FontFamily } from "../../../global-files/variables";
7
+ import { TagAndInput } from "../../molecules/TagAndInput";
8
+ import { Button } from "../../atoms/GeneralButton";
9
+
10
+ export const RegistrationThirdStep = () => {
11
+ const [emptyCommercialName, setEmptyCommercialName] = useState(false);
12
+ const [emptyBussinesName, setEmptyBussinesName] = useState(false);
13
+ const [emptyRFC, setEmptyRFC] = useState(false);
14
+ const [emptyFiscalAddress, setEmptyFiscalAddress] = useState(false);
15
+ const validate = async (e) => {
16
+ e.preventDefault();
17
+ const commercialName = document.querySelector("#commercialNameInput").value;
18
+ const bussinesName = document.querySelector("#bussinesNameInput").value;
19
+ const RFC = document.querySelector("#rfcInput").value;
20
+ const FiscalAddress = document.querySelector("#fiscalAddressInput").value;
21
+ commercialName === ""
22
+ ? setEmptyCommercialName(true)
23
+ : setEmptyCommercialName(false);
24
+ bussinesName === ""
25
+ ? setEmptyBussinesName(true)
26
+ : setEmptyBussinesName(false);
27
+ RFC === "" ? setEmptyRFC(true) : setEmptyRFC(false);
28
+ FiscalAddress === ""
29
+ ? setEmptyFiscalAddress(true)
30
+ : setEmptyFiscalAddress(false);
31
+ };
32
+ const loginRight = [
33
+ <LogoImage key="1" />,
34
+ <div className="credenciales" key={"2"}>
35
+ <ScreenHeader
36
+ fontFamily={FontFamily.AvenirNext}
37
+ color={GlobalColors.s5}
38
+ text={"Ingresa tus credenciales"}
39
+ />
40
+ </div>,
41
+ <div className="user" key="3">
42
+ <TagAndInput
43
+ inputType={"text"}
44
+ inputId={"commercialNameInput"}
45
+ label={"Nombre comercial"}
46
+ inputPlaceHolder={"Nombre comercial"}
47
+ />
48
+ {emptyCommercialName && (
49
+ <label>Ingrese el nombre comercial de la empresa</label>
50
+ )}
51
+ <TagAndInput
52
+ inputType={"text"}
53
+ inputId={"bussinesNameInput"}
54
+ label={"Razón social"}
55
+ inputPlaceHolder={"Razón social"}
56
+ />
57
+ {emptyBussinesName && (
58
+ <label>Ingrese la razón social de la empresa</label>
59
+ )}
60
+ <TagAndInput
61
+ inputType={"text"}
62
+ inputId={"rfcInput"}
63
+ label={"RFC"}
64
+ inputPlaceHolder={"RFC"}
65
+ />
66
+ {emptyRFC && <label>El RFC es requerido</label>}
67
+ <TagAndInput
68
+ inputType={"text"}
69
+ inputId={"fiscalAddressInput"}
70
+ label={"Direccion fiscal"}
71
+ inputPlaceHolder={"Dirección fiscal"}
72
+ />
73
+ {emptyFiscalAddress && (
74
+ <label>Ingrese la direccion fiscal de la empresa</label>
75
+ )}
76
+ </div>,
77
+ <div className="button-end" key="4">
78
+ <Button
79
+ buttonType={"general-default-button"}
80
+ label={"Enviar"}
81
+ onClick={(e) => validate(e)}
82
+ />
83
+ </div>,
84
+ <div className="progress-bar" key="5">
85
+ <div className="progress-bar-step-check"></div>
86
+ <div className="progress-bar-registration"></div>
87
+ </div>,
88
+ <ScreenHeader
89
+ text={"Paso 3"}
90
+ headerType={"date-header"}
91
+ color={GlobalColors.s4}
92
+ key="6"
93
+ />,
94
+ <div className="new-login" key="7">
95
+ <p className="pre-registro">
96
+ ¿Ya tienes una cuenta?<span> Inicia Sesión</span>
97
+ </p>
98
+ </div>,
99
+ ];
100
+ return (
101
+ <Container>
102
+ <GradientPanel
103
+ componentsArray={loginRight}
104
+ panelType={"home-login"}
105
+ panelColor={GlobalColors.white}
106
+ />
107
+ </Container>
108
+ );
109
+ };
@@ -0,0 +1,44 @@
1
+ import styled from "styled-components";
2
+ import { FontFamily, GlobalColors } from "../../../global-files/variables";
3
+
4
+ export const Container = styled.div`
5
+ display: flex;
6
+ width: 50%;
7
+ height: 100%;
8
+ .user {
9
+ .input-name-header {
10
+ margin-top: 10px;
11
+ }
12
+ }
13
+ .button-end {
14
+ text-align: end;
15
+ .general-default-button {
16
+ width: 160px;
17
+ }
18
+ & + * {
19
+ margin-top: 10px;
20
+ }
21
+ }
22
+ .progress-bar {
23
+ width: 100%;
24
+ height: 8px;
25
+ display: flex;
26
+ justify-content: space-between;
27
+ .progress-bar-step-check {
28
+ width: 66.66%;
29
+ background-color: ${GlobalColors.exported};
30
+ }
31
+ .progress-bar-registration {
32
+ background-color: rgb(196, 196, 196);
33
+ width: 33.33%;
34
+ }
35
+ }
36
+ .date-header {
37
+ margin-left: 66.66%;
38
+ .new-login {
39
+ & + * {
40
+ margin-top: 20px;
41
+ }
42
+ }
43
+ }
44
+ `;
@@ -5,75 +5,201 @@ import { Button } from "../../atoms/GeneralButton/index";
5
5
  import { CheckBox } from "../../atoms/CheckBox/index";
6
6
  import { TagAndInput } from "../TagAndInput";
7
7
  import { FontFamily, GlobalColors } from "../../../global-files/variables";
8
- import { useState } from "react";
8
+ import { useState, useEffect } from "react";
9
+ import { Loading } from "../../atoms/Loading";
10
+ import { Redirect } from "react-router-dom";
11
+ import { Auth } from "aws-amplify";
12
+ import axios from "axios";
9
13
 
10
- export const SignInLogin = () => {
14
+ export const SignInLogin = (props) => {
11
15
  const [emptyEmail, setEmptyEmail] = useState(false);
12
16
  const [invalidEmail, setInvalidEmail] = useState(false);
13
17
  const [emptyPassword, setEmptyPassword] = useState(false);
18
+ const [showErrors, setShowErrors] = useState(true);
19
+ const [signInError, setSignInError] = useState("");
20
+ const [loading, setLoading] = useState(false);
21
+ const [upgradePlanRedirect, setUpgradePlanRedirect] = useState(false);
14
22
  const validate = async (e) => {
23
+ setSignInError("");
24
+ setShowErrors(true);
15
25
  e.preventDefault();
26
+ let valid = true;
16
27
  const email = document.querySelector("#emailInput").value;
17
28
  const password = document.querySelector("#passwordInput").value;
18
- email === "" ? setEmptyEmail(true) : setEmptyEmail(false);
19
- password === "" ? setEmptyPassword(true) : setEmptyPassword(false);
20
29
  !/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(
21
30
  email
22
31
  )
23
32
  ? setInvalidEmail(true)
24
33
  : setInvalidEmail(false);
34
+ if (email === "") {
35
+ valid = false;
36
+ setEmptyEmail(true);
37
+ } else {
38
+ setEmptyEmail(false);
39
+ }
40
+ if (password === "") {
41
+ valid = false;
42
+ setEmptyPassword(true);
43
+ } else {
44
+ setEmptyPassword(false);
45
+ }
46
+ if (valid) {
47
+ try {
48
+ setLoading(true);
49
+ const session = await props.Auth.signIn(email, password);
50
+ if (session.challengeName === "NEW_PASSWORD_REQUIRED") {
51
+ props.setUser(session);
52
+ props.setPaso(8);
53
+ } else {
54
+ const userGroup =
55
+ session.signInUserSession.accessToken.payload["cognito:groups"];
56
+ const response = await axios.get(
57
+ process.env.REACT_APP_USER_ENDPOINT,
58
+ {
59
+ headers: {
60
+ Authorization: session.signInUserSession.idToken.jwtToken,
61
+ },
62
+ }
63
+ );
64
+ const userGroupValue =
65
+ typeof userGroup === "string" ? userGroup : userGroup[0];
66
+ if (userGroupValue === "usuario_contentoh") {
67
+ sessionStorage.setItem("auth", true);
68
+ sessionStorage.setItem(
69
+ "jwt",
70
+ session.signInUserSession.idToken.jwtToken
71
+ );
72
+ const user = JSON.parse(response.data.body).data[0];
73
+ const company = JSON.parse(response.data.body).data[1];
74
+ caches.keys().then((names) => {
75
+ names.forEach((name) => {
76
+ caches.delete(name);
77
+ });
78
+ });
79
+ user.src = `https://${
80
+ process.env.REACT_APP_IMAGES_PROFILE_BUCKET
81
+ }.s3.amazonaws.com/id-${user.id_user}/${
82
+ user.id_user
83
+ }.png?${new Date().getTime()}`;
84
+ sessionStorage.setItem("user", JSON.stringify(user));
85
+ sessionStorage.setItem("company", JSON.stringify(company));
86
+ setUpgradePlanRedirect(true);
87
+ } else {
88
+ setSignInError("NotAuthorizedException");
89
+ setLoading(false);
90
+ }
91
+ }
92
+ } catch (error) {
93
+ console.log(error);
94
+ setLoading(false);
95
+ if (error.code === "NotAuthorizedException") {
96
+ setSignInError("NotAuthorizedException");
97
+ } else if (error.code === "UserNotConfirmedException") {
98
+ sessionStorage.setItem(
99
+ "email",
100
+ JSON.stringify(
101
+ document.querySelector("#usernameInput").value.trim()
102
+ )
103
+ );
104
+ sessionStorage.setItem("email", JSON.stringify(email));
105
+ props.setPaso(5);
106
+ } else {
107
+ setSignInError("Error");
108
+ }
109
+ }
110
+ }
25
111
  };
26
- return (
27
- <Container className={"home-login"}>
28
- <div className="main-container">
29
- <LogoImage />
30
- <div className="credenciales">
31
- <ScreenHeader
32
- fontFamily={FontFamily.AvenirNext}
33
- color={GlobalColors.s5}
34
- text={"Ingresa tus credenciales"}
35
- />
112
+ useEffect(() => {
113
+ sessionStorage.getItem("resetPasswordProcess") &&
114
+ sessionStorage.removeItem("resetPasswordProcess");
115
+ }, []);
116
+ return loading ? (
117
+ <Loading />
118
+ ) : (
119
+ <>
120
+ <Container className={"home-login"}>
121
+ <div className="main-container">
122
+ <LogoImage />
123
+ <div className="credenciales">
124
+ <ScreenHeader
125
+ fontFamily={FontFamily.AvenirNext}
126
+ color={GlobalColors.s5}
127
+ text={"Ingresa tus credenciales"}
128
+ />
129
+ </div>
130
+ <div className="user">
131
+ <TagAndInput
132
+ inputType={"text"}
133
+ label={"Nombre de usuario"}
134
+ inputPlaceHolder={"username@contentoh.com"}
135
+ inputId={"emailInput"}
136
+ />
137
+ </div>
138
+ {showErrors && emptyEmail && <label>Ingrese su correo</label>}
139
+ {invalidEmail && !emptyEmail && (
140
+ <label>Ingrese un correo válido</label>
141
+ )}
142
+ <div className="password">
143
+ <TagAndInput
144
+ inputType={"password"}
145
+ label={"Contraseña"}
146
+ inputPlaceHolder={"Escribe tu contraseña"}
147
+ inputId={"passwordInput"}
148
+ />
149
+ </div>
150
+ {showErrors && emptyPassword && <label>Ingrese su contraseña</label>}
151
+ <div className="select">
152
+ <CheckBox
153
+ label={"Mantener sesión activada"}
154
+ id={"chk-default"}
155
+ className="active-left"
156
+ />
157
+ <p onClick={() => props.setPaso(10)} className="active-right">
158
+ Olvide mi contraseña
159
+ </p>
160
+ </div>
161
+ {showErrors && signInError === "NotAuthorizedException" && (
162
+ <label>Correo o contraseña incorrectos</label>
163
+ )}
164
+ {showErrors && signInError === "Error" && (
165
+ <label>Ha habido un problema al iniciar sesión</label>
166
+ )}
167
+ <div className="button-right">
168
+ <Button
169
+ buttonType={"general-default-button"}
170
+ label={"Iniciar sesión"}
171
+ onClick={(e) => validate(e)}
172
+ />
173
+ </div>
174
+ <div className="new-login">
175
+ <p
176
+ className="pre-registro"
177
+ onClick={() => {
178
+ props.setPaso(1);
179
+ sessionStorage.setItem(
180
+ "nuevoRegistro",
181
+ JSON.stringify({
182
+ name: "",
183
+ lastName: "",
184
+ email: "",
185
+ position: "",
186
+ country: "",
187
+ phone: "",
188
+ commercialName: "",
189
+ companyName: "",
190
+ rfc: "",
191
+ adress: "",
192
+ })
193
+ );
194
+ sessionStorage.setItem("countryCode", JSON.stringify("+52"));
195
+ }}
196
+ >
197
+ ¿Aún no tienes cuenta?<span> Regístrate</span>
198
+ </p>
199
+ </div>
36
200
  </div>
37
- <div className="user">
38
- <TagAndInput
39
- inputType={"text"}
40
- label={"Nombre de usuario"}
41
- inputPlaceHolder={"username@contentoh.com"}
42
- inputId={"emailInput"}
43
- />
44
- </div>
45
- {emptyEmail && <label>Ingrese su correo</label>}
46
- {invalidEmail && !emptyEmail && <label>Ingrese un correo válido</label>}
47
- <div className="password">
48
- <TagAndInput
49
- inputType={"text"}
50
- label={"Contraseña"}
51
- inputPlaceHolder={"Escribe tu contraseña"}
52
- inputId={"passwordInput"}
53
- />
54
- </div>
55
- {emptyPassword && <label>Ingrese su contraseña</label>}
56
- <div className="select">
57
- <CheckBox
58
- label={"Mantener sesión activada"}
59
- id={"chk-default"}
60
- className="active-left"
61
- />
62
- <p className="active-right">Olvide mi contraseña</p>
63
- </div>
64
- <div className="button-right">
65
- <Button
66
- buttonType={"general-default-button"}
67
- label={"Iniciar sesión"}
68
- onClick={(e) => validate(e)}
69
- />
70
- </div>
71
- <div className="new-login">
72
- <p className="pre-registro">
73
- ¿Aún no tienes cuenta?<span> Regístrate</span>
74
- </p>
75
- </div>
76
- </div>
77
- </Container>
201
+ </Container>
202
+ {upgradePlanRedirect && <Redirect to={{ pathname: "/dashboard" }} />}
203
+ </>
78
204
  );
79
205
  };
@@ -5,6 +5,7 @@ export const Container = styled.div`
5
5
  background: "white";
6
6
  display: flex;
7
7
  height: 100%;
8
+ width: 50%;
8
9
  justify-content: center;
9
10
  align-items: center;
10
11
  label {
@@ -0,0 +1,11 @@
1
+ import { VerificationCodeResetPasswordLogin } from "./index";
2
+
3
+ export default {
4
+ title: "Components/molecules/VerificationCodeResetPasswordLogin",
5
+ component: VerificationCodeResetPasswordLogin,
6
+ };
7
+ const Template = (args) => <VerificationCodeResetPasswordLogin {...args} />;
8
+
9
+ export const VerificationCodeResetPasswordLoginDefault = Template.bind({});
10
+
11
+ VerificationCodeResetPasswordLoginDefault.args = {};
@@ -0,0 +1,78 @@
1
+ import { Container } from "./styles";
2
+ import { GradientPanel } from "../../atoms/GradientPanel";
3
+ import { useEffect, useState } from "react";
4
+ import { LogoImage } from "../../atoms/LogoImage";
5
+ import { ScreenHeader } from "../../atoms/ScreenHeader";
6
+ import { GlobalColors, FontFamily } from "../../../global-files/variables";
7
+ import { GeneralInput } from "../../atoms/GeneralInput";
8
+ import { Button } from "../../atoms/GeneralButton";
9
+ import { validateInput, validate } from "./utils";
10
+
11
+ export const VerificationCodeResetPasswordLogin = () => {
12
+ const [emptyVerificationCode, setEmptyVerificationCode] = useState(false);
13
+ const [inputCodeVerificationAll, setInputCodeVerificationAll] = useState();
14
+ const inputPositions = [1, 2, 3, 4, 5, 6];
15
+
16
+ useEffect(() => {
17
+ setInputCodeVerificationAll(
18
+ document.querySelectorAll("[id^='verificationCodeInput']")
19
+ );
20
+ }, []);
21
+
22
+ const loginRight = [
23
+ <LogoImage key="1" />,
24
+ <div className="credenciales" key={"2"}>
25
+ <ScreenHeader
26
+ fontFamily={FontFamily.AvenirNext}
27
+ color={GlobalColors.s5}
28
+ text={"Ingresa tus credenciales"}
29
+ />
30
+ </div>,
31
+ <div className="user" key="3">
32
+ <ScreenHeader
33
+ text={"Ingresa el código de verificación enviado a:"}
34
+ headerType={"input-name-header"}
35
+ />
36
+ <div className="verification-code">
37
+ {inputPositions.map((position) => (
38
+ <GeneralInput
39
+ inputId={`verificationCodeInput${position}`}
40
+ inputType={"text"}
41
+ inputPlaceholder={"X"}
42
+ validateInput={validateInput}
43
+ inputsArray={inputCodeVerificationAll}
44
+ position={position}
45
+ maxLength="1"
46
+ />
47
+ ))}
48
+ </div>
49
+ {emptyVerificationCode && (
50
+ <label>Ingrese su código de verificación</label>
51
+ )}
52
+ </div>,
53
+ <div className="resend-code" key="4">
54
+ <p>Reenviar código de verificación</p>
55
+ </div>,
56
+ <div className="button-center" key="5">
57
+ <Button
58
+ buttonType={"general-default-button"}
59
+ label={"Enviar"}
60
+ onClick={(e) =>
61
+ validate(inputCodeVerificationAll, setEmptyVerificationCode)
62
+ }
63
+ />
64
+ </div>,
65
+ <div className="reset-password" key="6">
66
+ <p>Regresar...</p>
67
+ </div>,
68
+ ];
69
+ return (
70
+ <Container>
71
+ <GradientPanel
72
+ componentsArray={loginRight}
73
+ panelType={"home-login"}
74
+ panelColor={GlobalColors.white}
75
+ />
76
+ </Container>
77
+ );
78
+ };
@@ -0,0 +1,49 @@
1
+ import styled from "styled-components";
2
+ import { FontFamily, GlobalColors } from "../../../global-files/variables";
3
+
4
+ export const Container = styled.div`
5
+ display: flex;
6
+ height: 100%;
7
+ width: 50%;
8
+ .button-center {
9
+ text-align: center;
10
+ .general-default-button {
11
+ width: 160px;
12
+ }
13
+ }
14
+ .reset-password {
15
+ text-align: center;
16
+ margin: 15px !important;
17
+ color: ${GlobalColors.secondary_magenta};
18
+ cursor: pointer;
19
+ font-weight: bold;
20
+ font-family: ${FontFamily.Raleway};
21
+ font-size: 13px;
22
+ }
23
+ .resend-code {
24
+ margin-top: 8px !important;
25
+ color: ${GlobalColors.magenta_s2};
26
+ font-family: ${FontFamily.AvenirNext};
27
+ font-size: 11px;
28
+ text-decoration: underline rgb(228, 81, 172);
29
+ cursor: pointer;
30
+ & + * {
31
+ margin-top: 30px;
32
+ }
33
+ }
34
+ .verification-code {
35
+ display: flex;
36
+ text-align: center;
37
+ margin: auto;
38
+ margin-top: 10px;
39
+ input[type="number"]::-webkit-inner-spin-button,
40
+ input[type="number"]::-webkit-outer-spin-button {
41
+ -webkit-appearance: none;
42
+ margin: 0;
43
+ }
44
+ input {
45
+ width: 70%;
46
+ text-align: center;
47
+ }
48
+ }
49
+ `;
@@ -0,0 +1,56 @@
1
+ /**
2
+ *
3
+ * @param {event} e event received triggered by verification code input
4
+ * @param {number} index index position from the verification code(VC) input array (i.e. digit 1,2,3 etc...)
5
+ * @param {array<html nodes>} inputsArray array which contains every VC digit input (used to change focus on input change)
6
+ */
7
+ export const validateInput = (e, index, inputsArray) => {
8
+ let isValid = false;
9
+ const inputNotEmpty = e.target.value.length > 0;
10
+ if (inputNotEmpty) {
11
+ if (validateInputNumber(e) !== null) {
12
+ isValid = true;
13
+ nextInputFocus(inputsArray, index++);
14
+ }
15
+ }
16
+ return isValid ? e.target.value : "";
17
+ };
18
+
19
+ /**
20
+ *
21
+ * @param {event} e event received triggered by verification code input
22
+ * @returns {boolean} if digit is a number
23
+ */
24
+ const validateInputNumber = (e) => {
25
+ return (e.target.value || String.fromCharCode(e.keyCode)).match(/[0-9]{1}/);
26
+ };
27
+
28
+ /**
29
+ *
30
+ * @param {array<html nodes>} inputsArray array which contains every VC digit input (used to change focus on input change)
31
+ * @param {number} index index position from the verification code(VC) input array (i.e. digit 1,2,3 etc...)
32
+ * changes focus to next input if digit typed is a number and there wasn't any before
33
+ */
34
+ const nextInputFocus = (inputsArray, index) => {
35
+ const button = document.getElementsByClassName("general-default-button");
36
+
37
+ inputsArray?.length && index === inputsArray?.length
38
+ ? button[0].focus()
39
+ : inputsArray[index]?.focus();
40
+ };
41
+
42
+ /**
43
+ *
44
+ * @param {array<html nodes>} inputsArray array which contains every VC digit input (used to check if there's any empty)
45
+ * @param {function} setEmptyVerificationCode function to update flag which handles if there's an empty char
46
+ * updates emptyVerificationFlag from father component
47
+ */
48
+ export const validate = (inputsArray, setEmptyVerificationCode) => {
49
+ let contInputEmpty = 0;
50
+ inputsArray.forEach((element) => {
51
+ element.value === "" ? 0 : contInputEmpty++;
52
+ });
53
+ contInputEmpty === inputsArray.length
54
+ ? setEmptyVerificationCode(false)
55
+ : setEmptyVerificationCode(true);
56
+ };
@@ -0,0 +1,11 @@
1
+ import { ChangePassword } from "./index";
2
+
3
+ export default {
4
+ title: "Components/organisms/ChangePassword",
5
+ component: ChangePassword,
6
+ };
7
+ const Template = (args) => <ChangePassword {...args} />;
8
+
9
+ export const ChangePasswordDefault = Template.bind({});
10
+
11
+ ChangePasswordDefault.args = {};