ui-soxo-bootstrap-core 2.4.25-dev.9 → 2.4.25

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 (31) hide show
  1. package/.github/workflows/npm-publish.yml +15 -37
  2. package/core/components/extra-info/extra-info-details.js +126 -109
  3. package/core/components/landing-api/landing-api.js +30 -22
  4. package/core/lib/Store.js +18 -20
  5. package/core/lib/components/index.js +1 -4
  6. package/core/lib/components/sidemenu/sidemenu.js +256 -153
  7. package/core/lib/components/sidemenu/sidemenu.scss +26 -39
  8. package/core/lib/elements/basic/rangepicker/rangepicker.js +29 -118
  9. package/core/lib/hooks/index.js +12 -2
  10. package/core/lib/pages/login/login.js +139 -255
  11. package/core/lib/pages/login/login.scss +32 -140
  12. package/core/models/dashboard/dashboard.js +0 -14
  13. package/core/models/menus/components/menu-add/menu-add.js +268 -230
  14. package/core/models/menus/components/menu-lists/menu-lists.js +89 -126
  15. package/core/models/menus/components/menu-lists/menu-lists.scss +0 -9
  16. package/core/models/menus/menus.js +267 -247
  17. package/core/models/roles/components/role-add/role-add.js +227 -269
  18. package/core/models/roles/components/role-list/role-list.js +6 -8
  19. package/core/models/roles/roles.js +174 -182
  20. package/core/models/users/components/user-add/user-add.js +1 -69
  21. package/core/models/users/users.js +0 -57
  22. package/core/modules/index.js +13 -23
  23. package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.js +1 -1
  24. package/package.json +2 -2
  25. package/core/lib/hooks/use-otp-timer.js +0 -99
  26. package/core/models/staff/components/staff-add/staff-add.js +0 -352
  27. package/core/models/staff/components/staff-add/staff-add.scss +0 -0
  28. package/core/modules/steps/action-buttons.js +0 -79
  29. package/core/modules/steps/steps.js +0 -553
  30. package/core/modules/steps/steps.scss +0 -158
  31. package/core/modules/steps/timeline.js +0 -49
@@ -1,6 +1,6 @@
1
1
  import React, { useState, useContext, useEffect } from 'react';
2
2
 
3
- import { Form, Input, message, Result, Radio, Divider, Typography } from 'antd';
3
+ import { Form, Input, message, Result } from 'antd';
4
4
 
5
5
  import { withRouter, Link } from 'react-router-dom';
6
6
 
@@ -8,8 +8,6 @@ import backgroundImage from './../../../assets/images/vector.png';
8
8
 
9
9
  import OTPInput from 'otp-input-react';
10
10
 
11
- import { useOtpTimer } from '../../hooks/use-otp-timer';
12
-
13
11
  import { motion } from 'framer-motion';
14
12
 
15
13
  import { Button } from '../../elements';
@@ -32,10 +30,6 @@ import { Location } from '../../utils';
32
30
 
33
31
  import { checkLicenseStatus } from '../../utils/common/common.utils';
34
32
 
35
- import { MailOutlined, MessageOutlined, WhatsAppOutlined } from '@ant-design/icons';
36
-
37
- const { Text, Title } = Typography;
38
-
39
33
  const layout = {
40
34
  labelCol: { span: 24 },
41
35
 
@@ -56,10 +50,7 @@ const LICENSE_EXPIRY = '2026-12-12';
56
50
  function LoginPhone({ history, appSettings }) {
57
51
  const { brandLogo, heroImage, footerLogo, headers } = appSettings;
58
52
 
59
- // Hook for OTP Timer
60
- const { expired: otpExpired, formatted, startFromExpiry } = useOtpTimer();
61
-
62
- const { dispatch, state, isMobile } = useContext(GlobalContext);
53
+ const { dispatch, state } = useContext(GlobalContext);
63
54
  // variabel used for btnloading
64
55
 
65
56
  const [loading, setLoading] = useState(false);
@@ -72,19 +63,11 @@ function LoginPhone({ history, appSettings }) {
72
63
  // variabale used to show otp entering screen
73
64
 
74
65
  const [otpVerification, setotpVerification] = useState(false);
75
- // otp sucess
76
- const [otpSuccess, setOtpSuccess] = useState(false);
77
- // otp fail err
78
- const [otpError, setOtpError] = useState(false);
79
66
 
80
67
  const [otpValue, setOtpValue] = useState('');
81
68
  // setting user credentials
82
69
  const [user, setUser] = useState([]);
83
70
 
84
- // for communication mode [mobile,sms,email]
85
- const [communicationMode, setCommunicationMode] = useState(null); // default selected email
86
- const [modeError, setModeError] = useState(false);
87
-
88
71
  const isAuthenticated = Boolean(getAccessToken());
89
72
  const isRefreshTokenExist = Boolean(getRefreshToken());
90
73
 
@@ -142,10 +125,6 @@ function LoginPhone({ history, appSettings }) {
142
125
 
143
126
  // set user values
144
127
  setUser(data);
145
- // Set default communication mode automatically
146
- if (result.data.mode) {
147
- setCommunicationMode(result.data.mode); // <--- fix
148
- }
149
128
  } else {
150
129
  let d = user;
151
130
 
@@ -227,22 +206,12 @@ function LoginPhone({ history, appSettings }) {
227
206
  *
228
207
  */
229
208
  const sendAuthenticationOtp = () => {
230
- // Reset previous error
231
- setModeError(false);
232
-
233
- // Validate communication mode
234
- if (!communicationMode) {
235
- setModeError(true); // Show error
236
- return; // Stop OTP send
237
- }
238
-
239
209
  setLoading(true);
240
-
241
210
  // set formbody
242
211
  let formBody;
243
212
  formBody = {
244
213
  email: user.username,
245
- mode: communicationMode,
214
+ mode: user.mode,
246
215
  };
247
216
 
248
217
  // api used to send otp corresponding mail address
@@ -253,8 +222,6 @@ function LoginPhone({ history, appSettings }) {
253
222
  }).then((result) => {
254
223
  // if the api is sucess then go for otpverification step
255
224
  if (result.success) {
256
- // for expiry_time
257
- startFromExpiry(result?.expiry_time);
258
225
  // if the api is sucess then go for otpverification step
259
226
  setotpVerification(true);
260
227
  // set button loading false
@@ -272,17 +239,13 @@ function LoginPhone({ history, appSettings }) {
272
239
  */
273
240
 
274
241
  const verifyOtp = () => {
275
- // If OTP expired, block verification
276
- if (otpExpired) {
277
- return;
278
- }
279
-
280
242
  setLoading(true);
281
-
282
- const formBody = {
243
+ let formBody;
244
+ // set formBody
245
+ formBody = {
283
246
  username: user.username,
284
247
  password: user.password,
285
- mode: communicationMode,
248
+ mode: user.mode,
286
249
  mobile: user.mobile,
287
250
  otp: otpValue,
288
251
  };
@@ -291,46 +254,35 @@ function LoginPhone({ history, appSettings }) {
291
254
  url: 'auth/verify-authentication-otp',
292
255
  formBody,
293
256
  headers,
294
- hideError: true, // removing unwanted error msg
295
- })
296
- .then((result) => {
297
- if (result.success) {
298
- // OTP success
299
- setOtpSuccess(true);
300
- setOtpError(false);
301
- setLoading(false);
302
-
303
- const userInfo = {
304
- id: result.user.id,
305
- locations: [],
306
- ...result.user,
257
+ }).then((result) => {
258
+ if (result.success) {
259
+ setLoading(false);
260
+ let d = result.user;
261
+
262
+ // Setting access_token
263
+ if (result?.access_token) localStorage.access_token = result.access_token;
264
+ // Setting refresh_token
265
+ if (result.refresh_token) localStorage.setItem('refresh_token', result.refresh_token);
266
+
267
+ // set user info
268
+ let userInfo = {
269
+ id: result.user.id,
270
+ locations: [],
271
+ ...d,
272
+ ...{
307
273
  loggedCheckDone: true,
308
- };
309
- // Setting access_token
310
- if (result?.access_token) localStorage.access_token = result.access_token;
311
- // Setting refresh_token
312
- if (result.refresh_token) localStorage.setItem('refresh_token', result.refresh_token);
313
-
314
- dispatch({ type: 'user', payload: userInfo });
315
- // set user info into local storage
316
- localStorage.setItem('userInfo', JSON.stringify(userInfo));
317
-
318
- setTimeout(() => history.push('/'), 500);
319
- } else {
320
- // OTP FAILED (wrong OTP)
321
- setOtpSuccess(false);
322
- setOtpError(true);
323
- setOtpValue(''); // Clear OTP
324
- setLoading(false);
325
- }
326
- })
327
- .catch((error) => {
328
- // Server error, timeout, network fail → treat as failed OTP
329
- setOtpSuccess(false);
330
- setOtpError(true);
274
+ },
275
+ };
331
276
 
277
+ dispatch({ type: 'user', payload: userInfo });
278
+ // set user info into local storage
279
+ localStorage.setItem('userInfo', JSON.stringify(userInfo));
280
+ history.push('/');
281
+ } else {
332
282
  setLoading(false);
333
- });
283
+ message.error(result.message);
284
+ }
285
+ });
334
286
  };
335
287
 
336
288
  const onFinishFailed = () => {
@@ -345,21 +297,18 @@ function LoginPhone({ history, appSettings }) {
345
297
  */
346
298
  const handleOtpChange = (value) => {
347
299
  setOtpValue(value);
348
- // Reset states so correct OTP will work after wrong OTP
349
- setOtpError(false);
350
- setOtpSuccess(false);
351
300
  };
352
301
 
353
302
  /**
354
303
  * Otp resend Logic
355
304
  */
356
305
  const handleResendOTP = () => {
306
+ // Resend OTP logic
307
+ setOtpVisible(true);
308
+ setotpVerification(false);
309
+
310
+ // when resend the otp . otpvalue reset
357
311
  setOtpValue('');
358
- setModeError(false);
359
- setOtpError(false);
360
- setOtpSuccess(false);
361
- // resend the OTP automatically
362
- sendAuthenticationOtp();
363
312
  };
364
313
 
365
314
  /**
@@ -368,15 +317,10 @@ function LoginPhone({ history, appSettings }) {
368
317
  const handlecancel = () => {
369
318
  setOtpVisible(false);
370
319
  setotpVerification(false);
371
- setOtpValue('');
372
- setModeError(false);
373
- setOtpError(false);
374
320
  };
375
321
 
376
322
  // Redirect Home Page, When token is exist
377
323
  useEffect(() => {
378
- // Do NOT redirect when OTP is visible or verification is happening
379
- if (otpVerification) return;
380
324
  if (isAuthenticated && isRefreshTokenExist && path === '/login') {
381
325
  Location.navigate({ url: '/' });
382
326
  } else {
@@ -392,14 +336,6 @@ function LoginPhone({ history, appSettings }) {
392
336
  // document.documentElement.style.setProperty('--custom-input-bg-color', state.theme.colors.inputBgColor);
393
337
  // document.documentElement.style.setProperty('--custom-input-color', state.theme.colors.inputColor);
394
338
  }, [state.theme]);
395
-
396
- // when otp is expired
397
- useEffect(() => {
398
- if (otpExpired) {
399
- setOtpValue(''); // Clear OTP box
400
- setOtpError(false);
401
- }
402
- }, [otpExpired]);
403
339
  /**
404
340
  * Function to get Ldap users
405
341
  * @returns
@@ -509,13 +445,6 @@ function LoginPhone({ history, appSettings }) {
509
445
  });
510
446
  };
511
447
 
512
- // helper to show contact in OTP verification screen
513
- const getOtpDestinationText = () => {
514
- if (communicationMode === 'mobile') return user.mobile;
515
- // if (communicationMode === 'whatsapp') return user.mobile;
516
- return user.username;
517
- };
518
-
519
448
  const { globalCustomerHeader = () => {} } = appSettings;
520
449
 
521
450
  const themeName = process.env.REACT_APP_THEME; // e.g., 'purple'
@@ -540,7 +469,20 @@ function LoginPhone({ history, appSettings }) {
540
469
  };
541
470
 
542
471
  return (
543
- <section className="full-page" style={sectionStyle}>
472
+ <section
473
+ className="full-page"
474
+ style={
475
+ sectionStyle
476
+ // {
477
+ // width: '100%',
478
+ // height: '100vh',
479
+ // backgroundImage: `url(${backgroundImage}), ${state.theme.colors.loginPageBackground}`,
480
+ // backgroundPosition: 'center bottom, center',
481
+ // backgroundRepeat: 'no-repeat, no-repeat',
482
+ // backgroundSize: 'cover, cover',
483
+ // }
484
+ }
485
+ >
544
486
  <section className="user-authentication-section">
545
487
  {/* Background Section */}
546
488
  <motion.div
@@ -549,7 +491,7 @@ function LoginPhone({ history, appSettings }) {
549
491
  animate={{ y: 0, opacity: 1 }}
550
492
  transition={{ duration: 1, ease: 'anticipate' }}
551
493
  exit={{ opacity: 0 }}
552
- />
494
+ ></motion.div>
553
495
  {/* Background Section Ends */}
554
496
 
555
497
  <motion.div
@@ -560,170 +502,112 @@ function LoginPhone({ history, appSettings }) {
560
502
  exit={{ opacity: 0 }}
561
503
  >
562
504
  <div
563
- className=" login-form-container"
564
- style={{
565
- background: state.theme.colors.tableBg,
566
- borderStyle: state.theme.colors.tableBorderStyle,
567
- }}
505
+ className="card card-shadow login-form-container"
506
+ style={{ background: state.theme.colors.tableBg, borderStyle: state.theme.colors.tableBorderStyle }}
568
507
  >
569
508
  <div className="brand-logo">
570
509
  <img className="logo-welcome" src={brandLogo} alt="Logo" />
571
510
  </div>
572
511
 
573
512
  <div className="otp-form">
574
- {/* OTP Verification Section */}
575
-
576
- {/* OTP Method Selection Section */}
577
- {otpVisible && (
513
+ {/* Two factor authentication section start */}
514
+ {otpVerification ? (
578
515
  <div className="otp-input-container">
579
516
  <div className="form-title">
580
- {otpVerification ? (
581
- <>
582
- {/* <h3>OTP Verification</h3> */}
583
- {/* <p>
584
- Enter the verification code we sent to{' '}
585
- <span className="otp-mode-text">
586
- <strong>{getOtpDestinationText()}</strong>
587
- </span>
588
- </p> */}
589
- </>
590
- ) : (
591
- <>
592
- <Text type="primary">Two Factor Authentication</Text>
593
- <p>
594
- Two-Factor Authentication is enabled for your account. Please verify your account before logging in to enhance security.
595
- </p>
596
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
597
- </>
598
- )}
517
+ <h3>Verify your account</h3>
518
+ <p>
519
+ An OTP has been sent to your <span className="otp-mode-text">{user.mode ? user.mode : 'Email'}</span>
520
+ <br />
521
+ </p>
599
522
  </div>
600
-
601
- {/* Show Communication Method ONLY IF:
602
- - OTP not sent OR
603
- - OTP expired
604
- */}
605
-
606
- {(!otpVerification || otpExpired) && (
607
- <>
608
- <Divider />
609
- <div className="otp-method-section">
610
- <Text type="primary">Select Preferred OTP Verification Method</Text>
611
- <div className="otp-method-group">
612
- <Radio checked={communicationMode === 'email'} onChange={() => setCommunicationMode('email')}>
613
- Email <MailOutlined style={{ marginLeft: 6 }} />
614
- </Radio>
615
- <Radio checked={communicationMode === 'mobile'} onChange={() => setCommunicationMode('mobile')}>
616
- SMS <MessageOutlined style={{ marginLeft: 6 }} />
617
- </Radio>
618
- </div>
619
- {modeError && <p className="otp-mode-error">Please select a communication mode.</p>}
620
- </div>
621
- </>
622
- )}
623
-
624
- {!otpVerification ? (
625
- <div className="otp-container">
626
- <Button type="primary" onClick={sendAuthenticationOtp} style={{ marginTop: '6px' }}>
627
- Send OTP
628
- </Button>
629
- </div>
630
- ) : (
631
- <>
632
- {/* <Divider /> */}
633
- <div className="otp-container">
634
- <p>
635
- Enter the verification code we sent to{' '}
636
- <span className="otp-mode-text">
637
- <strong>{getOtpDestinationText()}</strong>
638
- </span>
639
- </p>
640
- <OTPInput
641
- value={otpValue}
642
- onChange={handleOtpChange}
643
- autoFocus
644
- OTPLength={6}
645
- disabled={loading || otpExpired}
646
- inputStyles={{
647
- border: otpSuccess
648
- ? '2px solid #52c41a' // green
649
- : otpError
650
- ? '2px solid #FF5C5C' // red
651
- : '1px solid #d9d9d9', // default
652
- borderRadius: 4,
653
- width: isMobile ? 28 : 45, // MOBILE FIX
654
- height: isMobile ? 36 : 40, // MOBILE FIX
655
- margin: isMobile ? '2px' : '0 4px',
656
- fontSize: isMobile ? 16 : 18,
657
- textAlign: 'center',
658
- }}
659
- />
660
- {/* Timer below OTP */}
661
- <div className="otp-timer">
662
- {/* {!otpExpired ? */}
663
- {otpSuccess ? null : <span>{formatted}</span>}
664
- {/* {otpError && (
665
- <p style={{ color: 'red', marginTop: 8 }}>Invalid OTP, please try again</p>
666
- )} */}
667
-
668
- {otpSuccess && <p style={{ color: 'green', marginTop: 8 }}>Your OTP has been verified successfully.</p>}
669
- </div>
670
- </div>
671
- {!otpSuccess && (
672
- <Button type="primary" disabled={otpExpired} onClick={verifyOtp} style={{ marginTop: 16 }}>
673
- Verify OTP
674
- </Button>
675
- )}
676
- </>
677
- )}
523
+ <p className="otp-title">ENTER OTP</p>
524
+ <div className="otp-container">
525
+ <OTPInput value={otpValue} onChange={handleOtpChange} autoFocus OTPLength={6} />
526
+ </div>
527
+ <Button type="primary" className="SubmitBtn" onClick={verifyOtp}>
528
+ <i className="fa-regular fa-circle-check"></i> Verify OTP
529
+ </Button>
530
+ <Link className="resend-otp-link" onClick={handleResendOTP}>
531
+ <i className="fa-solid fa-arrows-rotate"></i> Resend OTP
532
+ </Link>
533
+ {/* Two factor authentication section end */}
678
534
  </div>
679
- )}
680
-
681
- {/* Login Form Section */}
682
- {!otpVerification && !otpVisible && (
683
- <Form {...layout} layout="vertical" name="basic" onFinish={onFinish} onFinishFailed={onFinishFailed}>
535
+ ) : otpVisible ? (
536
+ <div className="otp-input-container">
537
+ {/* Two factor authentication otp verification section start */}
684
538
  <div className="form-title">
685
- <h4></h4>
539
+ <h4>Two Factor Authentication</h4>
540
+ <p>
541
+ Two-Factor Authentication is enabled for your account . Please verify your account before your login to enhance the security of
542
+ your account.
543
+ <br></br>
544
+ </p>
545
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
686
546
  </div>
687
547
 
688
- {!process.env.REACT_APP_SHOW_BRANCH_SWITCHER && <div className="branch-switcher">{globalCustomerHeader()}</div>}
689
-
690
- {process.env.REACT_APP_ENABLE_LDAP === 'true' && (
691
- <Button loading={ldaploading} type="secondary" className="SubmitBtn" onClick={loginWithLdap}>
692
- Sign in using AD
548
+ <div className="otp-container">
549
+ <Button type="primary" className="SubmitBtn" onClick={sendAuthenticationOtp} loading={loading}>
550
+ Send OTP
551
+ </Button>
552
+ <Button type="secondary" onClick={handlecancel}>
553
+ Cancel
693
554
  </Button>
694
- )}
555
+ </div>
556
+ {/* Two factor authentication otp verification section end */}
557
+ </div>
558
+ ) : (
559
+ <>
560
+ <Form {...layout} layout="vertical" name="basic" onFinish={onFinish} onFinishFailed={onFinishFailed}>
561
+ <div className="form-title">
562
+ <h4></h4>
563
+ {/* <p>Your work assistant for the day!</p> */}
564
+ </div>
695
565
 
696
- <Form.Item label="Email" name="email" rules={[{ required: true, message: 'Please input your email!' }]}>
697
- <Input autoComplete="off" autoFocus />
698
- </Form.Item>
566
+ {/** branchswitcher Option */}
567
+ {!process.env.REACT_APP_SHOW_BRANCH_SWITCHER ? <div className="branch-switcher">{globalCustomerHeader()}</div> : null}
699
568
 
700
- <Form.Item label="Password" name="password" rules={[{ required: true, message: 'Please input your password!' }]}>
701
- <Input.Password autoComplete="off" />
702
- </Form.Item>
569
+ {/* {heroImage && (
570
+ <img className="customers" src={heroImage} alt="Logo" />
571
+ )} */}
703
572
 
704
- <Form.Item {...tailLayout}>
705
- <Button loading={loading} type="primary" htmlType="submit" className="SubmitBtn">
706
- &nbsp;&nbsp; Submit
707
- </Button>
708
- </Form.Item>
709
- </Form>
573
+ <br></br>
574
+ <div>
575
+ {process.env.REACT_APP_ENABLE_LDAP == 'true' && (
576
+ <Button loading={ldaploading} type="secondary" className="SubmitBtn" onClick={loginWithLdap}>
577
+ Sign in using AD
578
+ </Button>
579
+ )}
580
+ </div>
581
+ <Form.Item label="Email" name="email" rules={[{ required: true, message: 'Please input your email!' }]}>
582
+ <Input autoComplete="off" />
583
+ </Form.Item>
584
+
585
+ <Form.Item label="Password" name="password" rules={[{ required: true, message: 'Please input your password!' }]}>
586
+ <Input.Password autoComplete="off" />
587
+ </Form.Item>
588
+
589
+ <Form.Item {...tailLayout}>
590
+ <Button loading={loading} type="primary" htmlType="submit" className="SubmitBtn">
591
+ {/* <FontAwesomeIcon icon={faCheck} /> */}
592
+ &nbsp;&nbsp;
593
+ {/* <span>
594
+ <img src="../assets/tick-icon.png" alt="Tick Icon" />
595
+ </span> */}
596
+ Submit
597
+ </Button>
598
+ </Form.Item>
599
+ </Form>
600
+ </>
710
601
  )}
711
602
  </div>
712
603
  </div>
713
- {!otpSuccess && otpVerification && (
714
- <div className="otp-actions">
715
- <div className="resend-action">
716
- <Text disabled>Didn't receive OTP?</Text>
717
- <Link className="resend-otp-link" disabled={!otpExpired} onClick={handleResendOTP}>
718
- Resend OTP
719
- </Link>
720
- </div>
721
-
722
- <Button size="small" type="default" onClick={handlecancel}>
723
- Cancel
724
- </Button>
725
- </div>
726
- )}
604
+
605
+ {/* <div className="center-line"> */}
606
+ {/* <Link to="/register">Create Account</Link> */}
607
+ {/* <img className="footer-logo" src={footerLogo} alt={'user photograph'} /> */}
608
+ {/* </div> */}
609
+
610
+ {/* {heroImage && <img className="customers2" src={heroImage} alt="Logo" />} */}
727
611
  </motion.div>
728
612
  </section>
729
613
  </section>