ui-soxo-bootstrap-core 2.6.1-dev.1 → 2.6.1-dev.11
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/core/components/extra-info/extra-info-details.js +2 -2
- package/core/lib/Store.js +3 -3
- package/core/lib/components/global-header/global-header.js +2 -2
- package/core/lib/components/sidemenu/sidemenu.js +19 -13
- package/core/lib/elements/basic/country-phone-input/country-phone-input.js +14 -8
- package/core/lib/elements/basic/dragabble-wrapper/draggable-wrapper.js +1 -1
- package/core/lib/elements/basic/menu-tree/menu-tree.js +26 -13
- package/core/lib/models/forms/components/form-creator/form-creator.scss +5 -4
- package/core/lib/models/menus/components/menu-list/menu-list.js +424 -467
- package/core/lib/pages/change-password/change-password.js +17 -24
- package/core/lib/pages/change-password/change-password.scss +45 -48
- package/core/lib/pages/login/commnication-mode-selection.js +46 -0
- package/core/lib/pages/login/communication-mode-selection.scss +60 -0
- package/core/lib/pages/login/login.js +126 -22
- package/core/lib/pages/login/login.scss +229 -334
- package/core/lib/pages/login/reset-password.js +124 -0
- package/core/lib/pages/login/reset-password.scss +31 -0
- package/core/lib/pages/profile/themes.json +4 -4
- package/core/lib/utils/api/api.utils.js +30 -18
- package/core/lib/utils/common/common.utils.js +85 -0
- package/core/lib/utils/http/http.utils.js +1 -0
- package/core/lib/utils/index.js +4 -1
- package/core/models/base/base.js +7 -3
- package/core/models/core-scripts/core-scripts.js +9 -0
- package/core/models/doctor/components/doctor-add/doctor-add.js +9 -4
- package/core/models/menus/components/menu-add/menu-add.js +1 -1
- package/core/models/menus/components/menu-lists/menu-lists.js +5 -9
- package/core/models/menus/menus.js +21 -2
- package/core/models/roles/components/role-add/role-add.js +92 -59
- package/core/models/roles/components/role-list/role-list.js +1 -1
- package/core/models/staff/components/staff-add/staff-add.js +20 -32
- package/core/models/users/components/assign-role/assign-role.js +145 -50
- package/core/models/users/components/assign-role/assign-role.scss +209 -45
- package/core/models/users/components/assign-role/avatar-props.js +45 -0
- package/core/models/users/components/user-add/user-add.js +46 -55
- package/core/models/users/components/user-add/user-edit.js +25 -4
- package/core/models/users/users.js +16 -1
- package/core/modules/dashboard/components/dashboard-card/menu-dashboard-card.js +1 -1
- package/core/modules/reporting/components/reporting-dashboard/README.md +316 -0
- package/core/modules/reporting/components/reporting-dashboard/adavance-search/advance-search.js +266 -0
- package/core/modules/reporting/components/reporting-dashboard/display-columns/build-display-columns.js +75 -0
- package/core/modules/reporting/components/reporting-dashboard/display-columns/build-display-columns.test.js +74 -0
- package/core/modules/reporting/components/reporting-dashboard/display-columns/display-cell-renderer.js +252 -0
- package/core/modules/reporting/components/reporting-dashboard/display-columns/display-cell-renderer.test.js +126 -0
- package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.js +285 -399
- package/core/modules/steps/action-buttons.js +42 -44
- package/core/modules/steps/action-buttons.scss +35 -6
- package/core/modules/steps/steps.js +12 -10
- package/core/modules/steps/steps.scss +229 -31
- package/core/modules/steps/timeline.js +21 -19
- package/package.json +2 -1
|
@@ -39,7 +39,7 @@ function ChangePassword({ history }) {
|
|
|
39
39
|
|
|
40
40
|
const [loading, setLoading] = useState(false);
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
|
|
44
44
|
const onFinish = (values) => {
|
|
45
45
|
|
|
@@ -55,34 +55,27 @@ function ChangePassword({ history }) {
|
|
|
55
55
|
confirm_password: values.conpassword
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
//If current Password is entered wrong
|
|
68
|
-
message.error('Incorrect Password')
|
|
69
|
-
setLoading(false);
|
|
70
|
-
return false
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
58
|
+
ApiUtils.post({
|
|
59
|
+
url: `users/change-password`,
|
|
60
|
+
headers: {
|
|
61
|
+
db_ptr: 'nuraho'
|
|
62
|
+
},
|
|
63
|
+
formBody,
|
|
64
|
+
hideError: true
|
|
65
|
+
})
|
|
66
|
+
.then((result) => {
|
|
73
67
|
|
|
74
68
|
setLoading(false);
|
|
75
69
|
|
|
76
70
|
history.goBack();
|
|
77
71
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
message.error(error.result || error.message)
|
|
72
|
+
// Update successful.
|
|
73
|
+
message.success(result.result || 'Your password has been updated!');
|
|
74
|
+
|
|
75
|
+
}).catch(function (error) {
|
|
76
|
+
|
|
77
|
+
// An error happened.
|
|
78
|
+
message.warning(error.result || error.message);
|
|
86
79
|
|
|
87
80
|
setLoading(false);
|
|
88
81
|
|
|
@@ -1,63 +1,51 @@
|
|
|
1
|
-
.change-password {
|
|
2
|
-
margin:
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
// margin: 10px 3%;
|
|
6
|
-
// align-items: center;
|
|
7
|
-
|
|
8
|
-
@media only screen and (min-width: 768px) {
|
|
9
|
-
justify-content: left;
|
|
10
|
-
align-items: left;
|
|
1
|
+
.change-password.card {
|
|
2
|
+
margin: -6px 8px;
|
|
3
|
+
.ant-card-body {
|
|
4
|
+
padding: 16px;
|
|
11
5
|
}
|
|
12
6
|
|
|
13
|
-
.homescreen{
|
|
14
|
-
width: 100%;
|
|
15
|
-
margin: 10px 0px;
|
|
16
|
-
border-radius: 4px;
|
|
17
|
-
background-color: aliceblue;
|
|
18
|
-
padding:10px;
|
|
19
|
-
height: 40px;
|
|
20
|
-
}
|
|
21
7
|
.auth-form-wrapper {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: column;
|
|
10
|
+
gap: 18px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.form-title {
|
|
14
|
+
h4 {
|
|
15
|
+
margin-bottom: 6px;
|
|
16
|
+
font-weight: 600;
|
|
17
|
+
color: #111827;
|
|
28
18
|
}
|
|
29
19
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
20
|
+
p {
|
|
21
|
+
margin: 0;
|
|
22
|
+
font-size: 14px;
|
|
23
|
+
line-height: 1.6;
|
|
24
|
+
color: #6b7280;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
35
27
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
28
|
+
.ant-form-item {
|
|
29
|
+
margin-bottom: 18px;
|
|
30
|
+
|
|
31
|
+
.ant-form-item-label > label {
|
|
32
|
+
font-weight: 500;
|
|
33
|
+
font-size: 14px;
|
|
34
|
+
color: #374151;
|
|
39
35
|
}
|
|
40
36
|
|
|
41
|
-
.ant-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
margin: 0 0 8px 0;
|
|
47
|
-
line-height: 020px;
|
|
48
|
-
padding: 0px;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
.ant-btn-primary {
|
|
52
|
-
margin-top: 0px;
|
|
53
|
-
}
|
|
37
|
+
.ant-input-password {
|
|
38
|
+
border-radius: 6px;
|
|
39
|
+
padding: 10px 12px;
|
|
40
|
+
transition: border 0.2s ease, box-shadow 0.2s ease;
|
|
41
|
+
|
|
54
42
|
}
|
|
55
43
|
|
|
56
|
-
.ant-form-explain {
|
|
57
|
-
position: absolute;
|
|
44
|
+
.ant-form-item-explain-error {
|
|
58
45
|
font-size: 12px;
|
|
59
|
-
margin-
|
|
46
|
+
margin-top: 4px;
|
|
60
47
|
}
|
|
48
|
+
}
|
|
61
49
|
|
|
62
50
|
.ant-btn-primary {
|
|
63
51
|
width: 110px;
|
|
@@ -70,6 +58,15 @@
|
|
|
70
58
|
.ant-btn-secondary {
|
|
71
59
|
width: 100px;
|
|
72
60
|
}
|
|
61
|
+
|
|
62
|
+
@media (max-width: 768px) {
|
|
63
|
+
margin: 0px ;
|
|
64
|
+
.ant-card-body {
|
|
65
|
+
padding: 24px;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
@media only screen and (max-width: 1024px) {
|
|
69
|
+
margin: 60px 8px;
|
|
73
70
|
}
|
|
74
71
|
|
|
75
72
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CommunicationModeSelection Component
|
|
3
|
+
*
|
|
4
|
+
* Renders radio options for selecting OTP delivery method.
|
|
5
|
+
* Supports Email and SMS modes.
|
|
6
|
+
*
|
|
7
|
+
* Props:
|
|
8
|
+
* @param {string} communicationMode - Currently selected mode ('email' | 'mobile')
|
|
9
|
+
* @param {Function} setCommunicationMode - Updates selected mode
|
|
10
|
+
* @param {boolean} modeError - Displays validation error if true
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import React from 'react';
|
|
14
|
+
import { Radio, Divider, Typography } from 'antd';
|
|
15
|
+
import { MailOutlined, MessageOutlined } from '@ant-design/icons';
|
|
16
|
+
|
|
17
|
+
import './communication-mode-selection.scss';
|
|
18
|
+
|
|
19
|
+
const { Text } = Typography;
|
|
20
|
+
|
|
21
|
+
function CommunicationModeSelection({ communicationMode, setCommunicationMode, modeError }) {
|
|
22
|
+
return (
|
|
23
|
+
<>
|
|
24
|
+
<div className="otp-method-section">
|
|
25
|
+
<Text type="primary">Select Preferred OTP Verification Method</Text>
|
|
26
|
+
<div className="otp-method-group">
|
|
27
|
+
|
|
28
|
+
{/* Email Option */}
|
|
29
|
+
<Radio checked={communicationMode === 'email'} onChange={() => setCommunicationMode('email')}>
|
|
30
|
+
Email <MailOutlined className="otp-icon" style={{ marginLeft: 6 }} />
|
|
31
|
+
</Radio>
|
|
32
|
+
|
|
33
|
+
{/* SMS Option */}
|
|
34
|
+
<Radio checked={communicationMode === 'mobile'} disabled onChange={() => setCommunicationMode('mobile')}>
|
|
35
|
+
SMS <MessageOutlined className="otp-icon" style={{ marginLeft: 6 }} />
|
|
36
|
+
</Radio>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
{/* Validation Error */}
|
|
40
|
+
{modeError && <p className="otp-mode-error">Please select a communication mode.</p>}
|
|
41
|
+
</div>
|
|
42
|
+
</>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export default CommunicationModeSelection;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
$error-color: red;
|
|
2
|
+
|
|
3
|
+
.otp-method-section {
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
gap: 6px;
|
|
7
|
+
|
|
8
|
+
.otp-method-title {
|
|
9
|
+
font-size: 16px;
|
|
10
|
+
font-weight: 600;
|
|
11
|
+
margin-bottom: 8px;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.otp-method-group {
|
|
15
|
+
display: flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
margin-bottom: 10px;
|
|
18
|
+
gap: 30px;
|
|
19
|
+
font-size: 12px;
|
|
20
|
+
|
|
21
|
+
.ant-radio-wrapper {
|
|
22
|
+
display: flex;
|
|
23
|
+
gap: 6px;
|
|
24
|
+
|
|
25
|
+
svg {
|
|
26
|
+
font-size: 18px;
|
|
27
|
+
opacity: 0.8;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@media only screen and (max-width: 600px) {
|
|
32
|
+
flex-direction: column !important;
|
|
33
|
+
align-items: flex-start !important;
|
|
34
|
+
gap: 12px !important;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@media only screen and (min-width: 601px) and (max-width: 1024px) {
|
|
38
|
+
flex-direction: row !important;
|
|
39
|
+
align-items: center !important;
|
|
40
|
+
justify-content: space-between !important;
|
|
41
|
+
gap: 20px !important;
|
|
42
|
+
width: 100%;
|
|
43
|
+
|
|
44
|
+
.ant-radio-wrapper {
|
|
45
|
+
flex: 1;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.otp-mode-error {
|
|
51
|
+
margin: 5px;
|
|
52
|
+
font-size: 13px;
|
|
53
|
+
color: $error-color;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.otp-icon {
|
|
57
|
+
position: relative;
|
|
58
|
+
top: 2px;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -30,10 +30,12 @@ import { getAccessToken, getRefreshToken } from '../../utils/http/auth.helper';
|
|
|
30
30
|
|
|
31
31
|
import { Location } from '../../utils';
|
|
32
32
|
|
|
33
|
-
import { checkLicenseStatus, formatMobile, safeJSON } from '../../utils/common/common.utils';
|
|
33
|
+
import { checkLicenseStatus, formatMobile, checkExpiryStatus, safeJSON } from '../../utils/common/common.utils';
|
|
34
34
|
|
|
35
35
|
import { MailOutlined, MessageOutlined, WhatsAppOutlined } from '@ant-design/icons';
|
|
36
36
|
|
|
37
|
+
import ResetPassword from './reset-password';
|
|
38
|
+
|
|
37
39
|
const { Text, Title } = Typography;
|
|
38
40
|
|
|
39
41
|
const layout = {
|
|
@@ -48,6 +50,9 @@ const tailLayout = {
|
|
|
48
50
|
|
|
49
51
|
const LICENSE_EXPIRY = '2026-12-12';
|
|
50
52
|
|
|
53
|
+
//password valdity expire
|
|
54
|
+
const PASSWORD_VALIDITY_DAYS = 90;
|
|
55
|
+
|
|
51
56
|
const headers = {
|
|
52
57
|
db_ptr: 'nuraho',
|
|
53
58
|
};
|
|
@@ -89,11 +94,71 @@ function LoginPhone({ history, appSettings }) {
|
|
|
89
94
|
const [communicationMode, setCommunicationMode] = useState(null); // default selected email
|
|
90
95
|
const [modeError, setModeError] = useState(false);
|
|
91
96
|
|
|
97
|
+
//for forgot password show
|
|
98
|
+
const [showResetpassword, setShowResetpassword] = useState(false);
|
|
99
|
+
|
|
100
|
+
//for expired password show
|
|
101
|
+
const [expiredPassword, setExpiredPassword] = useState(false);
|
|
102
|
+
|
|
103
|
+
//for default name select when expire case
|
|
104
|
+
const [defaultUsername, setDefaultUsername] = useState('');
|
|
105
|
+
|
|
92
106
|
const isAuthenticated = Boolean(getAccessToken());
|
|
93
107
|
const isRefreshTokenExist = Boolean(getRefreshToken());
|
|
94
108
|
|
|
95
109
|
const path = window.location.pathname;
|
|
96
110
|
|
|
111
|
+
/**
|
|
112
|
+
* handlePasswordExpiryCheck
|
|
113
|
+
* --------------------------
|
|
114
|
+
* Validates whether a user's password is expired or nearing expiry.
|
|
115
|
+
*
|
|
116
|
+
* - Parses `last_password_change` from user.other_details.
|
|
117
|
+
* - Calculates expiry using PASSWORD_VALIDITY_DAYS.
|
|
118
|
+
* - Uses `checkExpiryStatus()` to determine status.
|
|
119
|
+
* - Shows Ant Design warning message if expired or within warning period.
|
|
120
|
+
* - Warning message includes navigation to `/change-password`.
|
|
121
|
+
*
|
|
122
|
+
* Requires:
|
|
123
|
+
* - PASSWORD_VALIDITY_DAYS constant
|
|
124
|
+
* - checkExpiryStatus utility
|
|
125
|
+
* - React Router history
|
|
126
|
+
* - antd message component
|
|
127
|
+
*/
|
|
128
|
+
const handlePasswordExpiryCheck = (user) => {
|
|
129
|
+
const otherDetails = user?.other_details ? JSON.parse(user.other_details) : null;
|
|
130
|
+
|
|
131
|
+
const lastPasswordChange = otherDetails?.last_password_change;
|
|
132
|
+
|
|
133
|
+
if (lastPasswordChange) {
|
|
134
|
+
const onlyDate = new Date(lastPasswordChange).toISOString().split('T')[0];
|
|
135
|
+
const passwordExpiryDate = new Date(onlyDate);
|
|
136
|
+
passwordExpiryDate.setDate(passwordExpiryDate.getDate() + PASSWORD_VALIDITY_DAYS);
|
|
137
|
+
|
|
138
|
+
const passwordStatus = checkExpiryStatus({
|
|
139
|
+
expiryDate: passwordExpiryDate,
|
|
140
|
+
warningDays: 2,
|
|
141
|
+
expiredMessage: 'Your password has expired. Please reset it.',
|
|
142
|
+
warningMessage: (d) => (
|
|
143
|
+
<span>
|
|
144
|
+
Your password will expire in {d} day(s).{' '}
|
|
145
|
+
<a
|
|
146
|
+
onClick={() => {
|
|
147
|
+
history.push('/change-password');
|
|
148
|
+
}}
|
|
149
|
+
>
|
|
150
|
+
Click here to update.
|
|
151
|
+
</a>
|
|
152
|
+
</span>
|
|
153
|
+
),
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
if (passwordStatus.message) {
|
|
157
|
+
message.warning(passwordStatus.message);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
97
162
|
const onFinish = (values) => {
|
|
98
163
|
setLoading(true);
|
|
99
164
|
|
|
@@ -131,6 +196,8 @@ function LoginPhone({ history, appSettings }) {
|
|
|
131
196
|
if (insider_token) localStorage.insider_token = insider_token;
|
|
132
197
|
|
|
133
198
|
if (result.success) {
|
|
199
|
+
handlePasswordExpiryCheck(user);
|
|
200
|
+
|
|
134
201
|
//two_factor_authentication variable is present then proceed Two factor authentication
|
|
135
202
|
if (result.data && result.data.two_factor_authentication) {
|
|
136
203
|
let data;
|
|
@@ -183,7 +250,19 @@ function LoginPhone({ history, appSettings }) {
|
|
|
183
250
|
history.push('/');
|
|
184
251
|
}
|
|
185
252
|
} else {
|
|
186
|
-
|
|
253
|
+
if (result.passwordChange) {
|
|
254
|
+
message.warning(result.message);
|
|
255
|
+
|
|
256
|
+
//time for redirect when expire
|
|
257
|
+
setTimeout(() => {
|
|
258
|
+
setExpiredPassword(true);
|
|
259
|
+
setDefaultUsername(values.email);
|
|
260
|
+
|
|
261
|
+
setShowResetpassword(true);
|
|
262
|
+
}, 1500);
|
|
263
|
+
} else {
|
|
264
|
+
message.warning(result.message);
|
|
265
|
+
}
|
|
187
266
|
}
|
|
188
267
|
})
|
|
189
268
|
.catch((error) => {
|
|
@@ -272,10 +351,10 @@ function LoginPhone({ history, appSettings }) {
|
|
|
272
351
|
if (result.success) {
|
|
273
352
|
// for expiry_time
|
|
274
353
|
startFromExpiry(result?.expiry_time);
|
|
275
|
-
// if the api is sucess then go for otpverification step
|
|
276
|
-
setotpVerification(true);
|
|
277
354
|
// set button loading false
|
|
278
355
|
setLoading(false);
|
|
356
|
+
// if the api is sucess then go for otpverification step
|
|
357
|
+
setotpVerification(true);
|
|
279
358
|
} else {
|
|
280
359
|
setLoading(false);
|
|
281
360
|
message.error(result.message);
|
|
@@ -332,7 +411,7 @@ function LoginPhone({ history, appSettings }) {
|
|
|
332
411
|
if (result?.user?.organization_details) {
|
|
333
412
|
const data = safeJSON(result?.user?.organization_details);
|
|
334
413
|
|
|
335
|
-
const defaultBranch = data.branch.find((b) => b.defaultBranch ===
|
|
414
|
+
const defaultBranch = data.branch.find((b) => b.defaultBranch === true);
|
|
336
415
|
const defaultDbptr = defaultBranch?.dbPtr;
|
|
337
416
|
|
|
338
417
|
localStorage.setItem('db_ptr', defaultDbptr);
|
|
@@ -342,6 +421,8 @@ function LoginPhone({ history, appSettings }) {
|
|
|
342
421
|
// set user info into local storage
|
|
343
422
|
localStorage.setItem('userInfo', JSON.stringify(userInfo));
|
|
344
423
|
|
|
424
|
+
handlePasswordExpiryCheck(result.user);
|
|
425
|
+
|
|
345
426
|
setTimeout(() => history.push('/'), 500);
|
|
346
427
|
} else {
|
|
347
428
|
// OTP FAILED (wrong OTP)
|
|
@@ -543,28 +624,28 @@ function LoginPhone({ history, appSettings }) {
|
|
|
543
624
|
return user.username;
|
|
544
625
|
};
|
|
545
626
|
|
|
546
|
-
const { globalCustomerHeader = () => {} } = appSettings;
|
|
627
|
+
const { globalCustomerHeader = () => { } } = appSettings;
|
|
547
628
|
|
|
548
629
|
const themeName = process.env.REACT_APP_THEME; // e.g., 'purple'
|
|
549
630
|
const isPurple = themeName === 'purple';
|
|
550
631
|
|
|
551
632
|
const sectionStyle = isPurple
|
|
552
633
|
? {
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
634
|
+
width: '100%',
|
|
635
|
+
height: '100vh',
|
|
636
|
+
backgroundImage: `${state.theme.colors.loginPageBackground}`,
|
|
637
|
+
backgroundPosition: 'center bottom, center',
|
|
638
|
+
backgroundRepeat: 'no-repeat, no-repeat',
|
|
639
|
+
backgroundSize: 'cover, cover',
|
|
640
|
+
}
|
|
560
641
|
: {
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
642
|
+
width: '100%',
|
|
643
|
+
height: '100vh',
|
|
644
|
+
background: 'linear-gradient(to bottom, #F7F6E3 0%, #EEF1DE 20%, #D5E4DA 45%, #9DBFC8 75%, #4F89A6 100%)',
|
|
645
|
+
backgroundPosition: 'center bottom, center',
|
|
646
|
+
backgroundRepeat: 'no-repeat, no-repeat',
|
|
647
|
+
backgroundSize: 'cover, cover',
|
|
648
|
+
};
|
|
568
649
|
|
|
569
650
|
return (
|
|
570
651
|
<section className="full-page" style={sectionStyle}>
|
|
@@ -706,7 +787,7 @@ function LoginPhone({ history, appSettings }) {
|
|
|
706
787
|
)}
|
|
707
788
|
|
|
708
789
|
{/* Login Form Section */}
|
|
709
|
-
{!otpVerification && !otpVisible && (
|
|
790
|
+
{!otpVerification && !otpVisible && !showResetpassword && (
|
|
710
791
|
<Form {...layout} layout="vertical" name="basic" onFinish={onFinish} onFinishFailed={onFinishFailed}>
|
|
711
792
|
<div className="form-title">
|
|
712
793
|
<h4></h4>
|
|
@@ -728,19 +809,42 @@ function LoginPhone({ history, appSettings }) {
|
|
|
728
809
|
<Input.Password autoComplete="off" />
|
|
729
810
|
</Form.Item>
|
|
730
811
|
|
|
731
|
-
<Form.Item {...tailLayout}>
|
|
812
|
+
<Form.Item {...tailLayout} style={{ marginBottom: '0px' }}>
|
|
732
813
|
<Button loading={loading} type="primary" htmlType="submit" className="SubmitBtn">
|
|
733
814
|
Submit
|
|
734
815
|
</Button>
|
|
816
|
+
<div className="forgot-password">
|
|
817
|
+
<Link onClick={() => setShowResetpassword(true)}>Forgot Password?</Link>
|
|
818
|
+
</div>
|
|
735
819
|
</Form.Item>
|
|
736
820
|
</Form>
|
|
737
821
|
)}
|
|
822
|
+
|
|
823
|
+
{/* Forgot Password Section */}
|
|
824
|
+
{showResetpassword && (
|
|
825
|
+
<ResetPassword
|
|
826
|
+
defaultUsername={expiredPassword ? defaultUsername : undefined}
|
|
827
|
+
disabledUserName={expiredPassword}
|
|
828
|
+
onBack={() => {
|
|
829
|
+
setShowResetpassword(false);
|
|
830
|
+
setExpiredPassword(false);
|
|
831
|
+
}}
|
|
832
|
+
title={expiredPassword ? 'Password Expired!' : 'Forgot Password?'}
|
|
833
|
+
// subtitle={
|
|
834
|
+
// expiredPassword
|
|
835
|
+
// ? 'Your password has expired. Select a preferred communication method to receive the One-Time Password (OTP) to continue.'
|
|
836
|
+
// : 'Enter your username and Select a preferred communication method to receive the One-Time Password (OTP) to continue..'
|
|
837
|
+
// }
|
|
838
|
+
buttonText={expiredPassword ? 'Send Reset Link' : 'Send Reset Link'}
|
|
839
|
+
/>
|
|
840
|
+
)}
|
|
738
841
|
</div>
|
|
739
842
|
</div>
|
|
740
843
|
{!otpSuccess && otpVerification && (
|
|
741
844
|
<div className="otp-actions">
|
|
742
845
|
<div className="resend-action">
|
|
743
846
|
<Text disabled>Didn't receive OTP?</Text>
|
|
847
|
+
|
|
744
848
|
<Link className="resend-otp-link" disabled={!otpExpired} onClick={handleResendOTP}>
|
|
745
849
|
Resend OTP
|
|
746
850
|
</Link>
|