@visns-studio/visns-components 5.4.6 → 5.4.8
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/README.md +527 -67
- package/package.json +2 -1
- package/src/components/crm/Navigation.jsx +19 -4
- package/src/components/crm/auth/Login.jsx +66 -10
- package/src/components/crm/auth/Profile.jsx +861 -176
- package/src/components/crm/auth/TwoFactorAuth.jsx +347 -0
- package/src/components/crm/auth/styles/Login.module.scss +36 -0
- package/src/components/crm/auth/styles/Profile.module.scss +469 -20
- package/src/components/crm/auth/styles/TwoFactorAuth.module.scss +65 -0
- package/src/components/crm/generic/GenericAuth.jsx +23 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import '../../styles/global.css';
|
|
2
2
|
|
|
3
|
-
import React, {
|
|
4
|
-
import { Link, useLocation } from 'react-router-dom';
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
|
5
5
|
import Reveal from 'react-reveal/Reveal';
|
|
6
6
|
import { toast } from 'react-toastify';
|
|
7
7
|
import { Person, LockOff } from 'akar-icons';
|
|
@@ -12,11 +12,14 @@ import styles from './styles/Login.module.scss';
|
|
|
12
12
|
|
|
13
13
|
const Login = ({ logo, providers, setSystemAuth, setUserProfile }) => {
|
|
14
14
|
const location = useLocation();
|
|
15
|
+
const navigate = useNavigate();
|
|
16
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
15
17
|
|
|
16
18
|
const [auth, setAuth] = useState({
|
|
17
19
|
email: '',
|
|
18
20
|
password: '',
|
|
19
21
|
location: location,
|
|
22
|
+
remember: false,
|
|
20
23
|
});
|
|
21
24
|
|
|
22
25
|
const [authClass, setAuthClass] = useState({
|
|
@@ -81,9 +84,13 @@ const Login = ({ logo, providers, setSystemAuth, setUserProfile }) => {
|
|
|
81
84
|
|
|
82
85
|
const handleChange = (e) => {
|
|
83
86
|
if (e) {
|
|
87
|
+
const value =
|
|
88
|
+
e.target.type === 'checkbox'
|
|
89
|
+
? e.target.checked
|
|
90
|
+
: e.target.value;
|
|
84
91
|
setAuth((prevState) => ({
|
|
85
92
|
...prevState,
|
|
86
|
-
[e.target.name]:
|
|
93
|
+
[e.target.name]: value,
|
|
87
94
|
}));
|
|
88
95
|
}
|
|
89
96
|
};
|
|
@@ -92,6 +99,9 @@ const Login = ({ logo, providers, setSystemAuth, setUserProfile }) => {
|
|
|
92
99
|
if (e) {
|
|
93
100
|
e.preventDefault();
|
|
94
101
|
|
|
102
|
+
setIsLoading(true);
|
|
103
|
+
toast.info('Logging in...', { autoClose: 2000 });
|
|
104
|
+
|
|
95
105
|
CustomFetch(
|
|
96
106
|
'/login/authenticate',
|
|
97
107
|
'POST',
|
|
@@ -103,13 +113,28 @@ const Login = ({ logo, providers, setSystemAuth, setUserProfile }) => {
|
|
|
103
113
|
: '',
|
|
104
114
|
},
|
|
105
115
|
(result) => {
|
|
116
|
+
setIsLoading(false);
|
|
106
117
|
if (result.error === '') {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
118
|
+
// Check if 2FA is required
|
|
119
|
+
if (result.requires_two_factor) {
|
|
120
|
+
// Redirect to 2FA page with user data and remember flag
|
|
121
|
+
navigate('/2fa', {
|
|
122
|
+
state: {
|
|
123
|
+
userData: result.user,
|
|
124
|
+
previousUrl:
|
|
125
|
+
location.state?.previousUrl || '',
|
|
126
|
+
remember: auth.remember,
|
|
127
|
+
},
|
|
128
|
+
});
|
|
111
129
|
} else {
|
|
112
|
-
|
|
130
|
+
// Normal login flow
|
|
131
|
+
setUserProfile(result.user);
|
|
132
|
+
|
|
133
|
+
if (result.previous && result.previous !== '') {
|
|
134
|
+
window.location.href = result.previous;
|
|
135
|
+
} else {
|
|
136
|
+
setSystemAuth(true);
|
|
137
|
+
}
|
|
113
138
|
}
|
|
114
139
|
} else {
|
|
115
140
|
setSystemAuth(false);
|
|
@@ -120,11 +145,13 @@ const Login = ({ logo, providers, setSystemAuth, setUserProfile }) => {
|
|
|
120
145
|
}));
|
|
121
146
|
|
|
122
147
|
toast.error(
|
|
123
|
-
|
|
148
|
+
result.error ||
|
|
149
|
+
'Could not log in with the supplied credentials, please try again.'
|
|
124
150
|
);
|
|
125
151
|
}
|
|
126
152
|
},
|
|
127
153
|
(error) => {
|
|
154
|
+
setIsLoading(false);
|
|
128
155
|
setAuthClass((prevState) => ({
|
|
129
156
|
...prevState,
|
|
130
157
|
username: 'inputError',
|
|
@@ -200,14 +227,43 @@ const Login = ({ logo, providers, setSystemAuth, setUserProfile }) => {
|
|
|
200
227
|
</small>
|
|
201
228
|
</label>
|
|
202
229
|
</div>
|
|
230
|
+
<div
|
|
231
|
+
className={`${styles.formItem} ${styles.fwItem}`}
|
|
232
|
+
>
|
|
233
|
+
<div className={styles.rememberMeContainer}>
|
|
234
|
+
<div
|
|
235
|
+
className={
|
|
236
|
+
styles.rememberMeCheckboxWrapper
|
|
237
|
+
}
|
|
238
|
+
>
|
|
239
|
+
<input
|
|
240
|
+
type="checkbox"
|
|
241
|
+
id="rememberMe"
|
|
242
|
+
name="remember"
|
|
243
|
+
checked={auth.remember}
|
|
244
|
+
onChange={handleChange}
|
|
245
|
+
className={
|
|
246
|
+
styles.rememberMeCheckbox
|
|
247
|
+
}
|
|
248
|
+
/>
|
|
249
|
+
</div>
|
|
250
|
+
<label
|
|
251
|
+
htmlFor="rememberMe"
|
|
252
|
+
className={styles.rememberMeLabel}
|
|
253
|
+
>
|
|
254
|
+
Remember me
|
|
255
|
+
</label>
|
|
256
|
+
</div>
|
|
257
|
+
</div>
|
|
203
258
|
<div
|
|
204
259
|
className={`${styles.formItem} ${styles.fwItem} ${styles.lastItem}`}
|
|
205
260
|
>
|
|
206
261
|
<button
|
|
207
262
|
className={styles.btn}
|
|
208
263
|
type="submit"
|
|
264
|
+
disabled={isLoading}
|
|
209
265
|
>
|
|
210
|
-
Login
|
|
266
|
+
{isLoading ? 'Logging in...' : 'Login'}
|
|
211
267
|
</button>
|
|
212
268
|
</div>
|
|
213
269
|
<div
|