ui-soxo-bootstrap-core 2.6.17 → 2.6.19

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.
@@ -6,79 +6,53 @@
6
6
  * Ensure to follow a minimal standard
7
7
  */
8
8
  import React, { useState, useEffect, useRef } from 'react';
9
-
10
9
  import PhoneInput from 'react-phone-input-2';
11
-
12
10
  import 'react-phone-input-2/lib/style.css';
13
-
14
- import PropTypes from "prop-types";
15
-
11
+ import PropTypes from 'prop-types';
16
12
  import './phone-input.scss';
17
13
 
18
-
19
- export default function CountryPhoneInput({ value, onChange, disabled, disableCountryCode, required, defaultCountryCode, onBlur, onKeyDown }) {
20
-
21
- let inputRef = useRef();
22
-
23
- const [phone, setPhone] = useState();
24
-
14
+ export default function CountryPhoneInput({
15
+ value,
16
+ onChange,
17
+ disabled,
18
+ disableCountryCode,
19
+ required,
20
+ defaultCountryCode,
21
+ onBlur,
22
+ className,
23
+ onKeyDown,
24
+ }) {
25
+ const inputRef = useRef();
26
+ const hasInitializedRef = useRef(false); // IMPORTANT
27
+
28
+ const [phone, setPhone] = useState('');
29
+ /**
30
+ * run ONLY ONCE when initial value has dial code
31
+ */
25
32
  useEffect(() => {
26
- if (value && value.code && value.code.dialCode !== null) {
27
- // To prepopulate phone number ,concat dialCode and phone number
33
+ if (!hasInitializedRef.current && value?.code?.dialCode && value?.value) {
28
34
  setPhone(value.code.dialCode + value.value);
29
-
30
- // In case of update , to identify the country code that is getting selected
31
- // We are setting a timeout
32
- setTimeout(() => {
33
- // Using the reference , we get the internal state of the library component
34
- let selectedCountry = null;
35
-
36
- let selectedCode = null;
37
-
38
- if (
39
- inputRef.current &&
40
- inputRef.current.state &&
41
- inputRef.current.state.selectedCountry
42
- ) {
43
- selectedCountry = inputRef.current.state.selectedCountry;
44
-
45
- // Once we get the selected country ,we format it to the form that is received for normal onChange
46
- selectedCode = {
47
- countryCode: selectedCountry.iso2,
48
- dialCode: selectedCountry.dialCode,
49
- name: selectedCountry.name,
50
- };
51
- }
52
-
53
- // Below being the format expected , we trigger the onChange to manually update the form
54
- let updatedValue = {
55
- value: value.code.dialCode + value.value,
56
- code: selectedCode,
57
- };
58
-
59
- onChange(updatedValue);
60
- }, 0);
35
+ hasInitializedRef.current = true; // 👈 mark as done
61
36
  }
62
- }, []);
37
+ }, [value]);
63
38
 
64
39
  /**
65
- * To get value in parent component
66
- * @param {*} value
40
+ * handle user input
67
41
  */
68
- function handleInput(value, code) {
69
- if (code.dialCode) {
70
- value = value.substring(code.dialCode.length);
71
- }
72
- // To get country code with phone number in parent component
73
- value = {
74
- value,
42
+ function handleInput(inputValue, code) {
43
+ if (!code?.dialCode) return;
44
+
45
+ const phoneNumber = inputValue.slice(code.dialCode.length);
46
+
47
+ // remove autofill class when user edits field (if you use it)
48
+ onChange({
49
+ value: phoneNumber,
75
50
  code,
76
- };
77
- onChange(value);
51
+ });
78
52
  }
79
53
 
80
54
  return (
81
- <div className="phone-input">
55
+ <div className={`phone-input ${className || ''}`}>
82
56
  <PhoneInput
83
57
  ref={inputRef}
84
58
  country={defaultCountryCode || 'in'}
@@ -104,4 +78,4 @@ CountryPhoneInput.propTypes = {
104
78
  disableCountryCode: PropTypes.bool,
105
79
  /** A boolean indicating whether the input is required or not. This prop is optional. */
106
80
  required: PropTypes.bool,
107
- };
81
+ };
@@ -12,6 +12,20 @@
12
12
  // }
13
13
  }
14
14
 
15
+ .autofilled-field {
16
+ .react-tel-input {
17
+ .form-control {
18
+ border-color: #fa8c16 !important; // AntD warning orange
19
+ background-color: #fff7e6;
20
+ box-shadow: none;
21
+ }
22
+
23
+ .flag-dropdown {
24
+ border-color: #fa8c16 !important;
25
+ background-color: #fff7e6;
26
+ }
27
+ }
28
+ }
15
29
  // /* For tablets and smaller screens (max-width: 1024px) */
16
30
  // @media (max-width: 1024px) {
17
31
  // .phone-input {
@@ -30,7 +30,7 @@ import { getAccessToken, getRefreshToken } from '../../utils/http/auth.helper';
30
30
 
31
31
  import { Location } from '../../utils';
32
32
 
33
- import { checkLicenseStatus, formatMobile, checkExpiryStatus, safeJSON } from '../../utils/common/common.utils';
33
+ import { checkLicenseStatus, formatMobile, safeJSON } from '../../utils/common/common.utils';
34
34
 
35
35
  import { MailOutlined, MessageOutlined, WhatsAppOutlined } from '@ant-design/icons';
36
36
 
@@ -50,8 +50,6 @@ const tailLayout = {
50
50
 
51
51
  const LICENSE_EXPIRY = '2026-12-12';
52
52
 
53
- //password valdity expire
54
- const PASSWORD_VALIDITY_DAYS = 90;
55
53
 
56
54
  const headers = {
57
55
  db_ptr: 'nuraho',
@@ -115,47 +113,32 @@ function LoginPhone({ history, appSettings }) {
115
113
  *
116
114
  * - Parses `last_password_change` from user.other_details.
117
115
  * - Calculates expiry using PASSWORD_VALIDITY_DAYS.
118
- * - Uses `checkExpiryStatus()` to determine status.
119
116
  * - Shows Ant Design warning message if expired or within warning period.
120
117
  * - Warning message includes navigation to `/change-password`.
121
118
  *
122
119
  * Requires:
123
120
  * - PASSWORD_VALIDITY_DAYS constant
124
- * - checkExpiryStatus utility
125
121
  * - React Router history
126
122
  * - antd message component
127
123
  */
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
- });
124
+ const handlePasswordExpiryCheck = (expiryDays) => {
125
+ if (expiryDays == null) return;
155
126
 
156
- if (passwordStatus.message) {
157
- message.warning(passwordStatus.message);
158
- }
127
+ if (expiryDays <= 0) {
128
+ message.error('Your password has expired. Please reset it.');
129
+
130
+ setExpiredPassword(true);
131
+ setShowResetpassword(true);
132
+
133
+ return;
134
+ }
135
+
136
+ if (expiryDays <= 2) {
137
+ message.warning(
138
+ <span>
139
+ Your password will expire in {expiryDays} day(s). <a onClick={() => history.push('/change-password')}>Click here to update.</a>
140
+ </span>
141
+ );
159
142
  }
160
143
  };
161
144
 
@@ -196,7 +179,7 @@ function LoginPhone({ history, appSettings }) {
196
179
  if (insider_token) localStorage.insider_token = insider_token;
197
180
 
198
181
  if (result.success) {
199
- handlePasswordExpiryCheck(user);
182
+ handlePasswordExpiryCheck(result.expiry_in_days);
200
183
 
201
184
  //two_factor_authentication variable is present then proceed Two factor authentication
202
185
  if (result.data && result.data.two_factor_authentication) {
@@ -421,7 +404,7 @@ function LoginPhone({ history, appSettings }) {
421
404
  // set user info into local storage
422
405
  localStorage.setItem('userInfo', JSON.stringify(userInfo));
423
406
 
424
- handlePasswordExpiryCheck(result.user);
407
+ handlePasswordExpiryCheck(result.expiry_in_days);
425
408
 
426
409
  setTimeout(() => history.push('/'), 500);
427
410
  } else {
@@ -123,41 +123,6 @@ export const checkLicenseStatus = (expiryDate) => {
123
123
  return { valid: true, daysLeft, message: null, level: null };
124
124
  };
125
125
 
126
- /**
127
- * Checks password expiry status.
128
- *
129
- * @param {string|Date} expiryDate
130
- * @param {number} warningDays
131
- * @param {string} expiredMessage
132
- * @param {(daysLeft: number) => string} warningMessage
133
- *
134
- * @returns {{ valid: boolean, daysLeft: number, message: string|null, level: "error"|"warning"|null }}
135
- */
136
-
137
- export const checkExpiryStatus = ({ expiryDate, warningDays, expiredMessage, warningMessage }) => {
138
- const expiry = new Date(expiryDate);
139
-
140
- if (isNaN(expiry)) {
141
- return { valid: false, daysLeft: 0, message: 'Invalid date', level: 'error' };
142
- }
143
-
144
- expiry.setHours(0, 0, 0, 0);
145
- const today = new Date();
146
- today.setHours(0, 0, 0, 0);
147
-
148
- const msDiff = expiry.getTime() - today.getTime();
149
- const daysLeft = Math.ceil(msDiff / (1000 * 60 * 60 * 24));
150
-
151
- if (daysLeft < 0) {
152
- return { valid: false, daysLeft, message: expiredMessage, level: 'error' };
153
- }
154
-
155
- if (daysLeft <= warningDays) {
156
- return { valid: true, daysLeft, message: warningMessage(daysLeft), level: 'warning' };
157
- }
158
-
159
- return { valid: true, daysLeft, message: null, level: null };
160
- };
161
126
 
162
127
  /**
163
128
  * Masks a mobile number by hiding all but the last `visibleDigits`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ui-soxo-bootstrap-core",
3
- "version": "2.6.17",
3
+ "version": "2.6.19",
4
4
  "description": "All the Core Components for you to start",
5
5
  "keywords": [
6
6
  "all in one"