ui-soxo-bootstrap-core 2.6.1-dev.3 → 2.6.1-dev.31

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 (68) hide show
  1. package/core/components/extra-info/extra-info-details.js +2 -2
  2. package/core/components/index.js +2 -11
  3. package/core/components/landing-api/landing-api.js +216 -18
  4. package/core/components/landing-api/landing-api.scss +22 -0
  5. package/core/components/license-management/license-alert.js +97 -0
  6. package/core/lib/Store.js +8 -4
  7. package/core/lib/components/global-header/global-header.js +217 -242
  8. package/core/lib/components/index.js +2 -2
  9. package/core/lib/components/sidemenu/sidemenu.js +19 -13
  10. package/core/lib/components/sidemenu/sidemenu.scss +1 -1
  11. package/core/lib/elements/basic/country-phone-input/country-phone-input.js +14 -9
  12. package/core/lib/elements/basic/dragabble-wrapper/draggable-wrapper.js +1 -1
  13. package/core/lib/elements/basic/menu-tree/menu-tree.js +26 -13
  14. package/core/lib/models/forms/components/form-creator/form-creator.js +525 -468
  15. package/core/lib/models/forms/components/form-creator/form-creator.scss +30 -26
  16. package/core/lib/models/menus/components/menu-list/menu-list.js +424 -467
  17. package/core/lib/models/process/components/process-dashboard/process-dashboard.js +469 -3
  18. package/core/lib/models/process/components/process-dashboard/process-dashboard.scss +4 -0
  19. package/core/lib/modules/generic/generic-list/ExportReactCSV.js +28 -2
  20. package/core/lib/pages/change-password/change-password.js +17 -24
  21. package/core/lib/pages/change-password/change-password.scss +45 -48
  22. package/core/lib/pages/login/commnication-mode-selection.js +2 -2
  23. package/core/lib/pages/login/login.js +53 -64
  24. package/core/lib/pages/login/login.scss +9 -0
  25. package/core/lib/pages/login/reset-password.js +17 -17
  26. package/core/lib/pages/login/reset-password.scss +10 -1
  27. package/core/lib/pages/profile/themes.json +4 -4
  28. package/core/lib/utils/api/api.utils.js +53 -45
  29. package/core/lib/utils/common/common.utils.js +49 -35
  30. package/core/lib/utils/generic/generic.utils.js +2 -1
  31. package/core/lib/utils/http/http.utils.js +33 -4
  32. package/core/lib/utils/index.js +4 -1
  33. package/core/models/base/base.js +7 -3
  34. package/core/models/core-scripts/core-scripts.js +147 -126
  35. package/core/models/doctor/components/doctor-add/doctor-add.js +9 -4
  36. package/core/models/menus/components/menu-add/menu-add.js +1 -1
  37. package/core/models/menus/components/menu-lists/menu-lists.js +53 -54
  38. package/core/models/menus/menus.js +49 -2
  39. package/core/models/roles/components/role-add/role-add.js +92 -59
  40. package/core/models/roles/components/role-list/role-list.js +1 -1
  41. package/core/models/staff/components/staff-add/staff-add.js +20 -32
  42. package/core/models/users/components/assign-role/assign-role.js +145 -50
  43. package/core/models/users/components/assign-role/assign-role.scss +209 -45
  44. package/core/models/users/components/assign-role/avatar-props.js +45 -0
  45. package/core/models/users/components/user-add/user-add.js +46 -55
  46. package/core/models/users/components/user-add/user-edit.js +25 -4
  47. package/core/models/users/users.js +9 -1
  48. package/core/modules/dashboard/components/dashboard-card/menu-dashboard-card.js +1 -1
  49. package/core/modules/reporting/components/reporting-dashboard/README.md +316 -0
  50. package/core/modules/reporting/components/reporting-dashboard/adavance-search/advance-search.js +174 -0
  51. package/core/modules/reporting/components/reporting-dashboard/adavance-search/advance-search.scss +76 -0
  52. package/core/modules/reporting/components/reporting-dashboard/display-columns/build-display-columns.js +90 -0
  53. package/core/modules/reporting/components/reporting-dashboard/display-columns/build-display-columns.test.js +74 -0
  54. package/core/modules/reporting/components/reporting-dashboard/display-columns/display-cell-renderer.js +448 -0
  55. package/core/modules/reporting/components/reporting-dashboard/display-columns/display-cell-renderer.test.js +199 -0
  56. package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.js +195 -822
  57. package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.scss +43 -0
  58. package/core/modules/reporting/components/reporting-dashboard/reporting-table.js +517 -0
  59. package/core/modules/steps/action-buttons.js +30 -16
  60. package/core/modules/steps/action-buttons.scss +55 -9
  61. package/core/modules/steps/chat-assistant.js +141 -0
  62. package/core/modules/steps/openai-realtime.js +275 -0
  63. package/core/modules/steps/readme.md +167 -0
  64. package/core/modules/steps/steps.js +1286 -60
  65. package/core/modules/steps/steps.scss +703 -86
  66. package/core/modules/steps/timeline.js +21 -19
  67. package/core/modules/steps/voice-navigation.js +709 -0
  68. package/package.json +2 -1
@@ -1,5 +1,5 @@
1
1
  import React, { useState, useCallback, useEffect } from 'react';
2
- import { Space, Popconfirm, Input, Drawer, Skeleton, Collapse, message } from 'antd';
2
+ import { Space, Popconfirm, Input, Drawer, Skeleton, Collapse, message, Tag, Empty } from 'antd';
3
3
  import { ReloadOutlined, DeleteOutlined, EditOutlined, PlusCircleFilled, CopyOutlined } from '@ant-design/icons';
4
4
  import { Button, Card, Switch, DraggableWrapper } from '../../../../lib';
5
5
  // for draggable menu list import { DndProvider } from "react-dnd";
@@ -55,7 +55,6 @@ const MenuLists = ({ model, match, relativeAdd = false, additional_queries = [],
55
55
  .catch(() => setLoading(false));
56
56
  };
57
57
 
58
- console.log('record', records);
59
58
  /**
60
59
  *
61
60
  */
@@ -204,9 +203,9 @@ const MenuLists = ({ model, match, relativeAdd = false, additional_queries = [],
204
203
  model.delete(rec).then(loadMenus);
205
204
  };
206
205
 
207
- const filtered = records.filter((r) => r.name?.toUpperCase().includes(query.toUpperCase()));
206
+ const filtered = records.filter((r) => r.caption?.toUpperCase().includes(query.toUpperCase()));
208
207
 
209
- const visibleItems = dragMode ? records : filtered;
208
+ const visibleItems = filtered;
210
209
 
211
210
  const onSearch = (event) => {
212
211
  setQuery(event.target.value);
@@ -363,50 +362,53 @@ const MenuLists = ({ model, match, relativeAdd = false, additional_queries = [],
363
362
  <Card>
364
363
  <DndProvider backend={HTML5Backend}>
365
364
  <Collapse accordion>
366
- {visibleItems.map((item, index) => (
367
- <Panel
368
- key={item.id}
369
- header={
370
- <DraggableWrapper
371
- id={item.id}
372
- index={index}
373
- movePanel={movePanel}
374
- item={item}
375
- dragEnabled={dragMode}
376
- level={1}
377
- parentId={null}
378
- onCrossLevelMove={handleCrossLevelMove}
379
- canAcceptChildren={true}
380
- />
381
- }
382
- // only show arrow if sub_menus exist
383
- showArrow={item.sub_menus && item.sub_menus.length > 0}
384
- // disable panel
385
- // collapsible={item.sub_menus && item.sub_menus.length > 0 ? 'header' : 'disabled'}
386
- extra={panelActions(item, model, setSelectedRecord, setDrawerTitle, setDrawerVisible, deleteRecord)}
387
- >
388
- {item.sub_menus && item.sub_menus.length > 0 && (
389
- <NestedMenu
390
- parentId={item.id}
391
- step={item.step + 1}
392
- items={item.sub_menus || []}
393
- model={model}
394
- dragMode={dragMode}
395
- setSelectedRecord={setSelectedRecord}
396
- setDrawerTitle={setDrawerTitle}
397
- setDrawerVisible={setDrawerVisible}
398
- deleteRecord={deleteRecord}
399
- level={2}
400
- onCrossLevelMove={handleCrossLevelMove}
401
- onChange={(subMenus) => {
402
- const updated = records.map((r) => (r.id === item.id ? { ...r, sub_menus: subMenus } : r));
403
- setRecords(updated);
404
- setOrderChanged(true);
405
- }}
406
- />
407
- )}
408
- </Panel>
409
- ))}
365
+ {visibleItems && visibleItems.length > 0 ? (
366
+ visibleItems.map((item, index) => (
367
+ <Panel
368
+ key={item.id}
369
+ header={
370
+ <DraggableWrapper
371
+ id={item.id}
372
+ index={index}
373
+ movePanel={movePanel}
374
+ item={item}
375
+ dragEnabled={dragMode}
376
+ level={1}
377
+ parentId={null}
378
+ onCrossLevelMove={handleCrossLevelMove}
379
+ canAcceptChildren={true}
380
+ />
381
+ }
382
+ showArrow={item.sub_menus && item.sub_menus.length > 0}
383
+ extra={panelActions(item, model, setSelectedRecord, setDrawerTitle, setDrawerVisible, deleteRecord)}
384
+ >
385
+ {item.sub_menus && item.sub_menus.length > 0 && (
386
+ <NestedMenu
387
+ parentId={item.id}
388
+ step={item.step + 1}
389
+ items={item.sub_menus || []}
390
+ model={model}
391
+ dragMode={dragMode}
392
+ setSelectedRecord={setSelectedRecord}
393
+ setDrawerTitle={setDrawerTitle}
394
+ setDrawerVisible={setDrawerVisible}
395
+ deleteRecord={deleteRecord}
396
+ level={2}
397
+ onCrossLevelMove={handleCrossLevelMove}
398
+ onChange={(subMenus) => {
399
+ const updated = records.map((r) => (r.id === item.id ? { ...r, sub_menus: subMenus } : r));
400
+ setRecords(updated);
401
+ setOrderChanged(true);
402
+ }}
403
+ />
404
+ )}
405
+ </Panel>
406
+ ))
407
+ ) : (
408
+ <div style={{ textAlign: 'center', padding: '40px 0' }}>
409
+ <Empty description="No Menu Items" />
410
+ </div>
411
+ )}
410
412
  </Collapse>
411
413
  </DndProvider>
412
414
  </Card>
@@ -440,7 +442,7 @@ const MenuLists = ({ model, match, relativeAdd = false, additional_queries = [],
440
442
  function panelActions(item, model, setSelectedRecord, setDrawerTitle, setDrawerVisible, deleteRecord) {
441
443
  return (
442
444
  <Space onClick={(e) => e.stopPropagation()}>
443
- {/* NEW BUTTON Add Submenu */}
445
+ <Tag color={item.is_visible === true ? 'green' : 'blue'}>{item.is_visible === true ? 'VISIBLE' : 'HIDDEN'}</Tag>{' '}
444
446
  <Button
445
447
  size="small"
446
448
  type="dashed"
@@ -459,7 +461,6 @@ function panelActions(item, model, setSelectedRecord, setDrawerTitle, setDrawerV
459
461
  <PlusCircleFilled />
460
462
  Add Sub Menu
461
463
  </Button>
462
-
463
464
  {model.ModalAddComponent && (
464
465
  <Button
465
466
  size="small"
@@ -473,8 +474,7 @@ function panelActions(item, model, setSelectedRecord, setDrawerTitle, setDrawerV
473
474
  <EditOutlined />
474
475
  </Button>
475
476
  )}
476
-
477
- {/* <Button
477
+ <Button
478
478
  size="small"
479
479
  type="default"
480
480
  onClick={() => {
@@ -484,8 +484,7 @@ function panelActions(item, model, setSelectedRecord, setDrawerTitle, setDrawerV
484
484
  }}
485
485
  >
486
486
  <CopyOutlined />
487
- </Button> */}
488
-
487
+ </Button>
489
488
  <Popconfirm title="Are you sure?" onConfirm={() => deleteRecord(item)}>
490
489
  <Button danger size="small" type="default">
491
490
  <DeleteOutlined />
@@ -160,6 +160,29 @@ class MenusAPI extends Base {
160
160
  });
161
161
  };
162
162
 
163
+ getBranches = () => {
164
+ return ApiUtils.get({
165
+ url: 'branches',
166
+ });
167
+ };
168
+
169
+ switchBranch = (formBody, dbPtr) => {
170
+ return ApiUtils.post({
171
+ url: `auth/switch-branch`,
172
+ headers: { db_ptr: dbPtr },
173
+ formBody,
174
+ });
175
+ };
176
+
177
+ getProfile = (token) => {
178
+ return ApiUtils.get({
179
+ url: 'auth/profile',
180
+ headers: {
181
+ Authorization: `Bearer ${token}`,
182
+ },
183
+ });
184
+ };
185
+
163
186
  /**
164
187
  * create menu
165
188
  */
@@ -177,28 +200,46 @@ class MenusAPI extends Base {
177
200
  * @param {*} menu
178
201
  * @returns
179
202
  */
180
- getMenus = (config) => {
203
+ getMenus = (config, dbPtr = null) => {
181
204
  // Use 'core-menus' endpoint if REACT_APP_USE_CORE_MENUS is true (used for Matria)
182
205
  const url =
183
206
  process.env.REACT_APP_USE_CORE_MENUS === 'true'
184
207
  ? 'core-menus/get-menus' // Matria
185
208
  : 'menus/get-menus'; // NURA
186
209
 
210
+ if (!dbPtr) dbPtr = localStorage.db_ptr;
187
211
  return this.get({
188
212
  url,
189
213
  config,
214
+ headers: {
215
+ db_ptr: dbPtr,
216
+ },
217
+ }).then((result) => result);
218
+ };
219
+
220
+ getMenubyUser = (user_id) => {
221
+ const url = `menus/get-menus?userId=${user_id}`;
222
+ return this.get({
223
+ url,
190
224
  }).then((result) => result);
191
225
  };
192
226
 
193
227
  // get core-menu list with submenu
194
228
  getCoreMenuLists = () => {
195
229
  const url = 'core-menus/core-menus?step=1&header_id=null';
196
-
197
230
  return this.get({
198
231
  url,
199
232
  }).then((result) => result);
200
233
  };
201
234
 
235
+ getCoreMenuByRoleId = async (role_id) => {
236
+ const url = `menus/get-menus-by-role/${role_id}`;
237
+ const result = await this.get({
238
+ url,
239
+ });
240
+ return result;
241
+ };
242
+
202
243
  getCoreMenus = () => {
203
244
  return [
204
245
  // {
@@ -286,6 +327,12 @@ class MenusAPI extends Base {
286
327
  // }
287
328
  ];
288
329
  };
330
+ // license summary api call
331
+ getSummary = () => {
332
+ return ApiUtils.get({
333
+ url: 'license/summary',
334
+ });
335
+ };
289
336
  }
290
337
 
291
338
  export default MenusAPI;
@@ -1,6 +1,6 @@
1
1
  import React, { useState, useEffect, useContext } from 'react';
2
2
  import { useLocation, useParams } from 'react-router-dom';
3
- import { Skeleton, Typography, message, Form, Input, Collapse, Checkbox } from 'antd';
3
+ import { Skeleton, Typography, message, Form, Input, Collapse, Checkbox, Tag } from 'antd';
4
4
  import { GlobalContext } from './../../../../lib';
5
5
  import { Button } from './../../../../lib';
6
6
  import { ModelsAPI, PagesAPI, RolesAPI, MenusAPI } from '../../..';
@@ -29,7 +29,9 @@ const RoleAdd = ({ model, callback, edit, formContent = {}, match, additional_qu
29
29
  formContent.attributes = {};
30
30
  }
31
31
 
32
- const [loading, setLoading] = useState(true);
32
+ const isEdit = !!(formContent.id || formContent.copy);
33
+ const [initialLoading, setInitialLoading] = useState(isEdit);
34
+ const [loading, setLoading] = useState(false);
33
35
  const [form] = Form.useForm();
34
36
  const [pages, setPages] = useState([]);
35
37
  const [models, setModels] = useState([]);
@@ -49,36 +51,43 @@ const RoleAdd = ({ model, callback, edit, formContent = {}, match, additional_qu
49
51
 
50
52
  // On component mount
51
53
  useEffect(() => {
52
- getPages();
53
- getModels();
54
- loadMenus();
55
- setShowMenus(true);
56
-
57
- // Preselect menus when editing
58
- if (formContent && formContent.menu_ids) {
59
- let menus = formContent.menu_ids;
60
-
61
- setSelectedMenus(menus);
62
- // keep original copy for deselect comparison
63
- setOriginalMenus(menus);
64
- }
54
+ const fetchData = async () => {
55
+ if (isEdit) setInitialLoading(true);
56
+ try {
57
+ await Promise.all([getPages(), getModels(), loadMenus()]);
58
+ setShowMenus(true);
59
+
60
+ // Preselect menus when editing
61
+ if (formContent && formContent.menu_ids) {
62
+ let menus = formContent.menu_ids;
63
+
64
+ setSelectedMenus(menus);
65
+ // keep original copy for deselect comparison
66
+ setOriginalMenus(menus);
67
+ }
68
+ } catch (error) {
69
+ console.error('Error fetching data:', error);
70
+ } finally {
71
+ setInitialLoading(false);
72
+ }
73
+ };
65
74
 
66
- setLoading(false);
67
- }, [formContent]);
75
+ fetchData();
76
+ }, [formContent, isEdit]);
68
77
 
69
78
  // Load pages
70
79
  const getPages = () => {
71
- PagesAPI.getPages().then((res) => setPages(res.result || []));
80
+ return PagesAPI.getPages().then((res) => setPages(res.result || []));
72
81
  };
73
82
 
74
83
  // Load models
75
84
  const getModels = () => {
76
- ModelsAPI.get().then((res) => setModels(res.result || []));
85
+ return ModelsAPI.get().then((res) => setModels(res.result || []));
77
86
  };
78
87
 
79
88
  // Load top-level menus
80
89
  const loadMenus = () => {
81
- MenusAPI.getCoreMenuLists()
90
+ return MenusAPI.getCoreMenuLists()
82
91
  .then((res) => setMenuList(res.result || []))
83
92
  .catch(console.error);
84
93
  };
@@ -156,13 +165,13 @@ const RoleAdd = ({ model, callback, edit, formContent = {}, match, additional_qu
156
165
 
157
166
  return (
158
167
  <section className="collection-add">
159
- {loading ? (
160
- <Skeleton />
168
+ {initialLoading ? (
169
+ <Skeleton active paragraph={{ rows: 12 }} />
161
170
  ) : (
162
171
  <Form initialValues={{ ...formContent }} form={form} layout="vertical" onFinish={onSubmit}>
163
172
  {/* Role Name */}
164
173
  <Form.Item name="name" label="Enter Role Name" rules={[{ required: true, message: 'Role name is required' }]}>
165
- <Input placeholder="Enter name" />
174
+ <Input placeholder="Enter name" autoocus />
166
175
  </Form.Item>
167
176
 
168
177
  {/* Description */}
@@ -180,19 +189,31 @@ const RoleAdd = ({ model, callback, edit, formContent = {}, match, additional_qu
180
189
  {/* MENU TREE */}
181
190
  {showMenus && menuList.length > 0 && (
182
191
  <div style={{ marginTop: 30 }}>
183
- <Title level={5}>Menu List</Title>
184
- <p style={{ color: '#999' }}>Choose menus and set permissions</p>
192
+ <div
193
+ style={{
194
+ display: 'flex',
195
+ justifyContent: 'space-between',
196
+ alignItems: 'center',
197
+ marginBottom: 16,
198
+ }}
199
+ >
200
+ <div>
201
+ <Title level={5} style={{ marginBottom: 0 }}>
202
+ Menu List
203
+ </Title>
204
+ <p style={{ color: '#999', marginBottom: 0 }}>Choose menus and set permissions</p>
205
+ </div>
206
+
207
+ <Form.Item style={{ marginBottom: 0 }}>
208
+ <Button loading={loading} htmlType="submit" type="primary">
209
+ Save
210
+ </Button>
211
+ </Form.Item>
212
+ </div>
185
213
 
186
214
  <MenuTree menus={menuList} selectedMenus={selectedMenus} toggleMenu={toggleMenu} />
187
215
  </div>
188
216
  )}
189
-
190
- {/* Submit Button */}
191
- <Form.Item style={{ marginTop: 20 }}>
192
- <Button loading={loading} htmlType="submit" type="primary">
193
- Save
194
- </Button>
195
- </Form.Item>
196
217
  </Form>
197
218
  )}
198
219
  </section>
@@ -248,32 +269,41 @@ const MenuTree = ({ menus, selectedMenus, toggleMenu, parentId = null }) => {
248
269
  if (children.length === 0) {
249
270
  return (
250
271
  <div
251
- key={menu.id}
252
272
  style={{
273
+ justifyContent: 'space-between',
274
+ display: 'flex',
275
+ alignItems: 'center',
253
276
  border: '1px solid rgba(198, 195, 195, 0.85)',
254
277
  // borderRadius: 6,
255
278
  padding: '12px 16px',
256
279
  marginBottom: 6,
257
280
  background: '#fff',
258
- display: 'flex',
259
- alignItems: 'center',
260
- gap: 8,
261
281
  }}
262
282
  >
263
- <Checkbox
264
- checked={selectedMenus.includes(menu.id)}
265
- onChange={(e) => {
266
- const checked = e.target.checked;
267
-
268
- toggleMenu(menu.id, checked);
269
-
270
- // ✅ FORCE parent selection
271
- if (checked && parentId) {
272
- toggleMenu(parentId, true);
273
- }
283
+ <div
284
+ key={menu.id}
285
+ style={{
286
+ display: 'flex',
287
+ alignItems: 'center',
288
+ gap: 8,
274
289
  }}
275
- />
276
- <span>{menu.title || menu.caption}</span>
290
+ >
291
+ <Checkbox
292
+ checked={selectedMenus.includes(menu.id)}
293
+ onChange={(e) => {
294
+ const checked = e.target.checked;
295
+
296
+ toggleMenu(menu.id, checked);
297
+
298
+ // FORCE parent selection
299
+ if (checked && parentId) {
300
+ toggleMenu(parentId, true);
301
+ }
302
+ }}
303
+ />
304
+ <span>{menu.caption}</span>
305
+ </div>
306
+ <Tag color={menu.is_visible === true ? 'green' : 'blue'}>{menu.is_visible === true ? 'VISIBLE' : 'HIDDEN'}</Tag>{' '}
277
307
  </div>
278
308
  );
279
309
  }
@@ -287,16 +317,19 @@ const MenuTree = ({ menus, selectedMenus, toggleMenu, parentId = null }) => {
287
317
  <Panel
288
318
  key={menu.id}
289
319
  header={
290
- <div
291
- style={{
292
- display: 'flex',
293
- alignItems: 'center',
294
- gap: 8,
295
- }}
296
- onClick={(e) => e.stopPropagation()}
297
- >
298
- <Checkbox checked={parentChecked} indeterminate={parentIndeterminate} onChange={(e) => onParentChange(e.target.checked)} />
299
- <span>{menu.title || menu.caption}</span>
320
+ <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
321
+ <div
322
+ style={{
323
+ display: 'flex',
324
+ alignItems: 'center',
325
+ gap: 8,
326
+ }}
327
+ onClick={(e) => e.stopPropagation()}
328
+ >
329
+ <Checkbox checked={parentChecked} indeterminate={parentIndeterminate} onChange={(e) => onParentChange(e.target.checked)} />
330
+ <span>{menu.caption}</span>
331
+ </div>
332
+ <Tag color={menu.is_visible === true ? 'green' : 'blue'}>{menu.is_visible === true ? 'VISIBLE' : 'HIDDEN'}</Tag>{' '}
300
333
  </div>
301
334
  }
302
335
  >
@@ -331,7 +331,7 @@ const RoleList = ({ model, match, relativeAdd = false, additional_queries = [],
331
331
  {/* Table Header Ends */}
332
332
 
333
333
  {loading ? (
334
- <Skeleton />
334
+ <Skeleton active paragraph={{ rows: 10 }} />
335
335
  ) : (
336
336
  <>
337
337
  <>
@@ -1,8 +1,9 @@
1
1
  import React, { useState, useEffect, useRef } from 'react';
2
2
 
3
3
  import { Modal, Tabs, Input, Form, Row, Col, message, Checkbox, Select } from 'antd';
4
- import { useTranslation, Button } from './../../../../lib/';
4
+ import { useTranslation, Button, CountryPhoneInput, phoneValidator as libPhoneValidator, formatPhoneForForm } from './../../../../lib/';
5
5
  import { UsersAPI } from '../../..';
6
+ import { formatPhoneWithCountryCode } from '../../../../lib/utils/common/common.utils';
6
7
 
7
8
  const StaffAdd = ({ visible, onCancel, staffId, staffData, onSuccess }) => {
8
9
  const [form] = Form.useForm();
@@ -61,18 +62,6 @@ const StaffAdd = ({ visible, onCancel, staffId, staffData, onSuccess }) => {
61
62
  }
62
63
  }, [visible]);
63
64
 
64
- const phoneValidator = (_, value) => {
65
- if (!value) {
66
- return Promise.resolve(); // not required
67
- }
68
-
69
- if (!/^\d{10}$/.test(value)) {
70
- return Promise.reject('Phone number must be 10 digits');
71
- }
72
-
73
- return Promise.resolve();
74
- };
75
-
76
65
  /** -------------------------------
77
66
  * API CALL – Designations
78
67
  * ------------------------------- */
@@ -201,8 +190,8 @@ const StaffAdd = ({ visible, onCancel, staffId, staffData, onSuccess }) => {
201
190
  shortName: data.shortName,
202
191
  description: data.description,
203
192
  designation: data.designationPtr,
204
- phone1: data.phone || data.mobile,
205
- phone2: data.alternateMobile,
193
+ phone1: formatPhoneForForm(data.phone || data.mobile),
194
+ phone2: formatPhoneForForm(data.alternateMobile),
206
195
  email1: data.email,
207
196
  email2: data.alternateEmail,
208
197
  slno: data.slNo,
@@ -223,14 +212,17 @@ const StaffAdd = ({ visible, onCancel, staffId, staffData, onSuccess }) => {
223
212
  const handleFinish = async (values) => {
224
213
  setLoading(true);
225
214
 
215
+ let phone1Value = formatPhoneWithCountryCode(values.phone1);
216
+ let phone2Value = formatPhoneWithCountryCode(values.phone2);
217
+
226
218
  const payload = {
227
219
  id: values.id,
228
220
  shortName: values.shortName,
229
221
  description: values.description,
230
222
  designationPtr: values.designation ?? existing.designationPtr ?? null,
231
- phone: values.phone1 ?? existing.phone ?? null,
232
- mobile: values.phone1 ?? existing.mobile ?? null,
233
- alternateMobile: values.phone2 ?? existing.alternateMobile ?? null,
223
+ phone: phone1Value ?? existing.phone ?? null,
224
+ mobile: phone1Value ?? existing.mobile ?? null,
225
+ alternateMobile: phone2Value ?? existing.alternateMobile ?? null,
234
226
  email: values.email1 ?? existing.email ?? null,
235
227
  alternateEmail: values.email2 ?? existing.alternateEmail ?? null,
236
228
  remarks: values.remarks ?? existing.remarks ?? null,
@@ -331,26 +323,22 @@ const StaffAdd = ({ visible, onCancel, staffId, staffData, onSuccess }) => {
331
323
  </Form.Item>
332
324
  </Col> */}
333
325
  <Col span={6}>
334
- <Form.Item label="Phone Number" name="phone1" rules={[{ validator: phoneValidator }]}>
335
- <Input
336
- maxLength={10}
337
- autoComplete="off"
338
- placeholder="Enter Phone Number"
339
- inputMode="numeric"
340
- onChange={(e) => (e.target.value = e.target.value.replace(/\D/g, ''))}
326
+ <Form.Item label="Phone Number" name="phone1" validateTrigger="onBlur" rules={[{ validator: libPhoneValidator }]}>
327
+ <CountryPhoneInput
328
+ defaultCountryCode={process.env.REACT_APP_COUNTRYCODE}
329
+ enableSearch
330
+ inputStyle={{ width: '100%' }}
341
331
  onKeyDown={handleEnterKey}
342
332
  />
343
333
  </Form.Item>
344
334
  </Col>
345
335
 
346
336
  <Col span={6}>
347
- <Form.Item label="Alternate Phone Number" name="phone2" rules={[{ validator: phoneValidator }]}>
348
- <Input
349
- maxLength={10}
350
- placeholder="Enter Phone Number"
351
- autoComplete="off"
352
- inputMode="numeric"
353
- onChange={(e) => (e.target.value = e.target.value.replace(/\D/g, ''))}
337
+ <Form.Item label="Alternate Phone Number" name="phone2" validateTrigger="onBlur" rules={[{ validator: libPhoneValidator }]}>
338
+ <CountryPhoneInput
339
+ defaultCountryCode={process.env.REACT_APP_COUNTRYCODE}
340
+ enableSearch
341
+ inputStyle={{ width: '100%' }}
354
342
  onKeyDown={handleEnterKey}
355
343
  />
356
344
  </Form.Item>