@esvndev/es-react-template-chat 0.0.77 → 0.0.79

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/dist/index.mjs CHANGED
@@ -5,7 +5,7 @@ import '@styles/base/pages/app-chat.scss';
5
5
  import '@styles/base/pages/app-chat-list.scss';
6
6
  import * as ReactDOM from 'react-dom';
7
7
  import ReactDOM__default from 'react-dom';
8
- import { useAppDispatch, useAppSelector } from '@src/redux/configureStore';
8
+ import { useAppDispatch as useAppDispatch$1, useAppSelector } from '@src/redux/configureStore';
9
9
  import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
10
10
  import '@styles/react/libs/editor/editor.scss';
11
11
  import { useTranslation } from 'react-i18next';
@@ -27388,7 +27388,7 @@ const formatDateToMonthShort = (value, toTimeForCurrentDay = true) => {
27388
27388
  return new Intl.DateTimeFormat('vi-VN', formatting).format(new Date(value));
27389
27389
  };
27390
27390
 
27391
- const getToken = () => {
27391
+ const getToken$1 = () => {
27392
27392
  let accessToken = localStorage.getItem('access_token');
27393
27393
  if (!accessToken) {
27394
27394
  const userData = localStorage.getItem('userData');
@@ -27423,7 +27423,7 @@ const mapPinRecordToMessage = (record) => {
27423
27423
  }
27424
27424
  return record;
27425
27425
  };
27426
- const initialState = {
27426
+ const initialState$1 = {
27427
27427
  checkInit: true,
27428
27428
  chatRoomId: undefined,
27429
27429
  contactId: undefined,
@@ -27447,7 +27447,7 @@ const get_history = createAsyncThunk(CHAT.ACTION_TYPES.GET_HISTORY, async (param
27447
27447
  const response = await fetch(`${CHAT.URL_API.GET_HISTORY_API}?${queryString}`, {
27448
27448
  method: 'GET',
27449
27449
  headers: {
27450
- 'Authorization': `Bearer ${getToken()}`,
27450
+ 'Authorization': `Bearer ${getToken$1()}`,
27451
27451
  'Content-Type': 'application/json'
27452
27452
  }
27453
27453
  });
@@ -27467,7 +27467,7 @@ const get_message_by_group_cursor = createAsyncThunk(CHAT.ACTION_TYPES.GET_MESSA
27467
27467
  const response = await fetch(`${CHAT.URL_API.GET_MESSAGE_BY_GROUP_CURSOR_API}/${params.chatRoomId}?${queryString}`, {
27468
27468
  method: 'GET',
27469
27469
  headers: {
27470
- 'Authorization': `Bearer ${getToken()}`,
27470
+ 'Authorization': `Bearer ${getToken$1()}`,
27471
27471
  'Content-Type': 'application/json'
27472
27472
  }
27473
27473
  });
@@ -27487,7 +27487,7 @@ const get_history_active = createAsyncThunk(CHAT.ACTION_TYPES.GET_HISTORY_ACTIVE
27487
27487
  const response = await fetch(`${CHAT.URL_API.GET_HISTORY_API}?${queryString}`, {
27488
27488
  method: 'GET',
27489
27489
  headers: {
27490
- 'Authorization': `Bearer ${getToken()}`,
27490
+ 'Authorization': `Bearer ${getToken$1()}`,
27491
27491
  'Content-Type': 'application/json'
27492
27492
  }
27493
27493
  });
@@ -27507,7 +27507,7 @@ const get_info = createAsyncThunk(CHAT.ACTION_TYPES.GET_INFO, async (params, thu
27507
27507
  const response = await fetch(`${CHAT.URL_API.GET_INFO_API}?${queryString}`, {
27508
27508
  method: 'GET',
27509
27509
  headers: {
27510
- 'Authorization': `Bearer ${getToken()}`,
27510
+ 'Authorization': `Bearer ${getToken$1()}`,
27511
27511
  'Content-Type': 'application/json'
27512
27512
  }
27513
27513
  });
@@ -27526,7 +27526,7 @@ const groups = createAsyncThunk(CHAT.ACTION_TYPES.GROUP, async (params, thunkAPI
27526
27526
  const response = await fetch(CHAT.URL_API.GROUP_API, {
27527
27527
  method: 'POST',
27528
27528
  headers: {
27529
- 'Authorization': `Bearer ${getToken()}`,
27529
+ 'Authorization': `Bearer ${getToken$1()}`,
27530
27530
  'Content-Type': 'application/json'
27531
27531
  },
27532
27532
  body: JSON.stringify(params)
@@ -27546,7 +27546,7 @@ const addMemberGroup = createAsyncThunk(CHAT.ACTION_TYPES.MEMBER_GROUP, async (p
27546
27546
  const response = await fetch(CHAT.URL_API.ADD_MEMBER_GROUP, {
27547
27547
  method: 'POST',
27548
27548
  headers: {
27549
- 'Authorization': `Bearer ${getToken()}`,
27549
+ 'Authorization': `Bearer ${getToken$1()}`,
27550
27550
  'Content-Type': 'application/json'
27551
27551
  },
27552
27552
  body: JSON.stringify(params)
@@ -27566,7 +27566,7 @@ const sen_message = createAsyncThunk(CHAT.ACTION_TYPES.SEN_MESSAGE, async (param
27566
27566
  const response = await fetch(`${CHAT.URL_API.SEN_MESSAGE_API}/${params.id}`, {
27567
27567
  method: 'POST',
27568
27568
  headers: {
27569
- 'Authorization': `Bearer ${getToken()}`,
27569
+ 'Authorization': `Bearer ${getToken$1()}`,
27570
27570
  'Content-Type': 'application/json'
27571
27571
  },
27572
27572
  body: JSON.stringify({ ...params.formData, tickerDto: params.tickerDto })
@@ -27586,7 +27586,7 @@ const delete_message = createAsyncThunk(CHAT.ACTION_TYPES.DELETE_MESSAGE, async
27586
27586
  const response = await fetch(`${CHAT.URL_API.MESSAGE_API}/${params.chatRoomId}/delete-message/${params.id}`, {
27587
27587
  method: 'DELETE',
27588
27588
  headers: {
27589
- 'Authorization': `Bearer ${getToken()}`,
27589
+ 'Authorization': `Bearer ${getToken$1()}`,
27590
27590
  'Content-Type': 'application/json'
27591
27591
  }
27592
27592
  });
@@ -27605,7 +27605,7 @@ const recall_message = createAsyncThunk(CHAT.ACTION_TYPES.RECALL_MESSAGE, async
27605
27605
  const response = await fetch(`${CHAT.URL_API.MESSAGE_API}/${params.chatRoomId}/recall-message/${params.id}`, {
27606
27606
  method: 'PUT',
27607
27607
  headers: {
27608
- 'Authorization': `Bearer ${getToken()}`,
27608
+ 'Authorization': `Bearer ${getToken$1()}`,
27609
27609
  'Content-Type': 'application/json'
27610
27610
  },
27611
27611
  body: JSON.stringify({})
@@ -27625,7 +27625,7 @@ const update_group_avatar = createAsyncThunk(CHAT.ACTION_TYPES.UPDATE_GROUP_AVAT
27625
27625
  const response = await fetch(CHAT.URL_API.UPDATE_GROUP_AVATAR_API, {
27626
27626
  method: 'PUT',
27627
27627
  headers: {
27628
- 'Authorization': `Bearer ${getToken()}`,
27628
+ 'Authorization': `Bearer ${getToken$1()}`,
27629
27629
  'Content-Type': 'application/json'
27630
27630
  },
27631
27631
  body: JSON.stringify(params)
@@ -27646,7 +27646,7 @@ const get_message_by_group = createAsyncThunk(CHAT.ACTION_TYPES.GET_MESSAGE_BY_G
27646
27646
  const response = await fetch(`${CHAT.URL_API.GET_MESSAGE_BY_GROUP_API}/${params.chatRoomId}?${queryString}`, {
27647
27647
  method: 'GET',
27648
27648
  headers: {
27649
- 'Authorization': `Bearer ${getToken()}`,
27649
+ 'Authorization': `Bearer ${getToken$1()}`,
27650
27650
  'Content-Type': 'application/json'
27651
27651
  }
27652
27652
  });
@@ -27666,7 +27666,7 @@ const get_message_by_contact = createAsyncThunk(CHAT.ACTION_TYPES.GET_MESSAGE_BY
27666
27666
  const response = await fetch(`${CHAT.URL_API.GET_MESSAGE_BY_CONTACT_API}/${params.chatRoomId}?${queryString}`, {
27667
27667
  method: 'GET',
27668
27668
  headers: {
27669
- 'Authorization': `Bearer ${getToken()}`,
27669
+ 'Authorization': `Bearer ${getToken$1()}`,
27670
27670
  'Content-Type': 'application/json'
27671
27671
  }
27672
27672
  });
@@ -27685,7 +27685,7 @@ const contact_add = createAsyncThunk(CHAT.ACTION_TYPES.CONTACT_ADD, async (param
27685
27685
  const response = await fetch(CHAT.URL_API.CONTACT_ADD_API, {
27686
27686
  method: 'POST',
27687
27687
  headers: {
27688
- 'Authorization': `Bearer ${getToken()}`,
27688
+ 'Authorization': `Bearer ${getToken$1()}`,
27689
27689
  'Content-Type': 'application/json'
27690
27690
  },
27691
27691
  body: JSON.stringify(params)
@@ -27705,7 +27705,7 @@ const connectChatRoomMemberApi = createAsyncThunk(CHAT.ACTION_TYPES.CONNECT_CHAT
27705
27705
  const response = await fetch(CHAT.URL_API.CONNECT_CHAT_ROOM_MEMBER_API, {
27706
27706
  method: 'POST',
27707
27707
  headers: {
27708
- 'Authorization': `Bearer ${getToken()}`,
27708
+ 'Authorization': `Bearer ${getToken$1()}`,
27709
27709
  'Content-Type': 'application/json'
27710
27710
  },
27711
27711
  body: JSON.stringify(params)
@@ -27725,7 +27725,7 @@ const get_profile = createAsyncThunk(CHAT.ACTION_TYPES.GET_PROFILE, async (_, th
27725
27725
  const response = await fetch(CHAT.URL_API.GET_PROFILE, {
27726
27726
  method: 'GET',
27727
27727
  headers: {
27728
- 'Authorization': `Bearer ${getToken()}`,
27728
+ 'Authorization': `Bearer ${getToken$1()}`,
27729
27729
  'Content-Type': 'application/json'
27730
27730
  }
27731
27731
  });
@@ -27745,7 +27745,7 @@ const get_users = createAsyncThunk(CHAT.ACTION_TYPES.GET_USERS, async (params, t
27745
27745
  const response = await fetch(`${CHAT.URL_API.GET_USERS}?${queryString}`, {
27746
27746
  method: 'GET',
27747
27747
  headers: {
27748
- 'Authorization': `Bearer ${getToken()}`,
27748
+ 'Authorization': `Bearer ${getToken$1()}`,
27749
27749
  'Content-Type': 'application/json'
27750
27750
  }
27751
27751
  });
@@ -27765,7 +27765,7 @@ const get_contact = createAsyncThunk(CHAT.ACTION_TYPES.GET_CONTACT, async (param
27765
27765
  const response = await fetch(`${CHAT.URL_API.GET_CONTACT_API}?${queryString}`, {
27766
27766
  method: 'GET',
27767
27767
  headers: {
27768
- 'Authorization': `Bearer ${getToken()}`,
27768
+ 'Authorization': `Bearer ${getToken$1()}`,
27769
27769
  'Content-Type': 'application/json'
27770
27770
  }
27771
27771
  });
@@ -27784,7 +27784,7 @@ const update_chat_room_member = createAsyncThunk(CHAT.ACTION_TYPES.CHAT_ROOM_MEM
27784
27784
  const response = await fetch(`${CHAT.URL_API.CHAT_ROOM_MEMBER_API}/${params}`, {
27785
27785
  method: 'PUT',
27786
27786
  headers: {
27787
- 'Authorization': `Bearer ${getToken()}`,
27787
+ 'Authorization': `Bearer ${getToken$1()}`,
27788
27788
  'Content-Type': 'application/json'
27789
27789
  },
27790
27790
  body: JSON.stringify({})
@@ -27805,7 +27805,7 @@ const getPagingEmployeeApi = createAsyncThunk(CHAT.ACTION_TYPES.GET_PAGING_EMPLO
27805
27805
  const response = await fetch(`${CHAT.URL_API.GET_PAGING_EMPLOYEE_API}?${queryString}`, {
27806
27806
  method: 'GET',
27807
27807
  headers: {
27808
- 'Authorization': `Bearer ${getToken()}`,
27808
+ 'Authorization': `Bearer ${getToken$1()}`,
27809
27809
  'Content-Type': 'application/json'
27810
27810
  }
27811
27811
  });
@@ -27824,7 +27824,7 @@ const pinMessageChatRoomApi = createAsyncThunk(CHAT.ACTION_TYPES.PIN_MESSAGE_CHA
27824
27824
  const response = await fetch(`${CHAT.URL_API.PIN_MESSAGE_CHAT_ROOM_API}/${params.id}`, {
27825
27825
  method: 'POST',
27826
27826
  headers: {
27827
- 'Authorization': `Bearer ${getToken()}`,
27827
+ 'Authorization': `Bearer ${getToken$1()}`,
27828
27828
  'Content-Type': 'application/json'
27829
27829
  },
27830
27830
  body: JSON.stringify(params)
@@ -27844,7 +27844,7 @@ const getPinMessageChatRoomApi = createAsyncThunk(CHAT.ACTION_TYPES.GET_PIN_MESS
27844
27844
  const response = await fetch(`${CHAT.URL_API.GET_PIN_MESSAGE_CHAT_ROOM_API}/${params}`, {
27845
27845
  method: 'GET',
27846
27846
  headers: {
27847
- 'Authorization': `Bearer ${getToken()}`,
27847
+ 'Authorization': `Bearer ${getToken$1()}`,
27848
27848
  'Content-Type': 'application/json'
27849
27849
  }
27850
27850
  });
@@ -27863,7 +27863,7 @@ const deletePinMessageApi = createAsyncThunk(CHAT.ACTION_TYPES.DELETE_PIN_MESSAG
27863
27863
  const response = await fetch(`${CHAT.URL_API.PIN_MESSAGE_CHAT_ROOM_API}/${pinId}`, {
27864
27864
  method: 'DELETE',
27865
27865
  headers: {
27866
- 'Authorization': `Bearer ${getToken()}`,
27866
+ 'Authorization': `Bearer ${getToken$1()}`,
27867
27867
  'Content-Type': 'application/json'
27868
27868
  }
27869
27869
  });
@@ -27882,7 +27882,7 @@ const updateGroupTagApi = createAsyncThunk(CHAT.ACTION_TYPES.UPDATE_GROUP_TAG, a
27882
27882
  const response = await fetch(CHAT.URL_API.UPDATE_GROUP_TAG_API, {
27883
27883
  method: 'PUT',
27884
27884
  headers: {
27885
- 'Authorization': `Bearer ${getToken()}`,
27885
+ 'Authorization': `Bearer ${getToken$1()}`,
27886
27886
  'Content-Type': 'application/json'
27887
27887
  },
27888
27888
  body: JSON.stringify(params)
@@ -27902,7 +27902,7 @@ const createReminderApi = createAsyncThunk(CHAT.ACTION_TYPES.CREATE_REMINDER, as
27902
27902
  const response = await fetch(CHAT.URL_API.CREATE_REMINDER_API, {
27903
27903
  method: 'POST',
27904
27904
  headers: {
27905
- 'Authorization': `Bearer ${getToken()}`,
27905
+ 'Authorization': `Bearer ${getToken$1()}`,
27906
27906
  'Content-Type': 'application/json'
27907
27907
  },
27908
27908
  body: JSON.stringify(params)
@@ -27919,7 +27919,7 @@ const createReminderApi = createAsyncThunk(CHAT.ACTION_TYPES.CREATE_REMINDER, as
27919
27919
  });
27920
27920
  const appChatSlice = createSlice({
27921
27921
  name: 'appChat',
27922
- initialState,
27922
+ initialState: initialState$1,
27923
27923
  reducers: {
27924
27924
  selectChat(state, action) {
27925
27925
  state.chatRoomId = action.payload;
@@ -28284,7 +28284,7 @@ const { selectChat, selectContact, selectType, selectActive, selectLoadChat, sel
28284
28284
  getNotification, removeChatRoom, setListChatType, setArchive, setApproveStatus, setHistory, editGroupName, setScroll, updateMemberGroup, setMessageByGroup, leaveGroup, getGeneralGroup, setGeneralGroup, editGroupAvatar, editGroupTag, addPinnedMessage, userTyping } = appChatSlice.actions;
28285
28285
 
28286
28286
  const useChat = () => {
28287
- const dispatch = useAppDispatch();
28287
+ const dispatch = useAppDispatch$1();
28288
28288
  const { active, checkInit, chatRoomId, userLogin, listContact, contactId, typeChat, loadChat, messageByGroup, listHistory, listChatType, archiveStore, checkScroll, listGeneralGroup, pinnedMessages, typingUsers } = useAppSelector((state) => state.chat);
28289
28289
  const getHistoryApi = (params) => {
28290
28290
  return dispatch(get_history(params));
@@ -36599,6 +36599,99 @@ var SvgArrowRight = function (_a) {
36599
36599
  React.createElement("path", { d: "M5 12h14M12 5l7 7-7 7" })));
36600
36600
  };
36601
36601
 
36602
+ var SvgBecoxyApplication = function (_a) {
36603
+ var title = _a.title, titleId = _a.titleId, props = __rest(_a, ["title", "titleId"]);
36604
+ return (React.createElement("svg", __assign$1({ width: props.fontSize || 24, height: props.fontSize || 24, viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", strokeWidth: props.strokeWidth || 1.5, "aria-labelledby": titleId }, props),
36605
+ title ? React.createElement("title", { id: titleId }, title) : null,
36606
+ React.createElement("g", { clipPath: "url(#becoxy-application_svg__a)", fill: props.color || "currentColor" },
36607
+ React.createElement("path", { d: "M3.692 5.077H14.77a.462.462 0 1 0 0-.923H3.692a.462.462 0 1 0 0 .923ZM3.692 7.846H14.77a.462.462 0 1 0 0-.923H3.692a.462.462 0 1 0 0 .923ZM3.692 10.615H14.77a.462.462 0 0 0 0-.923H3.692a.462.462 0 1 0 0 .923ZM15.23 12.923a.462.462 0 0 0-.46-.462H3.691a.462.462 0 0 0 0 .923H14.77a.462.462 0 0 0 .462-.461Z" }),
36608
+ React.createElement("path", { d: "M22.774 3.043 20.18 2.09a.462.462 0 0 0-.593.275L17.538 7.96V1.384a.462.462 0 0 0-.461-.461H1.385a.462.462 0 0 0-.462.461v21.231c0 .255.207.462.462.462h15.692a.462.462 0 0 0 .461-.462V18.7c.36-.98 5.136-14.04 5.51-15.065a.462.462 0 0 0-.274-.591Zm-2.479.073 1.728.634-.633 1.733-1.73-.634.635-1.733Zm-3.662 15.37-1.733-.635 4.443-12.135 1.73.633-4.44 12.137Zm-.65.745-.86.696-.209-1.087 1.07.391ZM1.847 22.154V1.846h14.77v8.636c-2.924 7.987-2.757 7.5-2.767 7.6a.452.452 0 0 0 .005.125l.507 2.649c.066.341.473.49.743.272l1.511-1.22v2.246H1.846Z" }),
36609
+ React.createElement("path", { d: "M12.279 20.068c-.457.197-1.035.324-1.225.276a.756.756 0 0 0-.398-.483c-.508-.247-1.224.087-1.915.41-.217.1-.44.205-.556.237-.415.115-1.433.045-1.732-.105a.462.462 0 0 0-.91.023.7.7 0 0 0 .249.637c.547.482 2.097.484 2.638.335.19-.052.427-.163.701-.29.276-.13.816-.382 1.066-.41.073.2.216.36.41.459.632.318 1.72-.105 2.037-.242a.462.462 0 0 0-.365-.847Z" })),
36610
+ React.createElement("defs", null,
36611
+ React.createElement("clipPath", { id: "becoxy-application_svg__a" },
36612
+ React.createElement("path", { fill: "#fff", d: "M0 0h24v24H0z" })))));
36613
+ };
36614
+
36615
+ var SvgBecoxyBusinessMan = function (_a) {
36616
+ var title = _a.title, titleId = _a.titleId, props = __rest(_a, ["title", "titleId"]);
36617
+ return (React.createElement("svg", __assign$1({ width: props.fontSize || 24, height: props.fontSize || 24, viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", strokeWidth: props.strokeWidth || 1.5, "aria-labelledby": titleId }, props),
36618
+ title ? React.createElement("title", { id: titleId }, title) : null,
36619
+ React.createElement("path", { d: "M10.5 16.875H9.375v-.75A1.125 1.125 0 0 0 8.25 15h-1.5a1.125 1.125 0 0 0-1.125 1.125v.75H4.5A1.125 1.125 0 0 0 3.375 18v4.5A1.125 1.125 0 0 0 4.5 23.625h6a1.125 1.125 0 0 0 1.125-1.125V18a1.125 1.125 0 0 0-1.125-1.125Zm-4.125-.75a.375.375 0 0 1 .375-.375h1.5a.375.375 0 0 1 .375.375v.75h-2.25v-.75Zm4.5 6.375a.375.375 0 0 1-.375.375h-6a.375.375 0 0 1-.375-.375v-2.821l1.125.45v.308a.375.375 0 0 0 .75 0v-.187h3v.188a.375.375 0 0 0 .75 0v-.31l1.125-.45V22.5Zm0-3.629-1.125.45v-.009a.375.375 0 0 0-.75 0v.188H6v-.188a.375.375 0 0 0-.75 0v.01l-1.125-.45V18a.375.375 0 0 1 .375-.375h6a.375.375 0 0 1 .375.375v.871ZM17.759 4.168a2.25 2.25 0 1 0-3.268 0A3.377 3.377 0 0 0 11.626 7.5v5.625a1.5 1.5 0 0 0 1.5 1.5h.375v6.82a1.124 1.124 0 0 0-.75 1.055v.75a.375.375 0 0 0 .375.375h6a.375.375 0 0 0 .375-.375v-.75a1.125 1.125 0 0 0-.75-1.056v-6.819h.375a1.5 1.5 0 0 0 1.5-1.5V7.5a3.377 3.377 0 0 0-2.866-3.332Zm-1.634-3.043a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3Zm-3 12.75a.75.75 0 0 1-.75-.75H13.5v.75h-.375Zm2.625 9H13.5V22.5a.375.375 0 0 1 .375-.375h1.875v.75Zm.375-9.375a.375.375 0 0 0-.375.375v7.5h-1.5v-9.75H18v9.75h-1.5v-7.5a.375.375 0 0 0-.375-.375Zm2.625 9.375H16.5v-.75h1.875a.375.375 0 0 1 .375.375v.375Zm.375-9h-.375v-.75h1.125a.75.75 0 0 1-.75.75Zm.75-1.5H18.75V7.5a.375.375 0 1 0-.75 0v3.375h-3.75V7.5a.375.375 0 1 0-.75 0v4.875h-1.125V7.5A2.628 2.628 0 0 1 15 4.875h2.25A2.628 2.628 0 0 1 19.875 7.5v4.875Z", fill: props.color || "currentColor" })));
36620
+ };
36621
+
36622
+ var SvgBecoxyCar = function (_a) {
36623
+ var title = _a.title, titleId = _a.titleId, props = __rest(_a, ["title", "titleId"]);
36624
+ return (React.createElement("svg", __assign$1({ width: props.fontSize || 24, height: props.fontSize || 24, viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", strokeWidth: props.strokeWidth || 1.5, "aria-labelledby": titleId }, props),
36625
+ title ? React.createElement("title", { id: titleId }, title) : null,
36626
+ React.createElement("path", { d: "M4.5 13A2.503 2.503 0 0 0 2 15.5C2 16.878 3.122 18 4.5 18S7 16.878 7 15.5 5.878 13 4.5 13Zm0 4c-.827 0-1.5-.673-1.5-1.5S3.673 14 4.5 14s1.5.673 1.5 1.5S5.327 17 4.5 17ZM19.5 13a2.503 2.503 0 0 0-2.5 2.5c0 1.378 1.122 2.5 2.5 2.5s2.5-1.122 2.5-2.5-1.122-2.5-2.5-2.5Zm0 4c-.827 0-1.5-.673-1.5-1.5s.673-1.5 1.5-1.5 1.5.673 1.5 1.5-.673 1.5-1.5 1.5Z", fill: props.color || "currentColor" }),
36627
+ React.createElement("path", { d: "M21 10h-.846c-.309 0-.612-.106-.854-.3l-3.94-3.152A2.514 2.514 0 0 0 13.798 6H6.57c-.838 0-1.615.416-2.08 1.113l-.851 1.278A1.369 1.369 0 0 1 2.5 9 2.503 2.503 0 0 0 0 11.5v2C0 14.878 1.122 16 2.5 16a.5.5 0 0 0 0-1c-.827 0-1.5-.673-1.5-1.5v-2c0-.827.673-1.5 1.5-1.5.794 0 1.53-.394 1.971-1.055l.851-1.277A1.499 1.499 0 0 1 6.57 7h7.228c.34 0 .672.117.938.329l3.94 3.15c.417.336.943.52 1.479.52H21c1.467 0 2 1.496 2 2.5 0 .986-.754 1.5-1.5 1.5a.5.5 0 0 0 0 1C22.925 16 24 14.926 24 13.5c0-1.697-1.051-3.5-3-3.5Z", fill: props.color || "currentColor" }),
36628
+ React.createElement("path", { d: "M17.5 15h-11a.5.5 0 0 0 0 1h11a.5.5 0 0 0 0-1ZM16.5 10H12V8.5a.5.5 0 0 0-1 0v2a.5.5 0 0 0 .5.5h5a.5.5 0 0 0 0-1ZM9.5 10H6.31l.64-1.276a.5.5 0 0 0-.896-.447l-1 2A.498.498 0 0 0 5.5 11h4a.5.5 0 0 0 0-1ZM13.5 12h-1a.5.5 0 0 0 0 1h1a.5.5 0 0 0 0-1Z", fill: props.color || "currentColor" })));
36629
+ };
36630
+
36631
+ var SvgBecoxyLateEarly = function (_a) {
36632
+ var title = _a.title, titleId = _a.titleId, props = __rest(_a, ["title", "titleId"]);
36633
+ return (React.createElement("svg", __assign$1({ width: props.fontSize || 24, height: props.fontSize || 24, viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", strokeWidth: props.strokeWidth || 1.5, "aria-labelledby": titleId }, props),
36634
+ title ? React.createElement("title", { id: titleId }, title) : null,
36635
+ React.createElement("g", { clipPath: "url(#becoxy-late-early_svg__a)", fill: props.color || "currentColor" },
36636
+ React.createElement("path", { d: "M16.539 6.252c1.217 0 2.207-.99 2.207-2.207 0-1.218-.99-2.207-2.207-2.207-1.218 0-2.207.99-2.207 2.207 0 1.218.99 2.207 2.207 2.207Zm0-3.408c.66 0 1.2.54 1.2 1.201 0 .66-.54 1.201-1.2 1.201a1.2 1.2 0 1 1 0-2.402Z" }),
36637
+ React.createElement("path", { d: "M23.16 4.304a1.41 1.41 0 0 0-1.875.6v.003s0 .004-.003.004l-1.137 2.214-1.456-.366a2.015 2.015 0 0 0-.718-.05l-2.885.345h-.003a1.542 1.542 0 0 0-.772.319l-4.813 3.753h-.003c-.292.232-.477.56-.523.926-.048.369.053.735.285 1.026.278.356.694.544 1.113.544.295 0 .594-.094.842-.286l3.01-2.344.381 3.358v.006c.017.135.047.265.091.39l.01.04c.06.198.03.302-.114.61l-1.362 2.633c-.027.05-.077.08-.124.074l-2.73-.295h-.004a1.56 1.56 0 0 0-1.285.456c-.325.335-.48.792-.422 1.258.09.734.67 1.318 1.382 1.392h.003l3.381.369a2.303 2.303 0 0 0 2.274-1.224l1.604-3.096 2.663 1.734-.147 3.676v.02c0 .198.023.37.07.523.074.245.218.474.413.654.295.279.687.43 1.08.43.17 0 .338-.027.503-.087a1.62 1.62 0 0 0 1.03-1.154 1.29 1.29 0 0 0 .026-.201l.004-.03V22.5l.178-4.172a2.304 2.304 0 0 0-1.043-2.013l-2.043-1.328a.145.145 0 0 1-.057-.097l-.59-5.079.69.181h.004a1.98 1.98 0 0 0 2.257-1.026l1.429-2.794v-.004s0-.003.003-.003a1.404 1.404 0 0 0-.617-1.861ZM13.54 20.29l-3.381-.369h-.007c-.238-.023-.456-.255-.49-.517a.518.518 0 0 1 .145-.429.557.557 0 0 1 .463-.158l2.726.292a1.146 1.146 0 0 0 1.127-.614l1.366-2.643c0-.003 0-.003.003-.007 0-.003.003-.006.003-.01a.287.287 0 0 0 .017-.036l.946.617-1.647 3.186a1.29 1.29 0 0 1-1.27.688Zm6.796-11.274-.98-.255a.805.805 0 0 0-.996.865l.624 5.388c.04.339.225.637.507.822l2.042 1.328c.383.248.607.68.59 1.127l-.177 4.16-.004.02c-.003.033-.006.066-.01.083a.6.6 0 0 1-.382.416.566.566 0 0 1-.553-.127.482.482 0 0 1-.138-.215.8.8 0 0 1-.027-.225l.155-3.78a.813.813 0 0 0-.37-.708l-2.864-1.861a.52.52 0 0 0-.08-.067.781.781 0 0 0-.118-.064l-1.506-.98a.986.986 0 0 1-.44-.714l-.432-3.797a.77.77 0 0 0-.46-.617.76.76 0 0 0-.758.11l-3.354 2.617a.388.388 0 0 1-.547-.078.39.39 0 0 1 .07-.546l4.804-3.75a.56.56 0 0 1 .272-.115l2.884-.345a.978.978 0 0 1 .353.027l1.62.41c.006.002.017.002.023.006a.79.79 0 0 0 .872-.406c0-.003.004-.007.007-.01l1.208-2.355c.1-.188.345-.268.526-.174a.398.398 0 0 1 .171.52l-1.425 2.787a.963.963 0 0 1-1.107.503Z" }),
36638
+ React.createElement("path", { d: "M9.877 16.607a.425.425 0 0 0 .084-.09.99.99 0 0 0 .275-.587.974.974 0 0 0-.218-.725l-2.375-2.898a.986.986 0 0 0-1.389-.14l-1.952 1.596a.99.99 0 0 0-.359.67 1 1 0 0 0 .215.732l2.361 2.898a.99.99 0 0 0 .671.359c.037.003.07.006.108.006a.985.985 0 0 0 .624-.22l1.955-1.6ZM4.89 14.571c-.01-.013-.01-.033-.01-.04 0-.007.004-.027.02-.04l1.953-1.597c.02-.017.05-.01.067.01l2.368 2.891c0 .004.003.004.003.007.007.01.013.02.01.034 0 .013-.007.023-.017.033a.352.352 0 0 0-.07.07l-1.885 1.54c-.014.01-.034.01-.04.01a.055.055 0 0 1-.04-.02l-2.359-2.898Z" }),
36639
+ React.createElement("path", { d: "m7.013 15.96 1.21.318a.34.34 0 0 0 .413-.241.336.336 0 0 0-.238-.41l-1.214-.318a.192.192 0 0 1-.135-.17l-.09-1.393a.334.334 0 1 0-.668.044l.09 1.392a.853.853 0 0 0 .631.778ZM9.495 6.058a4.664 4.664 0 0 0-1.05-2.949l.235-.238.462.463a.471.471 0 0 0 .665 0 .468.468 0 0 0 0-.664L8.213 1.077a.468.468 0 0 0-.664 0 .468.468 0 0 0 0 .664l.466.466-.23.238A4.65 4.65 0 0 0 5.287 1.41v-.47h.86c.257 0 .469-.211.469-.47A.471.471 0 0 0 6.147 0h-2.66a.47.47 0 0 0-.47.47c0 .258.212.47.47.47h.859v.469A4.68 4.68 0 0 0 .153 6.058a4.678 4.678 0 0 0 4.672 4.672 4.678 4.678 0 0 0 4.67-4.672Zm-8.403 0a3.736 3.736 0 0 1 3.623-3.73.504.504 0 0 0 .104.013c.037 0 .07-.003.104-.013a3.71 3.71 0 0 1 2.472 1.03c.02.03.04.057.067.08a.41.41 0 0 0 .074.06 3.72 3.72 0 0 1 1.02 2.56 3.739 3.739 0 0 1-3.734 3.733 3.736 3.736 0 0 1-3.73-3.733Z" }),
36640
+ React.createElement("path", { d: "M5.235 6.065V3.626a.42.42 0 0 0-.839 0v2.439a.42.42 0 0 0 .839 0Z" })),
36641
+ React.createElement("defs", null,
36642
+ React.createElement("clipPath", { id: "becoxy-late-early_svg__a" },
36643
+ React.createElement("path", { fill: "#fff", d: "M0 0h24v24H0z" })))));
36644
+ };
36645
+
36646
+ var SvgBecoxyMoreTime = function (_a) {
36647
+ var title = _a.title, titleId = _a.titleId, props = __rest(_a, ["title", "titleId"]);
36648
+ return (React.createElement("svg", __assign$1({ xmlns: "http://www.w3.org/2000/svg", width: props.fontSize || 24, height: props.fontSize || 24, viewBox: "0 0 24 24", strokeWidth: props.strokeWidth || 1.5, "aria-labelledby": titleId }, props),
36649
+ title ? React.createElement("title", { id: titleId }, title) : null,
36650
+ React.createElement("path", { fill: "currentColor", d: "M10 8v6l4.7 2.9.8-1.2-4-2.4V8z" }),
36651
+ React.createElement("path", { fill: "currentColor", d: "M17.92 12A6.957 6.957 0 0 1 11 20c-3.9 0-7-3.1-7-7s3.1-7 7-7c.7 0 1.37.1 2 .29V4.23c-.64-.15-1.31-.23-2-.23-5 0-9 4-9 9s4 9 9 9a8.963 8.963 0 0 0 8.94-10h-2.02z" }),
36652
+ React.createElement("path", { fill: "currentColor", d: "M20 5V2h-2v3h-3v2h3v3h2V7h3V5z" })));
36653
+ };
36654
+
36655
+ var SvgBecoxySwitchShift = function (_a) {
36656
+ var title = _a.title, titleId = _a.titleId, props = __rest(_a, ["title", "titleId"]);
36657
+ return (React.createElement("svg", __assign$1({ width: props.fontSize || 24, height: props.fontSize || 24, viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", strokeWidth: props.strokeWidth || 1.5, "aria-labelledby": titleId }, props),
36658
+ title ? React.createElement("title", { id: titleId }, title) : null,
36659
+ React.createElement("g", { clipPath: "url(#becoxy-switch-shift_svg__a)" },
36660
+ React.createElement("path", { d: "M14.459 2.852a.375.375 0 0 1 .427-.313 6.349 6.349 0 0 1 4.098 2.433 6.36 6.36 0 0 1 1.303 3.605l.537-.544a.375.375 0 0 1 .533.527l-1.211 1.228a.374.374 0 0 1-.53.003L18.387 8.58a.375.375 0 1 1 .527-.534l.625.617a5.613 5.613 0 0 0-1.152-3.235 5.602 5.602 0 0 0-3.616-2.148.375.375 0 0 1-.313-.428ZM9.228 20.72a5.602 5.602 0 0 1-3.616-2.147 5.613 5.613 0 0 1-1.152-3.236l.625.617a.375.375 0 0 0 .527-.533l-1.228-1.212a.375.375 0 0 0-.53.004L2.642 15.44a.375.375 0 1 0 .534.527l.537-.544a6.36 6.36 0 0 0 1.303 3.605 6.348 6.348 0 0 0 4.098 2.433.376.376 0 0 0 .427-.313.375.375 0 0 0-.313-.428Zm-2.604-7.612A6.491 6.491 0 0 1 .141 6.624 6.491 6.491 0 0 1 6.624.141a6.491 6.491 0 0 1 6.484 6.483 6.491 6.491 0 0 1-6.484 6.484Zm0-.75a5.74 5.74 0 0 0 5.734-5.734A5.74 5.74 0 0 0 6.624.891 5.74 5.74 0 0 0 .891 6.624a5.74 5.74 0 0 0 5.733 5.734Zm0-.319A5.42 5.42 0 0 1 1.21 6.624 5.42 5.42 0 0 1 6.624 1.21a5.42 5.42 0 0 1 5.415 5.414 5.42 5.42 0 0 1-5.415 5.415Zm-2.646-1.576a.375.375 0 0 1 .644.374c.5.239 1.05.39 1.627.437v-.263a.375.375 0 0 1 .75 0v.263a4.63 4.63 0 0 0 1.627-.437.375.375 0 0 1 .645-.374c.466-.322.87-.726 1.192-1.192a.375.375 0 0 1 .374-.645c.239-.5.39-1.048.437-1.627h-.263a.375.375 0 0 1 0-.75h.263a4.627 4.627 0 0 0-.437-1.627.374.374 0 0 1-.476-.155.375.375 0 0 1 .102-.49A4.704 4.704 0 0 0 9.27 2.786a.375.375 0 0 1-.644-.373A4.629 4.629 0 0 0 7 1.975v.262a.375.375 0 0 1-.75 0v-.262a4.63 4.63 0 0 0-1.627.437.375.375 0 0 1-.644.373c-.466.322-.87.727-1.193 1.193a.375.375 0 0 1-.373.644c-.239.5-.391 1.049-.437 1.627h.262a.375.375 0 0 1 0 .75h-.262c.046.579.198 1.127.436 1.627a.375.375 0 0 1 .374.645c.322.466.727.87 1.193 1.192Zm.115-2.377a.375.375 0 0 1 .137-.512l1.468-.848a.933.933 0 0 1 .551-.954V3.107a.375.375 0 0 1 .75 0v2.665a.933.933 0 0 1-.375 1.784.926.926 0 0 1-.55-.181l-1.469.848a.373.373 0 0 1-.512-.137Zm2.713-1.462a.182.182 0 1 0-.364 0 .182.182 0 0 0 .364 0ZM23.86 17.376a6.491 6.491 0 0 1-6.483 6.483 6.491 6.491 0 0 1-6.484-6.483 6.491 6.491 0 0 1 6.484-6.484 6.49 6.49 0 0 1 6.483 6.484Zm-6.483 5.733c.736 0 1.44-.14 2.088-.393v-1.86a.375.375 0 0 1 .75 0v1.5c.316-.18.613-.39.888-.626v-.974c0-1.04-.847-1.887-1.887-1.887h-.86l-.633 1.537a.375.375 0 0 1-.693 0l-.632-1.537h-.86c-1.041 0-1.888.846-1.888 1.887v.974c.275.235.573.445.889.626v-1.5a.375.375 0 0 1 .75 0v1.86a5.705 5.705 0 0 0 2.088.393Zm5.733-5.733a5.74 5.74 0 0 0-5.733-5.734 5.74 5.74 0 0 0-5.734 5.734c0 1.352.471 2.597 1.258 3.578v-.198a2.64 2.64 0 0 1 2.636-2.637h1.112c.152 0 .29.092.347.232l.38.926.381-.926a.375.375 0 0 1 .347-.232h1.112a2.64 2.64 0 0 1 2.637 2.637v.199a5.707 5.707 0 0 0 1.257-3.58Zm-3.424-1.818c0 1.36-1.036 2.465-2.31 2.465-1.273 0-2.308-1.106-2.308-2.465 0-1.359 1.035-2.465 2.309-2.465 1.273 0 2.309 1.106 2.309 2.465Zm-.75 0c0-.945-.7-1.715-1.56-1.715-.859 0-1.558.77-1.558 1.715 0 .946.699 1.715 1.559 1.715s1.559-.77 1.559-1.715Z", fill: props.color || "currentColor" })),
36661
+ React.createElement("defs", null,
36662
+ React.createElement("clipPath", { id: "becoxy-switch-shift_svg__a" },
36663
+ React.createElement("path", { fill: "#fff", d: "M0 0h24v24H0z" })))));
36664
+ };
36665
+
36666
+ var SvgBecoxyTimeExplanation = function (_a) {
36667
+ var title = _a.title, titleId = _a.titleId, props = __rest(_a, ["title", "titleId"]);
36668
+ return (React.createElement("svg", __assign$1({ width: props.fontSize || 24, height: props.fontSize || 24, viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", strokeWidth: props.strokeWidth || 1.5, "aria-labelledby": titleId }, props),
36669
+ title ? React.createElement("title", { id: titleId }, title) : null,
36670
+ React.createElement("g", { clipPath: "url(#becoxy-time-explanation_svg__a)", fill: props.color || "currentColor" },
36671
+ React.createElement("path", { d: "M13.115 22.523a.264.264 0 0 1-.267-.267v-6.635c0-.149.117-.266.267-.266.149 0 .266.117.266.266v6.635c0 .15-.122.267-.266.267ZM15.381 22.523a.264.264 0 0 1-.266-.267v-6.635c0-.149.117-.266.266-.266.15 0 .267.117.267.266v6.635c0 .15-.117.267-.267.267ZM17.653 22.523a.264.264 0 0 1-.266-.267v-6.635c0-.149.117-.266.266-.266.15 0 .267.117.267.266v6.635c0 .15-.123.267-.267.267ZM19.92 22.523a.264.264 0 0 1-.267-.267v-6.635c0-.149.118-.266.267-.266.15 0 .267.117.267.266v6.635c0 .15-.118.267-.267.267Z" }),
36672
+ React.createElement("path", { d: "M22.635 23.67h-12.24a1.154 1.154 0 0 1-1.152-1.153v-8.293c0-.635.517-1.152 1.152-1.152h1.648c.149 0 .266.117.266.267 0 .149-.117.266-.266.266h-1.648a.62.62 0 0 0-.619.619v8.293a.62.62 0 0 0 .619.619h12.24a.62.62 0 0 0 .618-.619v-8.293a.62.62 0 0 0-.618-.619h-1.648a.264.264 0 0 1-.267-.266c0-.15.117-.267.267-.267h1.648c.634 0 1.152.517 1.152 1.152v8.293c0 .635-.518 1.152-1.152 1.152ZM19.7 13.604h-2.544a.264.264 0 0 1-.266-.266c0-.15.117-.267.266-.267h2.544c.15 0 .267.117.267.267 0 .149-.117.266-.267.266Zm-3.824 0h-2.544a.264.264 0 0 1-.266-.266c0-.15.117-.267.266-.267h2.544a.267.267 0 0 1 0 .533Z" }),
36673
+ React.createElement("path", { d: "M22.336 22.523H10.699a.264.264 0 0 1-.267-.267v-6.635c0-.149.117-.266.267-.266H22.34c.15 0 .267.117.267.266v6.635a.272.272 0 0 1-.272.267Zm-11.37-.534h11.109v-6.101h-11.11v6.101ZM12.688 14.95a.906.906 0 0 1-.907-.907v-1.414a.906.906 0 1 1 1.814 0v1.414a.906.906 0 0 1-.907.906Zm0-2.694a.371.371 0 0 0-.373.373v1.414c0 .208.165.373.373.373a.371.371 0 0 0 .373-.373v-1.414a.371.371 0 0 0-.373-.373ZM16.517 14.95a.906.906 0 0 1-.906-.907v-1.414a.906.906 0 1 1 1.813 0v1.414a.906.906 0 0 1-.907.906Zm0-2.694a.371.371 0 0 0-.373.373v1.414c0 .208.165.373.373.373a.371.371 0 0 0 .374-.373v-1.414a.371.371 0 0 0-.374-.373ZM20.347 14.95a.906.906 0 0 1-.907-.907v-1.414a.906.906 0 1 1 1.813 0v1.414a.906.906 0 0 1-.906.906Zm0-2.694a.371.371 0 0 0-.374.373v1.414c0 .208.166.373.374.373a.371.371 0 0 0 .373-.373v-1.414a.374.374 0 0 0-.373-.373ZM14.923 13.605a.264.264 0 0 1-.267-.266V4.81a.672.672 0 0 0-.667-.672h-2.453v1.488c0 .149-.117.266-.267.266a.264.264 0 0 1-.266-.266V4.16c0-.016 0-.032-.006-.048 0-.016-.005-.032-.005-.048a.632.632 0 0 0-.027-.117.254.254 0 0 1 .048-.23.27.27 0 0 1 .214-.106h2.762c.662 0 1.2.538 1.2 1.205v8.528a.263.263 0 0 1-.266.261Z" }),
36674
+ React.createElement("path", { d: "M10.64 23.67H1.413c-.661 0-1.2-.545-1.2-1.206V4.811c0-.662.539-1.206 1.2-1.206h2.763c.085 0 .16.038.213.107.048.064.07.15.048.23a.764.764 0 0 0-.021.117c-.005.016-.005.032-.005.048s-.006.032-.006.048V5.62c0 .15-.117.267-.266.267a.264.264 0 0 1-.267-.267V4.14H1.42a.668.668 0 0 0-.667.672v17.653c0 .368.299.667.667.667h9.221c.15 0 .267.117.267.266 0 .15-.118.272-.267.272ZM13.168 12.475a.264.264 0 0 1-.267-.267V5.893H11.27a.264.264 0 0 1-.266-.266c0-.15.117-.267.266-.267h1.899c.15 0 .267.117.267.267v6.581a.267.267 0 0 1-.267.267Z" }),
36675
+ React.createElement("path", { d: "M9.515 21.915h-7.28a.264.264 0 0 1-.267-.267V5.627c0-.15.117-.267.267-.267h1.904c.149 0 .266.117.266.267 0 .149-.117.266-.266.266H2.5v15.488h7.014a.267.267 0 0 1 0 .533Z" }),
36676
+ React.createElement("path", { d: "M5.333 10.315H4.107a.62.62 0 0 1-.619-.619V8.288a.62.62 0 0 1 .619-.619h1.226a.62.62 0 0 1 .619.619v1.408a.62.62 0 0 1-.619.619ZM4.107 8.203a.084.084 0 0 0-.086.085v1.408c0 .048.038.085.086.085h1.226a.084.084 0 0 0 .086-.085V8.288a.084.084 0 0 0-.086-.085H4.107ZM5.333 14.96H4.107a.62.62 0 0 1-.619-.619v-1.408a.62.62 0 0 1 .619-.618h1.226a.62.62 0 0 1 .619.618v1.408a.62.62 0 0 1-.619.619Zm-1.226-2.112a.084.084 0 0 0-.086.085v1.408c0 .048.038.086.086.086h1.226a.084.084 0 0 0 .086-.086v-1.408a.084.084 0 0 0-.086-.085H4.107ZM5.333 19.605H4.107a.62.62 0 0 1-.619-.618v-1.408a.62.62 0 0 1 .619-.619h1.226a.62.62 0 0 1 .619.619v1.408a.62.62 0 0 1-.619.618Zm-1.226-2.112a.084.084 0 0 0-.086.086v1.408c0 .048.038.085.086.085h1.226a.084.084 0 0 0 .086-.085v-1.408a.084.084 0 0 0-.086-.086H4.107ZM11.355 8.528H7.056a.264.264 0 0 1-.267-.267c0-.149.118-.266.267-.266h4.299c.15 0 .266.117.266.266 0 .15-.117.267-.266.267ZM9.925 9.99H7.061a.264.264 0 0 1-.266-.267c0-.15.117-.267.266-.267h2.864a.267.267 0 0 1 0 .533ZM8.48 13.173H7.061a.264.264 0 0 1-.266-.266c0-.15.117-.267.266-.267H8.48a.267.267 0 0 1 0 .533ZM8.005 14.635h-.949a.264.264 0 0 1-.267-.267c0-.15.118-.267.267-.267h.95c.149 0 .266.118.266.267 0 .15-.117.267-.267.267ZM8.48 17.819H7.061a.264.264 0 0 1-.266-.267c0-.15.117-.267.266-.267H8.48a.267.267 0 0 1 0 .533ZM8.005 19.28h-.949a.264.264 0 0 1-.267-.267c0-.149.118-.266.267-.266h.95c.149 0 .266.117.266.266 0 .15-.117.267-.267.267ZM11.27 6.427H4.132a.264.264 0 0 1-.266-.267V4.224c0-.923.746-1.67 1.669-1.67h.027v-.08c0-1.178.96-2.138 2.138-2.138 1.179 0 2.139.96 2.139 2.139v.08h.027c.922 0 1.669.746 1.669 1.669V6.16c0 .15-.123.267-.267.267ZM4.4 5.893h6.597V4.224c0-.63-.512-1.136-1.136-1.136h-.325a.264.264 0 0 1-.203-.096.292.292 0 0 1-.058-.219A1.607 1.607 0 0 0 7.696.87a1.607 1.607 0 0 0-1.579 1.904.25.25 0 0 1-.058.219.272.272 0 0 1-.203.096h-.325c-.63 0-1.136.512-1.136 1.136l.005 1.67Z" }),
36677
+ React.createElement("path", { d: "M7.701 3.621A1.154 1.154 0 0 1 6.55 2.47c0-.634.518-1.152 1.152-1.152.635 0 1.152.518 1.152 1.152 0 .635-.517 1.152-1.152 1.152Zm0-1.765a.62.62 0 0 0 0 1.237.624.624 0 0 0 .62-.624.615.615 0 0 0-.62-.613ZM16.384 19.488a.25.25 0 0 1-.187-.08l-.218-.219a.264.264 0 0 1 0-.378.264.264 0 0 1 .378 0l.032.032.379-.379a.264.264 0 0 1 .379 0 .264.264 0 0 1 0 .379l-.566.565a.293.293 0 0 1-.197.08ZM22.336 18.107H10.699a.264.264 0 0 1-.267-.267c0-.15.117-.267.267-.267H22.34c.15 0 .267.118.267.267 0 .15-.123.267-.272.267ZM22.336 20.304H10.699a.264.264 0 0 1-.267-.267c0-.149.117-.266.267-.266H22.34c.15 0 .267.117.267.266 0 .15-.123.267-.272.267Z" })),
36678
+ React.createElement("defs", null,
36679
+ React.createElement("clipPath", { id: "becoxy-time-explanation_svg__a" },
36680
+ React.createElement("path", { fill: "#fff", d: "M0 0h24v24H0z" })))));
36681
+ };
36682
+
36683
+ var SvgBecoxyWallet = function (_a) {
36684
+ var title = _a.title, titleId = _a.titleId, props = __rest(_a, ["title", "titleId"]);
36685
+ return (React.createElement("svg", __assign$1({ width: props.fontSize || 24, height: props.fontSize || 24, viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", strokeWidth: props.strokeWidth || 1.5, "aria-labelledby": titleId }, props),
36686
+ title ? React.createElement("title", { id: titleId }, title) : null,
36687
+ React.createElement("g", { clipPath: "url(#becoxy-wallet_svg__a)", fill: props.color || "currentColor" },
36688
+ React.createElement("path", { d: "M23.654 10.89 18.015.187a.358.358 0 0 0-.479-.148L2.186 8.129a.354.354 0 0 0-.063.042H.661a.354.354 0 0 0-.355.355v15.12c0 .195.159.354.355.354h15.293a.354.354 0 1 0 0-.709H1.014V8.88h19.68c.43 0 .78.35.78.78v4.181h-.809a.356.356 0 0 0 .006-.061v-.577a.354.354 0 1 0-.709 0v.577c0 .02.002.041.006.061h-1.163c-.613 0-1.11.498-1.11 1.11v2.269c0 .612.497 1.11 1.11 1.11h1.157v.3a.354.354 0 1 0 .709 0v-.3h.803v4.182c0 .43-.35.78-.78.78h-2.976a.354.354 0 0 0 0 .708h2.977a1.49 1.49 0 0 0 1.488-1.488V18.33h.402a.354.354 0 0 0 .354-.354v-3.78a.354.354 0 0 0-.354-.355h-.402v-1.776l1.323-.697a.358.358 0 0 0 .148-.479ZM4.248 8.17h-.622L17.553.832l2.221 4.215a.354.354 0 0 0-.302-.078l-.583.121-.626-1.187a.354.354 0 0 0-.478-.149c-.363.192-.779.23-1.17.109a1.525 1.525 0 0 1-.905-.751.358.358 0 0 0-.479-.148s-8.923 4.711-8.95 4.742c0 0-1.99.429-2.033.465ZM18.167 5.24l-9.46 1.963 6.566-3.46c.282.377.674.655 1.132.797.458.142.938.134 1.384-.018l.378.718Zm-3.196 2.931 1.302-.27c.035.093.077.183.124.27h-1.425Zm2.297 0a1.526 1.526 0 0 1-.4-.755.358.358 0 0 0-.42-.275l-4.78.992a.353.353 0 0 0-.102.038H7.53l11.74-2.436.506 2.436h-2.507Zm3.427 0h-.196L19.9 5.286l1.672 3.172a1.48 1.48 0 0 0-.877-.287Zm1.535 6.379v3.071h-3.425a.402.402 0 0 1-.402-.401v-2.268c0-.222.18-.402.402-.402h3.425Zm-.047-3.286V9.66l-.001-.044.68 1.29-.679.358Z" }),
36689
+ React.createElement("path", { d: "M2.52 21.785a.355.355 0 0 0-.702.065v.284c0 .195.159.354.354.354h.284a.354.354 0 0 0 .065-.703ZM2.172 14.578a.354.354 0 0 0-.354.355v.576a.354.354 0 1 0 .709 0v-.576a.354.354 0 0 0-.355-.355ZM2.172 18.037a.354.354 0 0 0-.354.355v.576a.354.354 0 1 0 .709 0v-.576a.354.354 0 0 0-.355-.355ZM2.172 16.308a.354.354 0 0 0-.354.354v.576a.354.354 0 1 0 .709 0v-.576a.354.354 0 0 0-.355-.354ZM2.172 19.766a.354.354 0 0 0-.354.355v.576a.354.354 0 1 0 .709 0v-.576a.354.354 0 0 0-.355-.355ZM2.172 11.12a.354.354 0 0 0-.354.354v.576a.354.354 0 0 0 .709 0v-.576a.354.354 0 0 0-.355-.354ZM2.172 12.849a.354.354 0 0 0-.354.354v.577a.354.354 0 1 0 .709 0v-.577a.354.354 0 0 0-.355-.354ZM2.456 9.683h-.284a.354.354 0 0 0-.354.354v.284a.354.354 0 0 0 .703.065.354.354 0 0 0-.065-.703ZM15.639 9.683h-.55a.354.354 0 1 0 0 .709h.55a.354.354 0 0 0 0-.709ZM4.104 9.683h-.55a.354.354 0 1 0 0 .709h.55a.354.354 0 0 0 0-.709ZM18.934 9.683h-.549a.354.354 0 0 0 0 .709h.55a.354.354 0 1 0 0-.709ZM17.287 9.683h-.55a.354.354 0 1 0 0 .709h.55a.354.354 0 0 0 0-.709ZM9.047 9.683h-.549a.354.354 0 1 0 0 .709h.55a.354.354 0 0 0 0-.709ZM12.343 9.683h-.55a.354.354 0 0 0 0 .709h.55a.354.354 0 1 0 0-.709ZM13.99 9.683h-.549a.354.354 0 0 0 0 .709h.55a.354.354 0 1 0 0-.709ZM10.695 9.683h-.55a.354.354 0 1 0 0 .709h.55a.354.354 0 0 0 0-.709ZM7.4 9.683h-.55a.354.354 0 1 0 0 .709h.55a.354.354 0 0 0 0-.709ZM5.752 9.683h-.55a.354.354 0 1 0 0 .709h.55a.354.354 0 0 0 0-.709ZM20.317 9.683h-.284a.354.354 0 0 0-.065.703.355.355 0 0 0 .703-.065v-.284a.354.354 0 0 0-.354-.354ZM20.317 19.43a.354.354 0 0 0-.355.354v.576a.354.354 0 1 0 .709 0v-.576a.354.354 0 0 0-.354-.355ZM20.317 11.12a.354.354 0 0 0-.355.354v.576a.354.354 0 1 0 .709 0v-.576a.354.354 0 0 0-.354-.354ZM20.317 21.496a.354.354 0 0 0-.349.29.354.354 0 0 0 .065.702h.284a.354.354 0 0 0 .354-.354v-.284a.354.354 0 0 0-.354-.354ZM17.287 21.78h-.55a.354.354 0 1 0 0 .708h.55a.354.354 0 1 0 0-.709ZM13.99 21.78h-.549a.354.354 0 0 0 0 .708h.55a.354.354 0 1 0 0-.709ZM7.4 21.78h-.55a.354.354 0 0 0 0 .708h.55a.354.354 0 1 0 0-.709ZM12.343 21.78h-.55a.354.354 0 0 0 0 .708h.55a.354.354 0 1 0 0-.709ZM10.695 21.78h-.55a.354.354 0 1 0 0 .708h.55a.354.354 0 1 0 0-.709ZM15.639 21.78h-.55a.354.354 0 1 0 0 .708h.55a.354.354 0 1 0 0-.709ZM4.104 21.78h-.55a.354.354 0 0 0 0 .708h.55a.354.354 0 1 0 0-.709ZM5.752 21.78h-.55a.354.354 0 0 0 0 .708h.55a.354.354 0 1 0 0-.709ZM18.934 21.78h-.549a.354.354 0 0 0 0 .708h.55a.354.354 0 1 0 0-.709ZM9.047 21.78h-.549a.354.354 0 0 0 0 .708h.55a.354.354 0 1 0 0-.709ZM20.316 14.975a1.112 1.112 0 0 0 0 2.22 1.112 1.112 0 0 0 0-2.22Zm0 1.512a.402.402 0 1 1 .001-.804.402.402 0 0 1 0 .804ZM11.623 15.731h-.473a1.064 1.064 0 0 1 0-2.126h1.89a.354.354 0 1 0 0-.709h-1.063v-.59a.354.354 0 1 0-.709 0v.59h-.118c-.977 0-1.772.795-1.772 1.772s.795 1.772 1.772 1.772h.473a1.064 1.064 0 0 1 0 2.126h-1.89a.354.354 0 1 0 0 .709h1.535v.59a.354.354 0 1 0 .709 0v-.626a1.775 1.775 0 0 0 1.417-1.736c0-.977-.794-1.772-1.771-1.772Z" })),
36690
+ React.createElement("defs", null,
36691
+ React.createElement("clipPath", { id: "becoxy-wallet_svg__a" },
36692
+ React.createElement("path", { fill: "#fff", d: "M0 0h24v24H0z" })))));
36693
+ };
36694
+
36602
36695
  var SvgBecoxyWriting = function (_a) {
36603
36696
  var title = _a.title, titleId = _a.titleId, props = __rest(_a, ["title", "titleId"]);
36604
36697
  return (React.createElement("svg", __assign$1({ width: props.fontSize || 24, height: props.fontSize || 24, viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", strokeWidth: props.strokeWidth || 1.5, "aria-labelledby": titleId }, props),
@@ -36621,6 +36714,14 @@ var SvgCopy = function (_a) {
36621
36714
  React.createElement("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })));
36622
36715
  };
36623
36716
 
36717
+ var SvgCreditCard = function (_a) {
36718
+ var title = _a.title, titleId = _a.titleId, props = __rest(_a, ["title", "titleId"]);
36719
+ return (React.createElement("svg", __assign$1({ xmlns: "http://www.w3.org/2000/svg", width: props.fontSize || 24, height: props.fontSize || 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: props.strokeWidth || 1.5, strokeLinecap: "round", strokeLinejoin: "round", className: "credit-card_svg__feather credit-card_svg__feather-credit-card", "aria-labelledby": titleId }, props),
36720
+ title ? React.createElement("title", { id: titleId }, title) : null,
36721
+ React.createElement("rect", { x: 1, y: 4, width: 22, height: 16, rx: 2, ry: 2 }),
36722
+ React.createElement("path", { d: "M1 10h22" })));
36723
+ };
36724
+
36624
36725
  var SvgEdit3 = function (_a) {
36625
36726
  var title = _a.title, titleId = _a.titleId, props = __rest(_a, ["title", "titleId"]);
36626
36727
  return (React.createElement("svg", __assign$1({ xmlns: "http://www.w3.org/2000/svg", width: props.fontSize || 24, height: props.fontSize || 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: props.strokeWidth || 1.5, strokeLinecap: "round", strokeLinejoin: "round", className: "edit-3_svg__feather edit-3_svg__feather-edit-3", "aria-labelledby": titleId }, props),
@@ -36669,6 +36770,13 @@ var SvgLink = function (_a) {
36669
36770
  React.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })));
36670
36771
  };
36671
36772
 
36773
+ var SvgListCheck = function (_a) {
36774
+ var title = _a.title, titleId = _a.titleId, props = __rest(_a, ["title", "titleId"]);
36775
+ return (React.createElement("svg", __assign$1({ xmlns: "http://www.w3.org/2000/svg", width: props.fontSize || 24, height: props.fontSize || 24, fill: "currentColor", className: "list-check_svg__bi list-check_svg__bi-list-check", viewBox: "0 0 16 16", strokeWidth: props.strokeWidth || 1.5, "aria-labelledby": titleId }, props),
36776
+ title ? React.createElement("title", { id: titleId }, title) : null,
36777
+ React.createElement("path", { fillRule: "evenodd", d: "M5 11.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zM3.854 2.146a.5.5 0 0 1 0 .708l-1.5 1.5a.5.5 0 0 1-.708 0l-.5-.5a.5.5 0 1 1 .708-.708L2 3.293l1.146-1.147a.5.5 0 0 1 .708 0zm0 4a.5.5 0 0 1 0 .708l-1.5 1.5a.5.5 0 0 1-.708 0l-.5-.5a.5.5 0 1 1 .708-.708L2 7.293l1.146-1.147a.5.5 0 0 1 .708 0zm0 4a.5.5 0 0 1 0 .708l-1.5 1.5a.5.5 0 0 1-.708 0l-.5-.5a.5.5 0 0 1 .708-.708l.146.147 1.146-1.147a.5.5 0 0 1 .708 0z" })));
36778
+ };
36779
+
36672
36780
  var SvgLogOut = function (_a) {
36673
36781
  var title = _a.title, titleId = _a.titleId, props = __rest(_a, ["title", "titleId"]);
36674
36782
  return (React.createElement("svg", __assign$1({ xmlns: "http://www.w3.org/2000/svg", width: props.fontSize || 24, height: props.fontSize || 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: props.strokeWidth || 1.5, strokeLinecap: "round", strokeLinejoin: "round", className: "log-out_svg__feather log-out_svg__feather-log-out", "aria-labelledby": titleId }, props),
@@ -69828,7 +69936,7 @@ const ModalGroupInfo = (props) => {
69828
69936
  const [openModalPreview, setOpenModalPreview] = useState(false);
69829
69937
  const [selectedMessage, setSelectedMessage] = useState(null);
69830
69938
  const uploading = (args) => {
69831
- args.currentRequest.setRequestHeader("Authorization", `Bearer ${getToken()}`);
69939
+ args.currentRequest.setRequestHeader("Authorization", `Bearer ${getToken$1()}`);
69832
69940
  };
69833
69941
  const uploadFailure = () => {
69834
69942
  notificationError(t('UploadFail'));
@@ -71781,17 +71889,2323 @@ const UserProfileSidebar = (props) => {
71781
71889
  return (jsxs("div", { className: classnames('user-profile-sidebar', { show: userSidebarRight === true }), children: [jsxs("header", { className: 'user-profile-header', children: [jsx("span", { className: 'close-icon', onClick: handleUserSidebarRight, children: jsx(SvgX, { fontSize: 14 }) }), jsxs("div", { className: 'header-profile-sidebar', children: [jsx(AvatarDefault, { className: 'box-shadow-1 avatar-border', size: 'xl', status: user.status === 1 ? 'online' : 'offline', img: userAvatar, imgHeight: '70', imgWidth: '70', color: 'light-secondary' }), jsx("h4", { className: 'chat-user-name', children: user.name }), jsx("span", { className: 'user-post', children: user.code })] })] }), jsx(PerfectScrollbar, { className: 'user-profile-sidebar-area', options: { wheelPropagation: false }, children: jsxs("div", { className: 'personal-info', children: [jsx("h6", { className: 'section-label mb-1 mt-3', children: t('Personal Information') }), jsxs("ul", { className: 'list-unstyled', children: [jsxs("li", { className: 'mb-1', children: [jsx(SvgMail, { className: 'me-75', fontSize: 17 }), jsx("span", { className: 'align-middle', children: user?.email })] }), jsxs("li", { className: 'mb-1', children: [jsx(SvgPhoneCall, { className: 'me-50', fontSize: 17 }), jsx("span", { className: 'align-middle', children: user?.phone })] })] })] }) })] }));
71782
71890
  };
71783
71891
 
71892
+ const initialState = {
71893
+ dataUploadFile: [],
71894
+ status: false
71895
+ };
71896
+ // Helper function to get token
71897
+ const getToken = () => {
71898
+ let accessToken = localStorage.getItem('access_token');
71899
+ if (!accessToken) {
71900
+ const userData = localStorage.getItem('userData');
71901
+ if (userData) {
71902
+ accessToken = JSON.parse(userData).id_token;
71903
+ }
71904
+ }
71905
+ return accessToken;
71906
+ };
71907
+ const baseUrl = process.env.REACT_APP_BASE_URL;
71908
+ const uploadFileApi = createAsyncThunk(UPLOADFILE.ACTION_TYPES.UPLOAD_FILE, async (params, thunkAPI) => {
71909
+ try {
71910
+ const token = getToken();
71911
+ const response = await fetch(`${baseUrl}/api/file/upload`, {
71912
+ method: 'POST',
71913
+ headers: {
71914
+ 'Authorization': `Bearer ${token}`
71915
+ },
71916
+ body: params
71917
+ });
71918
+ if (!response.ok) {
71919
+ const errorData = await response.json().catch(() => ({}));
71920
+ throw new Error(errorData.message || `HTTP error! status: ${response.status}`);
71921
+ }
71922
+ return await response.json();
71923
+ }
71924
+ catch (error) {
71925
+ return thunkAPI.rejectWithValue({ error: error.message || error });
71926
+ }
71927
+ });
71928
+ const uploadImageApi = createAsyncThunk(UPLOADFILE.ACTION_TYPES.UPLOAD_IMAGE, async (params, thunkAPI) => {
71929
+ try {
71930
+ const token = getToken();
71931
+ const response = await fetch(`${baseUrl}/api/image/upload`, {
71932
+ method: 'POST',
71933
+ headers: {
71934
+ 'Authorization': `Bearer ${token}`
71935
+ },
71936
+ body: params
71937
+ });
71938
+ if (!response.ok) {
71939
+ const errorData = await response.json().catch(() => ({}));
71940
+ throw new Error(errorData.message || `HTTP error! status: ${response.status}`);
71941
+ }
71942
+ return await response.json();
71943
+ }
71944
+ catch (error) {
71945
+ return thunkAPI.rejectWithValue({ error: error.message || error });
71946
+ }
71947
+ });
71948
+ const uploadMultiFileApi = createAsyncThunk(UPLOADFILE.ACTION_TYPES.UPLOAD_FILE_MULTI, async (params, thunkAPI) => {
71949
+ try {
71950
+ const token = getToken();
71951
+ const response = await fetch(`${baseUrl}/api/file/upload-mutil`, {
71952
+ method: 'POST',
71953
+ headers: {
71954
+ 'Authorization': `Bearer ${token}`
71955
+ },
71956
+ body: params
71957
+ });
71958
+ if (!response.ok) {
71959
+ const errorData = await response.json().catch(() => ({}));
71960
+ throw new Error(errorData.message || `HTTP error! status: ${response.status}`);
71961
+ }
71962
+ return await response.json();
71963
+ }
71964
+ catch (error) {
71965
+ return thunkAPI.rejectWithValue({ error: error.message || error });
71966
+ }
71967
+ });
71968
+ const uploadFileSlice = createSlice({
71969
+ name: 'uploadFile',
71970
+ initialState,
71971
+ reducers: {
71972
+ handleAddUploadFile: (state, action) => {
71973
+ state.dataUploadFile.push(action.payload);
71974
+ }
71975
+ },
71976
+ extraReducers: builder => {
71977
+ builder.addCase(uploadImageApi.pending, (state) => {
71978
+ console.log(state);
71979
+ });
71980
+ }
71981
+ });
71982
+ const { handleAddUploadFile } = uploadFileSlice.actions;
71983
+
71984
+ const useUploadFile = () => {
71985
+ const dispatch = useAppDispatch();
71986
+ const { dataUploadFile, status } = useAppSelector((state) => state.uploadFile);
71987
+ const uploadFileApi$1 = (params) => {
71988
+ return dispatch(uploadFileApi(params));
71989
+ };
71990
+ const uploadImageApi$1 = (params) => {
71991
+ return dispatch(uploadImageApi(params));
71992
+ };
71993
+ const uploadMultiFileApi$1 = (params) => {
71994
+ return dispatch(uploadMultiFileApi(params));
71995
+ };
71996
+ const handleAddUploadFile$1 = (arr) => { return dispatch(handleAddUploadFile(arr)); };
71997
+ return {
71998
+ uploadFileApi: uploadFileApi$1,
71999
+ uploadImageApi: uploadImageApi$1,
72000
+ uploadMultiFileApi: uploadMultiFileApi$1,
72001
+ dataUploadFile,
72002
+ status,
72003
+ handleAddUploadFile: handleAddUploadFile$1
72004
+ };
72005
+ };
72006
+
71784
72007
  const DateHeader = memo(({ label }) => (jsx("div", { className: "d-flex justify-content-center", children: jsx("div", { style: {
71785
72008
  backgroundColor: "rgba(0,0,0,0.2)",
71786
72009
  padding: "2px 15px",
71787
72010
  borderRadius: "6px"
71788
72011
  }, children: jsx("p", { className: "m-0", style: { textAlign: "center", color: "#fff" }, children: label }) }) })));
71789
72012
  DateHeader.displayName = 'DateHeader';
72013
+ const ADMINISTRATIVE_ITEMS = [
72014
+ { type: 'administrative', label: 'Đơn xin nghỉ', adminType: 'leaveApplication', Icon: SvgBecoxyApplication },
72015
+ { type: 'administrative', label: 'Đăng ký đi muộn về sớm', adminType: 'lateEarly', Icon: SvgBecoxyLateEarly },
72016
+ { type: 'administrative', label: 'Đăng ký xe', adminType: 'registerCars', Icon: SvgBecoxyCar },
72017
+ { type: 'administrative', label: 'Đăng ký công tác', adminType: 'mission', Icon: SvgBecoxyBusinessMan },
72018
+ { type: 'administrative', label: 'Đăng ký làm thêm', adminType: 'overtime', Icon: SvgBecoxyMoreTime },
72019
+ { type: 'administrative', label: 'Đăng ký tạm ứng', adminType: 'advancePays', Icon: SvgBecoxyWallet },
72020
+ { type: 'administrative', label: 'Đề nghị thanh toán', adminType: 'pay', Icon: SvgCreditCard },
72021
+ { type: 'administrative', label: 'Đề nghị đổi ca', adminType: 'shiftChange', Icon: SvgBecoxySwitchShift },
72022
+ { type: 'administrative', label: 'Giải trình chấm công', adminType: 'attendanceExplanation', Icon: SvgBecoxyTimeExplanation }
72023
+ ];
71790
72024
  const ChatLog = (props) => {
71791
72025
  // ** Props & Store
71792
72026
  // const clipboard = useClipboard()
71793
- const { contactId, chatRoomId } = useChat();
72027
+ useLexicalComposerContext();
72028
+ useTranslation();
72029
+ useUploadFile();
72030
+ const { typeChat, contactId, chatRoomId, active, messageByGroup, pinnedMessages, setScroll, checkScroll, pinMessageChatRoom, deleteMessageApi, recallMessageApi, get_message_by_group_cursor_api, getPinMessageChatRoomApi, deletePinMessage,
72031
+ //updateGroupTagApi,
72032
+ createReminderApi, senMessageApi, typingUsers } = useChat();
72033
+ useAppSelector((state) => state.hubNotification);
72034
+ const [dynamicMenuItems, setDynamicMenuItems] = useState([]);
72035
+ useEffect(() => {
72036
+ const fetchFormConfig = async () => {
72037
+ try {
72038
+ const token = getToken$1();
72039
+ const response = await fetch(`${BASE_URL}/api/formconfig`, {
72040
+ method: 'GET',
72041
+ headers: {
72042
+ 'Authorization': `Bearer ${token}`,
72043
+ 'Content-Type': 'application/json'
72044
+ }
72045
+ });
72046
+ if (!response.ok) {
72047
+ throw new Error(`HTTP error! status: ${response.status}`);
72048
+ }
72049
+ const res = await response.json();
72050
+ if (res) {
72051
+ const items = res.map((item) => ({
72052
+ type: 'dynamic',
72053
+ label: item.title,
72054
+ dynamicType: item.type,
72055
+ Icon: SvgBecoxyApplication
72056
+ }));
72057
+ setDynamicMenuItems(items);
72058
+ }
72059
+ }
72060
+ catch (err) {
72061
+ console.log(err);
72062
+ }
72063
+ };
72064
+ fetchFormConfig();
72065
+ }, []);
72066
+ //const menuItems = useMemo(() => [...ADMINISTRATIVE_ITEMS, ...dynamicMenuItems], [dynamicMenuItems])
72067
+ // Tách menu items cho Công việc (task + dynamic)
72068
+ useMemo(() => [
72069
+ { type: 'task', label: 'Công việc', Icon: SvgListCheck },
72070
+ ...dynamicMenuItems
72071
+ ], [dynamicMenuItems]);
72072
+ // Menu items cho Hành chính (chỉ administrative)
72073
+ useMemo(() => ADMINISTRATIVE_ITEMS, []);
72074
+ useRef(false);
72075
+ useRef(null);
72076
+ useRef(null);
72077
+ useRef(null);
72078
+ useRef(null);
71794
72079
  const containerChatRef = useRef(null);
72080
+ const { connectHub, dataInfo, dataProfile,
72081
+ //handleUser,
72082
+ //handleUserSidebarRight,
72083
+ handleSidebar, handleSidebarRight, userSidebarLeft, dataHistory, chatGetType, approveUpdateStatus, handleModalAdministrative, setDataItem, handleModalAddUserGroup, handleModalGroup, typeOpenModalAdd, setTypeOpenModalAdd
72084
+ //unpinMessage
72085
+ //getPinnedMessages
72086
+ } = props;
72087
+ dataHistory?.find((dt) => dt.id === active);
72088
+ //const dataInfoAvatar = dataInfo && dataInfo.avatar ? dataInfo.avatar : DEFAULT_AVATAR
72089
+ useState([]);
72090
+ useState(false);
72091
+ useState(false);
72092
+ useState(false);
72093
+ useState(false);
72094
+ useState(false);
72095
+ useState('');
72096
+ useState(null);
72097
+ useState(null);
72098
+ useState(null);
72099
+ useState({ x: 0, y: 0 });
72100
+ useState(undefined);
72101
+ useState(undefined);
72102
+ useState(null);
72103
+ useState(false);
72104
+ useState(true);
72105
+ useRef(0);
72106
+ useState(0);
72107
+ useState(true);
72108
+ useState(new Set());
72109
+ useState(null);
72110
+ useState(false);
72111
+ useState(new Set());
72112
+ // const [isPinnedCollapsed, setIsPinnedCollapsed] = useState(true)
72113
+ // const scrollToBottom = () => {
72114
+ // const messagesEndEle = document.getElementById('messagesEnd')
72115
+ // messagesEndEle?.scrollIntoView({ block: 'end', behavior: "instant" })
72116
+ // }
72117
+ // // Load initial messages
72118
+ // useEffect(() => {
72119
+ // if (!checkScroll) {
72120
+ // scrollToBottom()
72121
+ // }
72122
+ // }, [messageByGroup, checkScroll])
72123
+ // const mentionItems = useMemo(() => {
72124
+ // if (!groupChatUsers) { return [] }
72125
+ // const users = Array.isArray(groupChatUsers.users) ? groupChatUsers.users : []
72126
+ // const mappedUsers = users.map((user: any) => {
72127
+ // const rawAvatar = user.avatar
72128
+ // let avatar = DEFAULT_AVATAR
72129
+ // if (rawAvatar) {
72130
+ // avatar = isValidUrl(rawAvatar) ? rawAvatar : `${CDN_URL_VIEW}/${rawAvatar}`
72131
+ // }
72132
+ // return {
72133
+ // ...user,
72134
+ // avatar
72135
+ // }
72136
+ // })
72137
+ // return [{ id: "all", name: "All" }, ...mappedUsers]
72138
+ // }, [groupChatUsers])
72139
+ // const toggleModalPreview = () => {
72140
+ // setOpenModalPreview(!openModalPreview)
72141
+ // }
72142
+ // const handlePreview = useCallback((mes: any) => {
72143
+ // setSelectedMessage(mes)
72144
+ // setOpenModalPreview(true)
72145
+ // }, [])
72146
+ // const [isFetching, setIsFetching] = useState(false)
72147
+ // const dispatch = useDispatch()
72148
+ // const handleStartConversation = () => {
72149
+ // if (
72150
+ // !Object.keys({}).length &&
72151
+ // !userSidebarLeft &&
72152
+ // window.innerWidth < 992
72153
+ // ) {
72154
+ // handleSidebar()
72155
+ // }
72156
+ // }
72157
+ // const uploadGroup = async (files: File[], type: 'image' | 'file') => {
72158
+ // if (files.length === 0) { return }
72159
+ // const batchId = newGuid()
72160
+ // const errors: Array<{ file: File; error: any }> = []
72161
+ // // Upload và gửi từng file một
72162
+ // for (const file of files) {
72163
+ // try {
72164
+ // const result = await uploadWithRetry(file)
72165
+ // if (result.success && chatRoomId) {
72166
+ // const infoFiles = result.data?.infoFiles || []
72167
+ // const items = type === 'image' ? infoFiles.map((x: any) => ({ ...x, batchId, createdDate: new Date().toISOString() })) : infoFiles
72168
+ // // Gửi message ngay sau khi upload thành công
72169
+ // connectHub(chatRoomId, {
72170
+ // sendTo: dataInfo.id,
72171
+ // content: '',
72172
+ // type,
72173
+ // path: JSON.stringify(items),
72174
+ // typeChat
72175
+ // })
72176
+ // } else {
72177
+ // errors.push({ file, error: result.error })
72178
+ // }
72179
+ // } catch (error) {
72180
+ // errors.push({ file, error })
72181
+ // }
72182
+ // }
72183
+ // // Thông báo lỗi nếu có
72184
+ // if (errors.length > 0) {
72185
+ // notificationError(`${errors.length}/${files.length} ${type === 'image' ? 'ảnh' : 'file'} upload thất bại`)
72186
+ // }
72187
+ // }
72188
+ // const dataURLToFile = (dataUrl: string, fileName: string) => {
72189
+ // const [header, data] = dataUrl.split(',')
72190
+ // const mime = header.match(/data:(.*?);/)?.[1] || 'image/png'
72191
+ // const binary = atob(data)
72192
+ // const len = binary.length
72193
+ // const u8 = new Uint8Array(len)
72194
+ // for (let i = 0; i < len; i++) { u8[i] = binary.charCodeAt(i) }
72195
+ // return new File([u8], fileName, { type: mime })
72196
+ // }
72197
+ // // ** Extract tagUserIds from editor mentions
72198
+ // const extractTagUserIds = (): string[] => {
72199
+ // const tagUserIds: string[] = []
72200
+ // let hasAllMention = false
72201
+ // editor.getEditorState().read(() => {
72202
+ // const root = $getRoot()
72203
+ // const nodes = root.getAllTextNodes()
72204
+ // nodes.forEach((node) => {
72205
+ // if ($isMentionNode(node)) {
72206
+ // const userId = (node as any).__userId
72207
+ // if (userId === 'all') {
72208
+ // hasAllMention = true
72209
+ // } else if (userId && !tagUserIds.includes(userId)) {
72210
+ // tagUserIds.push(userId)
72211
+ // }
72212
+ // }
72213
+ // })
72214
+ // })
72215
+ // // Nếu có @All, lấy tất cả userId trong nhóm
72216
+ // if (hasAllMention && groupChatUsers?.users) {
72217
+ // const allUserIds = groupChatUsers.users
72218
+ // .map((user: any) => user.id)
72219
+ // .filter((id: string) => id !== dataProfile?.id) // Loại bỏ chính mình
72220
+ // return allUserIds
72221
+ // }
72222
+ // return tagUserIds
72223
+ // }
72224
+ // // ** Sends New Msg
72225
+ // const handleSendMsg = (message: any) => {
72226
+ // if (imgCopy.length > 0) {
72227
+ // const imageFiles: File[] = []
72228
+ // const otherFiles: File[] = []
72229
+ // imgCopy.forEach((item: any, idx: number) => {
72230
+ // const data = item?.data || item
72231
+ // if (typeof data === 'string' && data.startsWith('data:image')) {
72232
+ // imageFiles.push(dataURLToFile(data, item.name || `pasted_${Date.now()}_${idx}.png`))
72233
+ // } else if (data instanceof File) {
72234
+ // if (data.type?.startsWith('image')) {
72235
+ // imageFiles.push(data)
72236
+ // } else {
72237
+ // otherFiles.push(data)
72238
+ // }
72239
+ // }
72240
+ // })
72241
+ // // Gửi ảnh trước rồi file
72242
+ // uploadGroup(imageFiles, 'image')
72243
+ // uploadGroup(otherFiles, 'file')
72244
+ // }
72245
+ // if (message.trim().length) {
72246
+ // if (typingTimeoutRef.current) {
72247
+ // clearTimeout(typingTimeoutRef.current)
72248
+ // }
72249
+ // isTypingRef.current = false
72250
+ // if (connection && chatRoomId) {
72251
+ // connection.invoke('StopTyping', chatRoomId).catch(console.error)
72252
+ // }
72253
+ // const tagUserIds = extractTagUserIds()
72254
+ // const id = typeChat === 'CHAT' ? chatRoomId : contactId
72255
+ // if (id) {
72256
+ // connectHub(id, {
72257
+ // sendTo: dataInfo.id,
72258
+ // content: message.trim(),
72259
+ // replyContent: replyMessage?.currentMessage ? JSON.stringify(replyMessage.currentMessage) : null,
72260
+ // path: null,
72261
+ // type: 'text',
72262
+ // typeChat,
72263
+ // tagUserIds
72264
+ // })
72265
+ // }
72266
+ // }
72267
+ // setImgCopy([])
72268
+ // }
72269
+ // const uploadWithRetry = async (file: File, maxRetries = 2) => {
72270
+ // let lastError
72271
+ // for (let attempt = 0; attempt <= maxRetries; attempt++) {
72272
+ // try {
72273
+ // const formDataFile = new FormData()
72274
+ // formDataFile.append('files', file, file.name)
72275
+ // const rs = await uploadMultiFileApi(formDataFile).unwrap()
72276
+ // return { success: true, data: rs }
72277
+ // } catch (error: any) {
72278
+ // lastError = error
72279
+ // // Không retry nếu là lỗi validation từ server
72280
+ // if (error?.status === 400 || error?.status === 413) {
72281
+ // break
72282
+ // }
72283
+ // if (attempt < maxRetries) {
72284
+ // // Exponential backoff: 1s, 2s, 4s...
72285
+ // await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, attempt))
72286
+ // )
72287
+ // }
72288
+ // }
72289
+ // }
72290
+ // return {
72291
+ // success: false,
72292
+ // error: lastError?.message || 'Upload thất bại'
72293
+ // }
72294
+ // }
72295
+ // const sendFile = async (event: any) => {
72296
+ // if (event.target.files && event.target.files[0]) {
72297
+ // const filesToUpload: File[] = Array.from(event.target.files)
72298
+ // const errors: Array<{ file: File, error: any }> = []
72299
+ // for (const file of filesToUpload) {
72300
+ // const result = await uploadWithRetry(file)
72301
+ // if (result.success && chatRoomId) {
72302
+ // connectHub(chatRoomId, {
72303
+ // sendTo: dataInfo.id,
72304
+ // content: '',
72305
+ // type: 'file',
72306
+ // path: JSON.stringify(result.data?.infoFiles),
72307
+ // typeChat
72308
+ // })
72309
+ // } else {
72310
+ // errors.push({ file, error: result.error })
72311
+ // }
72312
+ // }
72313
+ // if (errors.length > 0) {
72314
+ // notificationError(`${errors.length} file upload thất bại`)
72315
+ // }
72316
+ // event.target.value = ''
72317
+ // }
72318
+ // }
72319
+ // const sendImage = async (event: any) => {
72320
+ // if (event.target.files && event.target.files[0]) {
72321
+ // const filesToUpload: File[] = Array.from(event.target.files)
72322
+ // const errors: Array<{ file: File, error: any }> = []
72323
+ // const batchId = newGuid()
72324
+ // for (const file of filesToUpload) {
72325
+ // const result = await uploadWithRetry(file)
72326
+ // const item = result.data?.infoFiles?.map((x: any) => ({ ...x, batchId, createdDate: new Date().toISOString() })) || []
72327
+ // if (result.success && chatRoomId && result?.data?.status) {
72328
+ // connectHub(chatRoomId, {
72329
+ // sendTo: dataInfo.id,
72330
+ // content: '',
72331
+ // type: 'image',
72332
+ // path: JSON.stringify(item),
72333
+ // typeChat
72334
+ // })
72335
+ // } else {
72336
+ // errors.push({ file, error: result.error })
72337
+ // }
72338
+ // }
72339
+ // if (errors.length > 0) {
72340
+ // notificationError(`${errors.length} ảnh upload thất bại`)
72341
+ // }
72342
+ // event.target.value = ''
72343
+ // }
72344
+ // }
72345
+ // const handleRemoveImage = useCallback((idx: number) => {
72346
+ // const newArr = [...imgCopy]
72347
+ // newArr.splice(idx, 1)
72348
+ // setImgCopy(newArr)
72349
+ // }, [imgCopy])
72350
+ // const onContextMenu = useCallback((e: any, chatMessage: any) => {
72351
+ // const selection: any = window.document.getSelection()
72352
+ // setIsOpen(true)
72353
+ // setPosition({ x: e.clientX, y: e.clientY })
72354
+ // if (e.target) {
72355
+ // setCurrentMessage(chatMessage)
72356
+ // }
72357
+ // // Detect ảnh được click từ data attribute
72358
+ // const fileIndex = e.target?.dataset?.fileIndex
72359
+ // if (fileIndex !== undefined && chatMessage?.path) {
72360
+ // setClickedImageFile(chatMessage.path[parseInt(fileIndex)])
72361
+ // } else {
72362
+ // setClickedImageFile(null)
72363
+ // }
72364
+ // e.preventDefault()
72365
+ // const contextType = selection.toString() ? 'selection' : chatMessage?.type ? chatMessage.type : 'default'
72366
+ // const config = CONTEXT_CONFIG[contextType]
72367
+ // setListContextShow({ list: config.show, type: "SHOW" })
72368
+ // setListContextHide({ list: config.hide, type: "HIDE" })
72369
+ // }, [])
72370
+ // const clearReply = () => {
72371
+ // setReplyMessage(null)
72372
+ // }
72373
+ // const handleTypingStart = () => {
72374
+ // if (!isTypingRef.current && connection && chatRoomId) {
72375
+ // connection.invoke('StartTyping', chatRoomId).catch(console.error)
72376
+ // isTypingRef.current = true
72377
+ // }
72378
+ // }
72379
+ // const handleTypingStop = () => {
72380
+ // if (typingTimeoutRef.current) { clearTimeout(typingTimeoutRef.current) }
72381
+ // typingTimeoutRef.current = setTimeout(() => {
72382
+ // if (isTypingRef.current && connection && chatRoomId) {
72383
+ // connection.invoke('StopTyping', chatRoomId).catch(console.error)
72384
+ // isTypingRef.current = false
72385
+ // }
72386
+ // }, 2000)
72387
+ // }
72388
+ // const handleChange = useCallback(
72389
+ // (editorState: EditorState) => {
72390
+ // if (
72391
+ // inputContainer &&
72392
+ // inputContainer.current &&
72393
+ // inputContainer.current.clientHeight > 50
72394
+ // ) {
72395
+ // setIsMultiLine(true)
72396
+ // } else {
72397
+ // setIsMultiLine(false)
72398
+ // }
72399
+ // editorState.read(() => {
72400
+ // handleTypingStart()
72401
+ // handleTypingStop()
72402
+ // })
72403
+ // },
72404
+ // [inputContainer, connection, chatRoomId]
72405
+ // )
72406
+ // const onEnter = (val: any) => {
72407
+ // handleSendMsg(val)
72408
+ // clearReply()
72409
+ // setReplyMessage(null)
72410
+ // }
72411
+ // useEffect(() => {
72412
+ // if (active) {
72413
+ // setReplyMessage(null)
72414
+ // setImgCopy([])
72415
+ // setIsAtBottom(true)
72416
+ // prevListLength.current = 0
72417
+ // }
72418
+ // }, [
72419
+ // active,
72420
+ // dataInfo
72421
+ // //chatRoomId,
72422
+ // //chatGetType
72423
+ // ])
72424
+ // // Chuyển phòng thì load lại message + pinned messages
72425
+ // useEffect(() => {
72426
+ // if (!chatRoomId && handleSidebar) { return }
72427
+ // chatGetType(chatRoomId, undefined, "", "", undefined, undefined, 0, 0)
72428
+ // if (chatRoomId) {
72429
+ // getPinMessageChatRoomApi(chatRoomId)
72430
+ // }
72431
+ // }, [chatRoomId])
72432
+ // const handleUnpinMessage = useCallback(async (message: any) => {
72433
+ // const pinId = message?.pinId || message?.id
72434
+ // if (!pinId) { return }
72435
+ // await deletePinMessage(pinId)
72436
+ // }, [deletePinMessage, chatRoomId])
72437
+ // const handleViewPinnedMessage = useCallback((message: any) => {
72438
+ // if (message?.id) {
72439
+ // //setViewingPinnedMessage(message.id)
72440
+ // // Tìm message element
72441
+ // const element = document.getElementById(`msg-${message.id}`)
72442
+ // const chatContainer = document.getElementById('scrollableDivChat')
72443
+ // if (element && chatContainer) {
72444
+ // // Lấy vị trí của element và container
72445
+ // const elementRect = element.getBoundingClientRect()
72446
+ // const containerRect = chatContainer.getBoundingClientRect()
72447
+ // // Tính toán scroll position để đưa element vào giữa container
72448
+ // const scrollTop = chatContainer.scrollTop
72449
+ // const offset = elementRect.top - containerRect.top - (containerRect.height / 2) + (elementRect.height / 2)
72450
+ // // Scroll trong container, không scroll toàn page
72451
+ // chatContainer.scrollTo({
72452
+ // top: scrollTop + offset,
72453
+ // behavior: 'smooth'
72454
+ // })
72455
+ // // Highlight message
72456
+ // const originalBg = element.style.backgroundColor
72457
+ // const originalZIndex = element.style.zIndex
72458
+ // element.style.backgroundColor = '#fff3cd'
72459
+ // element.style.zIndex = '1000'
72460
+ // element.style.position = 'relative'
72461
+ // element.style.transition = 'background-color 0.3s'
72462
+ // // Auto close sau 500ms
72463
+ // setTimeout(() => {
72464
+ // element.style.backgroundColor = originalBg || ''
72465
+ // element.style.zIndex = originalZIndex || ''
72466
+ // //setViewingPinnedMessage(null)
72467
+ // }, 500)
72468
+ // } else {
72469
+ // console.log('Message not found in current view, may need to load more messages')
72470
+ // setTimeout(() => {
72471
+ // //setViewingPinnedMessage(null)
72472
+ // }, 2000)
72473
+ // }
72474
+ // }
72475
+ // }, [])
72476
+ // const onKeyDown = (event: any) => {
72477
+ // if (event.code === 'NumpadEnter') {
72478
+ // event.preventDefault()
72479
+ // const baseOptions = {
72480
+ // key: 'Enter',
72481
+ // code: 'Enter',
72482
+ // which: 13,
72483
+ // keyCode: 13,
72484
+ // bubbles: true,
72485
+ // shiftKey: event.shiftKey,
72486
+ // altKey: event.altKey,
72487
+ // ctrlKey: event.ctrlKey,
72488
+ // metaKey: event.metaKey
72489
+ // }
72490
+ // const newEvent = new KeyboardEvent('keydown', baseOptions)
72491
+ // event.target.dispatchEvent(newEvent)
72492
+ // }
72493
+ // }
72494
+ // const useParsedChatData = (chatMsg: string) => {
72495
+ // if (!chatMsg) { return {} }
72496
+ // try {
72497
+ // return typeof chatMsg === 'string' ? JSON.parse(chatMsg) : chatMsg
72498
+ // } catch (err) {
72499
+ // console.error('JSON parse error:', err)
72500
+ // return {}
72501
+ // }
72502
+ // }
72503
+ // const renderChatText = useCallback((chat: any) => {
72504
+ // const isPath = Array.isArray(chat?.path) && typeof chat.path[0]?.path === "string" ? chat.path[0].path.trim() : ""
72505
+ // const img = isPath ? `${CDN_URL_VIEW}/${isPath}` : ""
72506
+ // const toggleExpanded = (messageId: string) => {
72507
+ // const newExpanded = new Set(expandedMessages)
72508
+ // if (newExpanded.has(messageId)) {
72509
+ // newExpanded.delete(messageId)
72510
+ // } else {
72511
+ // newExpanded.add(messageId)
72512
+ // }
72513
+ // setExpandedMessages(newExpanded)
72514
+ // }
72515
+ // const formatMentionsReact = (text: string, mentions: any[], messageId: string) => {
72516
+ // if (!text || !mentions || mentions.length === 0) { return text }
72517
+ // const maxLength = 200
72518
+ // const isExpanded = expandedMessages.has(messageId)
72519
+ // let displayText = text
72520
+ // let isTruncated = false
72521
+ // if (!isExpanded && text.length > maxLength) {
72522
+ // displayText = text.substring(0, maxLength)
72523
+ // isTruncated = true
72524
+ // }
72525
+ // // Chỉ highlight những mention có trong danh sách
72526
+ // let result: any = displayText
72527
+ // // Hàm helper để xử lý mention trong cả string và array
72528
+ // const processMention = (text: string, mention: any): any => {
72529
+ // const escapedName = mention?.name?.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
72530
+ // const mentionRegex = new RegExp(`@${escapedName}(?=\\s|$|[.,;:!?()[\\]{}'"\`~@])`, 'g')
72531
+ // const parts = text.split(mentionRegex)
72532
+ // const matches = text.match(mentionRegex) || []
72533
+ // if (matches.length === 0) {
72534
+ // return text
72535
+ // }
72536
+ // const newParts: any[] = []
72537
+ // parts.forEach((part: any, index: any) => {
72538
+ // newParts.push(part)
72539
+ // if (matches[index]) {
72540
+ // newParts.push(
72541
+ // <span key={`mention-${messageId}-${mention.id || mention.name}-${index}`} className="chat-mention">
72542
+ // {matches[index]}
72543
+ // </span>
72544
+ // )
72545
+ // }
72546
+ // })
72547
+ // return newParts
72548
+ // }
72549
+ // mentions.forEach((mention: any) => {
72550
+ // if (typeof result === 'string') {
72551
+ // result = processMention(result, mention)
72552
+ // } else if (Array.isArray(result)) {
72553
+ // // Xử lý từng phần tử trong array
72554
+ // const processedArray: any[] = []
72555
+ // result.forEach((item: any) => {
72556
+ // if (typeof item === 'string') {
72557
+ // const processed = processMention(item, mention)
72558
+ // if (Array.isArray(processed)) {
72559
+ // processedArray.push(...processed)
72560
+ // } else {
72561
+ // processedArray.push(processed)
72562
+ // }
72563
+ // } else {
72564
+ // // Giữ nguyên các React elements đã được xử lý
72565
+ // processedArray.push(item)
72566
+ // }
72567
+ // })
72568
+ // result = processedArray
72569
+ // }
72570
+ // })
72571
+ // // Add expand/collapse functionality
72572
+ // if (isTruncated || (isExpanded && text.length > maxLength)) {
72573
+ // const expandButton = (
72574
+ // <span
72575
+ // key={`expand-${messageId}`}
72576
+ // onClick={() => toggleExpanded(messageId)}
72577
+ // style={{
72578
+ // color: '#006edc',
72579
+ // cursor: 'pointer',
72580
+ // fontWeight: 500,
72581
+ // marginLeft: 5
72582
+ // }}
72583
+ // >
72584
+ // {isExpanded ? ' Thu gọn' : '... Mở rộng'}
72585
+ // </span>
72586
+ // )
72587
+ // if (Array.isArray(result)) {
72588
+ // result.push(expandButton)
72589
+ // } else {
72590
+ // result = [result, expandButton]
72591
+ // }
72592
+ // }
72593
+ // return result
72594
+ // }
72595
+ // return (
72596
+ // <>
72597
+ // <div>
72598
+ // <div>
72599
+ // {chat.path && chat.path.length === 1 && (
72600
+ // <div className="image-container">
72601
+ // {img && <img src={img} alt="" />}
72602
+ // </div>
72603
+ // )}
72604
+ // {isValidUrl(chat.msg) && renderLinkPreview(chat.msg)}
72605
+ // {chat.msg && !isValidUrl(chat.msg) ? (
72606
+ // <div>{formatMentionsReact(chat.msg, mentionItems, chat.id)}</div>
72607
+ // ) : (
72608
+ // <></>
72609
+ // )}
72610
+ // {chat.path && chat.path.length > 1 && (
72611
+ // <div className="group-image">
72612
+ // {chat.path.map((it: any, index: any) => {
72613
+ // return (
72614
+ // <div
72615
+ // key={index}
72616
+ // className="group-image-item image-container"
72617
+ // >
72618
+ // <img
72619
+ // style={{ maxWidth: "100%", maxHeight: 360 }}
72620
+ // src={`${CDN_URL_VIEW}/${it.path.trim()}`}
72621
+ // onClick={() => handlePreview(it)}
72622
+ // alt=""
72623
+ // />
72624
+ // </div>
72625
+ // )
72626
+ // })}
72627
+ // </div>
72628
+ // )}
72629
+ // <div className="" style={{ fontSize: "12px", color: "#476285" }}>
72630
+ // {moment(chat.time).format("HH:mm")}
72631
+ // </div>
72632
+ // </div>
72633
+ // </div>
72634
+ // </>
72635
+ // )
72636
+ // }, [expandedMessages, handlePreview, mentionItems])
72637
+ // const getLinkPreviewData = (urlString: string) => {
72638
+ // try {
72639
+ // const hasProtocol = /^https?:\/\//i.test(urlString)
72640
+ // const href = hasProtocol ? urlString : `https://${urlString}`
72641
+ // const url = new URL(href)
72642
+ // const displayUrl =
72643
+ // urlString.length > 80 ? `${urlString.slice(0, 77)}...` : urlString
72644
+ // return {
72645
+ // href,
72646
+ // displayUrl,
72647
+ // host: url.host
72648
+ // }
72649
+ // } catch (e) {
72650
+ // return {
72651
+ // href: urlString,
72652
+ // displayUrl: urlString,
72653
+ // host: ''
72654
+ // }
72655
+ // }
72656
+ // }
72657
+ // const renderLinkPreview = (urlString: string) => {
72658
+ // const { href, displayUrl, host } = getLinkPreviewData(urlString)
72659
+ // return (
72660
+ // <>
72661
+ // <a
72662
+ // href={href}
72663
+ // target="_blank"
72664
+ // rel="noreferrer"
72665
+ // style={{
72666
+ // textDecoration: 'none',
72667
+ // color: 'inherit'
72668
+ // }}
72669
+ // >
72670
+ // <div
72671
+ // style={{
72672
+ // marginTop: 4,
72673
+ // marginBottom: 4,
72674
+ // padding: '8px 10px',
72675
+ // borderRadius: 8,
72676
+ // backgroundColor: '#eef5ff',
72677
+ // border: '1px solid #d3e2ff',
72678
+ // maxWidth: 420
72679
+ // }}
72680
+ // >
72681
+ // <div
72682
+ // style={{
72683
+ // fontSize: 14,
72684
+ // fontWeight: 500,
72685
+ // color: '#1d4f91',
72686
+ // wordBreak: 'break-word'
72687
+ // }}
72688
+ // >
72689
+ // {displayUrl}
72690
+ // </div>
72691
+ // {host && (
72692
+ // <div
72693
+ // style={{
72694
+ // marginTop: 4,
72695
+ // fontSize: 12,
72696
+ // color: '#6f6b7d'
72697
+ // }}
72698
+ // >
72699
+ // {host}
72700
+ // </div>
72701
+ // )}
72702
+ // </div>
72703
+ // </a>
72704
+ // </>
72705
+ // )
72706
+ // }
72707
+ // const renderNotifyLeaveGroup = useCallback((chat: any) => {
72708
+ // const msg = JSON.parse(chat?.msg)
72709
+ // if (chat?.createdById === dataProfile?.id) {
72710
+ // return (
72711
+ // <>
72712
+ // <div>
72713
+ // <span style={{ fontWeight: "bold", marginRight: "5px" }}>
72714
+ // {msg?.name}
72715
+ // </span>
72716
+ // <span>được bạn xoá khỏi nhóm</span>
72717
+ // </div>
72718
+ // </>
72719
+ // )
72720
+ // }
72721
+ // if (chat?.createdById === msg?.id) {
72722
+ // return (
72723
+ // <>
72724
+ // <div>
72725
+ // <span style={{ fontWeight: "bold", marginRight: "5px" }}>
72726
+ // {msg?.name}
72727
+ // </span>
72728
+ // <span>đã rời khỏi nhóm</span>
72729
+ // </div>
72730
+ // </>
72731
+ // )
72732
+ // }
72733
+ // return (
72734
+ // <>
72735
+ // <div>
72736
+ // <span style={{ fontWeight: "bold", marginRight: "5px" }}>
72737
+ // {msg?.name}
72738
+ // </span>
72739
+ // <span>được <span style={{ fontWeight: "bold", marginRight: "5px" }}>{chat?.createdBy?.name}</span> xoá khỏi nhóm</span>
72740
+ // </div>
72741
+ // </>
72742
+ // )
72743
+ // }, [dataProfile])
72744
+ // const renderChatNotification = useCallback((chat: any) => {
72745
+ // const parseChatMsg = (msg: string) => {
72746
+ // if (!msg) { return [] }
72747
+ // try {
72748
+ // const parsed = typeof msg === 'string' ? JSON.parse(msg) : msg
72749
+ // return Array.isArray(parsed) ? parsed : [parsed]
72750
+ // } catch (err) {
72751
+ // console.error('JSON parse error:', err)
72752
+ // return []
72753
+ // }
72754
+ // }
72755
+ // const dataParse = parseChatMsg(chat.msg)
72756
+ // // ✅ FIX: Kiểm tra array trước khi dùng slice
72757
+ // if (!Array.isArray(dataParse) || dataParse.length === 0) {
72758
+ // return (
72759
+ // <div>
72760
+ // <span>Đã có thay đổi trong nhóm</span>
72761
+ // </div>
72762
+ // )
72763
+ // }
72764
+ // const displayedItems = dataParse.slice(0, 2)
72765
+ // const extraCount = Math.max(0, dataParse.length - displayedItems.length)
72766
+ // return (
72767
+ // <>
72768
+ // <div>
72769
+ // {displayedItems.map((item: any, index: any) => (
72770
+ // <strong key={index}>
72771
+ // {item.name}
72772
+ // {index < displayedItems.length - 1 && ", "}
72773
+ // </strong>
72774
+ // ))}
72775
+ // {dataParse.length > 3 && (
72776
+ // <strong>
72777
+ // <span style={{ fontWeight: "normal" }}>{" và "}</span>{" "}
72778
+ // {extraCount} người khác
72779
+ // </strong>
72780
+ // )}
72781
+ // {" được "}
72782
+ // {chat?.createdBy?.id === dataProfile?.id ? (
72783
+ // <span>bạn </span>
72784
+ // ) : (
72785
+ // <strong style={{ marginRight: "5px" }}>{chat?.createdByName}</strong>
72786
+ // )}
72787
+ // thêm vào nhóm
72788
+ // </div>
72789
+ // </>
72790
+ // )
72791
+ // }, [dataProfile])
72792
+ // const renderChatImage = useCallback((chat: any) => {
72793
+ // const files = chat.path
72794
+ // if (!files || !Array.isArray(files) || files.length === 0) {
72795
+ // return null
72796
+ // }
72797
+ // // Ảnh đơn lẻ
72798
+ // if (files.length === 1) {
72799
+ // const imagePath = files[0]?.path?.trim()
72800
+ // if (!imagePath) { return null }
72801
+ // return (
72802
+ // <>
72803
+ // <div className="image-container" style={{ maxWidth: "100%", position: "relative" }}>
72804
+ // <img
72805
+ // src={`${CDN_URL_VIEW}/${imagePath}`}
72806
+ // alt={`Chat image ${chat.id + 1}`}
72807
+ // data-file-index={chat.id}
72808
+ // style={{
72809
+ // maxWidth: "100%",
72810
+ // maxHeight: 400,
72811
+ // borderRadius: 8,
72812
+ // cursor: "pointer"
72813
+ // }}
72814
+ // onClick={() => handlePreview(files[0])}
72815
+ // />
72816
+ // {/* HD Badge */}
72817
+ // <div
72818
+ // style={{
72819
+ // position: "absolute",
72820
+ // top: 6,
72821
+ // left: 6,
72822
+ // backgroundColor: "rgba(0, 0, 0, 0.6)",
72823
+ // color: "white",
72824
+ // padding: "2px 6px",
72825
+ // borderRadius: 4,
72826
+ // fontSize: "10px",
72827
+ // fontWeight: "bold"
72828
+ // }}
72829
+ // >
72830
+ // HD
72831
+ // </div>
72832
+ // </div>
72833
+ // <div className="px-1 py-75">{moment(chat.time).format("HH:mm")}</div>
72834
+ // </>
72835
+ // )
72836
+ // }
72837
+ // // Nhiều ảnh - hiển thị dạng grid 2 cột, tối đa 6 ảnh
72838
+ // const imagesToShow = files.slice(0, 6)
72839
+ // const remainingCount = files.length - 6
72840
+ // return (
72841
+ // <>
72842
+ // <div
72843
+ // className="images-grid-container"
72844
+ // style={{
72845
+ // display: "flex",
72846
+ // flexWrap: "wrap",
72847
+ // maxWidth: "600px",
72848
+ // gap: "4px"
72849
+ // }}
72850
+ // >
72851
+ // {imagesToShow.map((file: any, index: number) => {
72852
+ // const imagePath = file?.path?.trim()
72853
+ // if (!imagePath) { return null }
72854
+ // const imageUrl = `${CDN_URL_VIEW}/${imagePath}`
72855
+ // const isLastImage = index === 5 && remainingCount > 0
72856
+ // // ✅ THÊM: Kiểm tra ảnh cuối khi số lượng lẻ
72857
+ // const isOddCount = imagesToShow.length % 2 !== 0
72858
+ // const isLastItem = index === imagesToShow.length - 1
72859
+ // const isFullWidth = isOddCount && isLastItem && !isLastImage
72860
+ // return (
72861
+ // <div
72862
+ // key={`image-${chat.id}-${index}`}
72863
+ // style={{
72864
+ // width: isFullWidth ? "100%" : "calc(50% - 2px)",
72865
+ // height: "140px",
72866
+ // position: "relative",
72867
+ // overflow: "hidden",
72868
+ // borderRadius: 8,
72869
+ // border: "1px solid #e0e0e0"
72870
+ // }}
72871
+ // >
72872
+ // <img
72873
+ // src={imageUrl}
72874
+ // alt={`Chat image ${index + 1}`}
72875
+ // style={{
72876
+ // width: "100%",
72877
+ // height: "100%",
72878
+ // objectFit: "cover",
72879
+ // borderRadius: 8,
72880
+ // display: "block",
72881
+ // cursor: "pointer"
72882
+ // }}
72883
+ // onClick={() => handlePreview(file)}
72884
+ // />
72885
+ // {/* HD Badge */}
72886
+ // <div
72887
+ // style={{
72888
+ // position: "absolute",
72889
+ // top: 6,
72890
+ // left: 6,
72891
+ // backgroundColor: "rgba(0, 0, 0, 0.6)",
72892
+ // color: "white",
72893
+ // padding: "2px 6px",
72894
+ // borderRadius: 4,
72895
+ // fontSize: "10px",
72896
+ // fontWeight: "bold",
72897
+ // zIndex: 1
72898
+ // }}
72899
+ // >
72900
+ // HD
72901
+ // </div>
72902
+ // {/* Overlay cho ảnh cuối nếu có nhiều hơn 6 ảnh */}
72903
+ // {isLastImage && (
72904
+ // <div
72905
+ // style={{
72906
+ // position: "absolute",
72907
+ // top: 0,
72908
+ // left: 0,
72909
+ // right: 0,
72910
+ // bottom: 0,
72911
+ // backgroundColor: "rgba(0, 0, 0, 0.6)",
72912
+ // display: "flex",
72913
+ // alignItems: "center",
72914
+ // justifyContent: "center",
72915
+ // color: "white",
72916
+ // fontSize: "20px",
72917
+ // fontWeight: "bold",
72918
+ // borderRadius: 8,
72919
+ // cursor: "pointer"
72920
+ // }}
72921
+ // onClick={() => handlePreview(file)}
72922
+ // >
72923
+ // +{remainingCount}
72924
+ // </div>
72925
+ // )}
72926
+ // </div>
72927
+ // )
72928
+ // })}
72929
+ // </div>
72930
+ // <div className="px-1 py-75">{moment(chat.time).format("HH:mm")}</div>
72931
+ // </>
72932
+ // )
72933
+ // }, [handlePreview])
72934
+ // const renderChatFile = useCallback((chat: any) => {
72935
+ // const files = chat?.path
72936
+ // return (
72937
+ // <>
72938
+ // {files?.map((file: any, index: number) => {
72939
+ // return (
72940
+ // <div key={index}>
72941
+ // <div className="d-flex p-50">
72942
+ // <div className="me-1" onClick={() => handlePreview(file)}>
72943
+ // {/*<IconFileType fileType={file?.type} fontSize={50} />*/}
72944
+ // <IconFileTypeColor fileType={file?.type} width={35} />
72945
+ // </div>
72946
+ // <div>
72947
+ // <p className="file-name-chat">{file.name}</p>
72948
+ // <p>{formatBytes({ size: file.size })}</p>
72949
+ // </div>
72950
+ // </div>
72951
+ // {index + 1 === files.length && (
72952
+ // <div className="px-1 pb-75">
72953
+ // {moment(chat.time).format("HH:mm")}
72954
+ // </div>
72955
+ // )}
72956
+ // </div>
72957
+ // )
72958
+ // })}
72959
+ // </>
72960
+ // )
72961
+ // }, [handlePreview])
72962
+ // const renderTaskApplication = useCallback((chat: any) => {
72963
+ // const safeParse = (str: any) => {
72964
+ // if (!str) { return {} }
72965
+ // try {
72966
+ // return typeof str === 'string' ? JSON.parse(str) : str
72967
+ // } catch (err) {
72968
+ // //console.error('JSON parse error:', err)
72969
+ // return {}
72970
+ // }
72971
+ // }
72972
+ // // Helper function to strip HTML tags and get clean text
72973
+ // const stripHtml = (html: string) => {
72974
+ // if (!html) { return '' }
72975
+ // const tmp = document.createElement('div')
72976
+ // tmp.innerHTML = html
72977
+ // return tmp.textContent || tmp.innerText || ''
72978
+ // }
72979
+ // const taskData = safeParse(chat.msg)
72980
+ // const cleanDescription = taskData.description ? stripHtml(taskData.description) : ''
72981
+ // return (
72982
+ // <div
72983
+ // style={{
72984
+ // width: 320,
72985
+ // backgroundColor: "#f8f9fa",
72986
+ // borderRadius: 12,
72987
+ // border: "1px solid #e3e8ef",
72988
+ // padding: "12px",
72989
+ // boxShadow: "0 2px 4px rgba(0,0,0,0.04)"
72990
+ // }}
72991
+ // >
72992
+ // {/* Header với icon và tiêu đề */}
72993
+ // <div className="d-flex align-items-start" style={{ marginBottom: 10 }}>
72994
+ // <div style={{
72995
+ // backgroundColor: "#e7f3ff",
72996
+ // borderRadius: 8,
72997
+ // padding: 6,
72998
+ // display: "flex",
72999
+ // alignItems: "center",
73000
+ // justifyContent: "center",
73001
+ // marginRight: 8,
73002
+ // flexShrink: 0
73003
+ // }}>
73004
+ // <BecoxyWriting color="#006edc" fontSize={24} />
73005
+ // </div>
73006
+ // <div style={{ flex: 1, minWidth: 0 }}>
73007
+ // <div style={{ fontSize: 10, color: "#8b92a7", marginBottom: 2, fontWeight: 500 }}>
73008
+ // Công việc
73009
+ // </div>
73010
+ // <div style={{
73011
+ // fontWeight: 600,
73012
+ // fontSize: 14,
73013
+ // color: "#283046",
73014
+ // lineHeight: "1.4",
73015
+ // wordBreak: "break-word"
73016
+ // }}>
73017
+ // {taskData.subject || 'Không có tiêu đề'}
73018
+ // </div>
73019
+ // </div>
73020
+ // </div>
73021
+ // {/* Nội dung */}
73022
+ // {cleanDescription && (
73023
+ // <div
73024
+ // style={{
73025
+ // marginBottom: 10,
73026
+ // padding: "8px 10px",
73027
+ // backgroundColor: "white",
73028
+ // borderRadius: 8,
73029
+ // fontSize: 12,
73030
+ // color: "#5e5873",
73031
+ // lineHeight: "1.5",
73032
+ // border: "1px solid #eff1f5",
73033
+ // wordBreak: "break-word",
73034
+ // whiteSpace: "pre-wrap"
73035
+ // }}
73036
+ // dangerouslySetInnerHTML={{ __html: taskData.description }}
73037
+ // />
73038
+ // )}
73039
+ // {/* Thông tin người tham gia */}
73040
+ // <div style={{
73041
+ // backgroundColor: "white",
73042
+ // borderRadius: 8,
73043
+ // padding: "8px 10px",
73044
+ // marginBottom: 8,
73045
+ // border: "1px solid #eff1f5"
73046
+ // }}>
73047
+ // {/* Người tạo phiếu */}
73048
+ // {taskData.createdByName && (
73049
+ // <div style={{ marginBottom: taskData.hostPerson?.length > 0 || taskData.thePerformer?.length > 0 ? 8 : 0 }}>
73050
+ // <div style={{ fontSize: 10, color: "#8b92a7", marginBottom: 4, fontWeight: 500 }}>
73051
+ // Người tạo phiếu
73052
+ // </div>
73053
+ // <div className="d-flex align-items-center">
73054
+ // <AvatarDefault
73055
+ // imgWidth={20}
73056
+ // imgHeight={20}
73057
+ // color="light-primary"
73058
+ // className="me-50"
73059
+ // img={taskData?.createdByImg}
73060
+ // />
73061
+ // <span style={{ fontSize: 12, color: "#283046", fontWeight: 500 }}>
73062
+ // {taskData.createdByName}
73063
+ // </span>
73064
+ // </div>
73065
+ // </div>
73066
+ // )}
73067
+ // {/* Người chủ trì */}
73068
+ // {taskData.hostPerson && taskData.hostPerson.length > 0 && (
73069
+ // <div style={{ marginBottom: taskData.thePerformer?.length > 0 ? 8 : 0 }}>
73070
+ // <div style={{ fontSize: 10, color: "#8b92a7", marginBottom: 4, fontWeight: 500 }}>
73071
+ // Người chủ trì
73072
+ // </div>
73073
+ // <div className="d-flex align-items-center flex-wrap" style={{ gap: 4 }}>
73074
+ // {taskData.hostPerson.slice(0, 2).map((person: any, index: number) => (
73075
+ // <div key={index} className="d-flex align-items-center" style={{
73076
+ // backgroundColor: "#f8f9fa",
73077
+ // borderRadius: 6,
73078
+ // padding: "3px 6px",
73079
+ // marginRight: 4
73080
+ // }}>
73081
+ // <AvatarDefault
73082
+ // imgWidth={18}
73083
+ // imgHeight={18}
73084
+ // color="light-info"
73085
+ // className="me-50"
73086
+ // img={person.img}
73087
+ // />
73088
+ // <span style={{ fontSize: 11, color: "#5e5873", fontWeight: 500 }}>
73089
+ // {person.name || person.fullName || 'N/A'}
73090
+ // </span>
73091
+ // </div>
73092
+ // ))}
73093
+ // {taskData.hostPerson.length > 2 && (
73094
+ // <span style={{
73095
+ // fontSize: 11,
73096
+ // color: "#8b92a7",
73097
+ // backgroundColor: "#f8f9fa",
73098
+ // padding: "3px 8px",
73099
+ // borderRadius: 6,
73100
+ // fontWeight: 500
73101
+ // }}>
73102
+ // +{taskData.hostPerson.length - 2}
73103
+ // </span>
73104
+ // )}
73105
+ // </div>
73106
+ // </div>
73107
+ // )}
73108
+ // {/* Người thực hiện */}
73109
+ // {taskData.thePerformer && taskData.thePerformer.length > 0 && (
73110
+ // <div>
73111
+ // <div style={{ fontSize: 10, color: "#8b92a7", marginBottom: 4, fontWeight: 500 }}>
73112
+ // Người thực hiện
73113
+ // </div>
73114
+ // <div className="d-flex align-items-center flex-wrap" style={{ gap: 4 }}>
73115
+ // {taskData.thePerformer.slice(0, 2).map((performer: any, index: number) => (
73116
+ // <div key={index} className="d-flex align-items-center" style={{
73117
+ // backgroundColor: "#f8f9fa",
73118
+ // borderRadius: 6,
73119
+ // padding: "3px 6px",
73120
+ // marginRight: 4
73121
+ // }}>
73122
+ // <AvatarDefault
73123
+ // imgWidth={18}
73124
+ // imgHeight={18}
73125
+ // color="light-secondary"
73126
+ // className="me-50"
73127
+ // img={performer.img}
73128
+ // />
73129
+ // <span style={{ fontSize: 11, color: "#5e5873", fontWeight: 500 }}>
73130
+ // {performer.name || performer.fullName || 'N/A'}
73131
+ // </span>
73132
+ // </div>
73133
+ // ))}
73134
+ // {taskData.thePerformer.length > 2 && (
73135
+ // <span style={{
73136
+ // fontSize: 11,
73137
+ // color: "#8b92a7",
73138
+ // backgroundColor: "#f8f9fa",
73139
+ // padding: "3px 8px",
73140
+ // borderRadius: 6,
73141
+ // fontWeight: 500
73142
+ // }}>
73143
+ // +{taskData.thePerformer.length - 2}
73144
+ // </span>
73145
+ // )}
73146
+ // </div>
73147
+ // </div>
73148
+ // )}
73149
+ // </div>
73150
+ // {/* Hạn hoàn thành */}
73151
+ // {taskData.dueDate && (
73152
+ // <div style={{
73153
+ // display: "flex",
73154
+ // alignItems: "center",
73155
+ // justifyContent: "space-between",
73156
+ // backgroundColor: "#fff5f5",
73157
+ // padding: "6px 10px",
73158
+ // borderRadius: 8,
73159
+ // marginBottom: 8,
73160
+ // border: "1px solid #ffe5e5"
73161
+ // }}>
73162
+ // <div style={{ display: "flex", alignItems: "center" }}>
73163
+ // <Clock fontSize={14} style={{ color: "#ea5455", marginRight: 6 }} />
73164
+ // <span style={{ fontSize: 10, color: "#8b92a7", fontWeight: 500 }}>
73165
+ // Hạn hoàn thành
73166
+ // </span>
73167
+ // </div>
73168
+ // <span style={{ fontSize: 12, color: "#ea5455", fontWeight: 600 }}>
73169
+ // {moment(taskData.dueDate).format('DD/MM/YYYY HH:mm')}
73170
+ // </span>
73171
+ // </div>
73172
+ // )}
73173
+ // {/* Footer time */}
73174
+ // <div style={{
73175
+ // fontSize: 11,
73176
+ // color: "#adb5bd",
73177
+ // textAlign: "right",
73178
+ // fontWeight: 500
73179
+ // }}>
73180
+ // {moment(chat.time).format("HH:mm")}
73181
+ // </div>
73182
+ // </div>
73183
+ // )
73184
+ // }, [])
73185
+ // const renderChatReminder = useCallback((chat: any) => {
73186
+ // let msgContent = chat.msg
73187
+ // let timeDisplay = chat.time
73188
+ // try {
73189
+ // const parsed = JSON.parse(chat.msg)
73190
+ // if (parsed && typeof parsed === 'object') {
73191
+ // msgContent = parsed.content || chat.msg
73192
+ // timeDisplay = parsed.scheduleTime || chat.time
73193
+ // }
73194
+ // } catch (e) {
73195
+ // // Not JSON, use original
73196
+ // }
73197
+ // return (
73198
+ // <div
73199
+ // style={{
73200
+ // borderTopRightRadius: 6,
73201
+ // borderBottomRightRadius: 6,
73202
+ // // borderTopLeftRadius: 6, // Should be conditional or default
73203
+ // borderBottomLeftRadius: 6,
73204
+ // backgroundColor: '#fff',
73205
+ // padding: '20px 20px 15px 20px',
73206
+ // boxShadow: '0 4px 24px 0 rgba(34, 41, 47, 0.1)',
73207
+ // minWidth: 300,
73208
+ // textAlign: 'center',
73209
+ // marginBottom: 15
73210
+ // }}
73211
+ // >
73212
+ // <div style={{ marginBottom: 8, display: 'flex', justifyContent: 'center' }}>
73213
+ // <Clock color="#ea5455" fontSize={32} />
73214
+ // </div>
73215
+ // <div style={{ fontWeight: 600, fontSize: 16, marginBottom: 4, color: '#5e5873' }}>
73216
+ // {msgContent}
73217
+ // </div>
73218
+ // <div style={{ color: '#6e6b7b', fontSize: 12, marginBottom: 16, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
73219
+ // <Clock fontSize={12} style={{ marginRight: 4 }} />
73220
+ // {moment(timeDisplay).calendar(null, {
73221
+ // lastDay: '[Hôm qua lúc] HH:mm',
73222
+ // sameDay: '[Hôm nay lúc] HH:mm',
73223
+ // nextDay: '[Ngày mai lúc] HH:mm',
73224
+ // lastWeek: 'dddd [lúc] HH:mm',
73225
+ // nextWeek: 'dddd [lúc] HH:mm',
73226
+ // sameElse: 'DD/MM/YYYY HH:mm'
73227
+ // })}
73228
+ // </div>
73229
+ // <div
73230
+ // style={{
73231
+ // border: '1px solid #00cfe8',
73232
+ // color: '#00cfe8',
73233
+ // padding: '8px',
73234
+ // borderRadius: 4,
73235
+ // cursor: 'pointer',
73236
+ // fontWeight: 600,
73237
+ // fontSize: 14,
73238
+ // width: '100%'
73239
+ // }}
73240
+ // onClick={() => {
73241
+ // setOpenModalReminder(true)
73242
+ // }}
73243
+ // >
73244
+ // Xem chi tiết
73245
+ // </div>
73246
+ // </div>
73247
+ // )
73248
+ // }, [])
73249
+ // const renderMessageReply = useCallback((type: IArchiveType, msg?: string, path?: any[]) => {
73250
+ // switch (type) {
73251
+ // case "file": // ✅ THÊM CASE NÀY
73252
+ // const fileName = path?.[0]?.name || ''
73253
+ // return `[File] ${fileName}`
73254
+ // case "image":
73255
+ // return "[Hình ảnh]"
73256
+ // default:
73257
+ // return msg
73258
+ // }
73259
+ // }, [])
73260
+ // const renderReplyContent = useCallback((replyMsg: any) => {
73261
+ // const replyData = useParsedChatData(replyMsg)
73262
+ // return (
73263
+ // <div
73264
+ // className={classnames("chat-app-reply p-0 mb-50", {
73265
+ // show: true
73266
+ // })}
73267
+ // >
73268
+ // <div className="reply-container">
73269
+ // <div className="reply-quote" />
73270
+ // {replyData?.type === "image" && (
73271
+ // <div
73272
+ // className="reply-image"
73273
+ // style={{
73274
+ // backgroundImage: `url(${`${CDN_URL_VIEW}/${replyData?.path[0].path.trim()}`})`
73275
+ // }}
73276
+ // />
73277
+ // )}
73278
+ // {/* ✅ THÊM: File */}
73279
+ // {replyData?.type === "file" && (
73280
+ // <div style={{ marginRight: 8 }}>
73281
+ // <IconFileTypeColor
73282
+ // fileType={replyData?.path?.[0]?.type}
73283
+ // width={35}
73284
+ // />
73285
+ // </div>
73286
+ // )}
73287
+ // <div className="reply-content d-flex flex-column">
73288
+ // <div className="fw-bold">{replyData?.createdByName}</div>
73289
+ // <div>{renderMessageReply(replyData?.type, replyData?.msg)}</div>
73290
+ // </div>
73291
+ // </div>
73292
+ // </div>
73293
+ // )
73294
+ // }, [renderMessageReply])
73295
+ // const downloadFile = useCallback(async (path: string) => {
73296
+ // const url = `${CDN_URL_VIEW}/${path}`
73297
+ // try {
73298
+ // const response = await axios.get(url, { responseType: "blob" })
73299
+ // const dataUrl = URL.createObjectURL(new Blob([response.data]))
73300
+ // const fileName = path.split("/").pop() || "downloaded-file"
73301
+ // const a = document.createElement("a")
73302
+ // a.href = dataUrl
73303
+ // a.download = fileName
73304
+ // document.body.appendChild(a)
73305
+ // a.click()
73306
+ // a.remove()
73307
+ // } catch (error) {
73308
+ // console.error(error)
73309
+ // }
73310
+ // }, [])
73311
+ // const handleDownloadClick = useCallback((param: any) => {
73312
+ // // Ưu tiên ảnh được click, fallback về ảnh đầu tiên
73313
+ // const targetFile = clickedImageFile || param?.path?.[0]
73314
+ // if (targetFile?.path) {
73315
+ // downloadFile(targetFile.path)
73316
+ // } else {
73317
+ // console.error("No valid path found in param")
73318
+ // }
73319
+ // }, [clickedImageFile, downloadFile])
73320
+ // const handleDelete = useCallback(async (param: any) => {
73321
+ // try {
73322
+ // const result = await MySwal.fire({
73323
+ // title: "Xác nhận",
73324
+ // html: "Tin nhắn sẽ bị xóa vĩnh viễn. <br> Bạn có chắc muốn xóa?",
73325
+ // allowOutsideClick: false,
73326
+ // showCancelButton: true,
73327
+ // confirmButtonText: "Xoá",
73328
+ // cancelButtonText: "Hủy",
73329
+ // customClass: {
73330
+ // confirmButton: "btn btn-primary",
73331
+ // cancelButton: "btn btn-danger ms-1"
73332
+ // },
73333
+ // buttonsStyling: false
73334
+ // })
73335
+ // if (result.value) {
73336
+ // const data = { id: param.id, chatRoomId: groupChatUsers.id }
73337
+ // await deleteMessageApi(data)
73338
+ // } else if (result.dismiss === MySwal.DismissReason.cancel) {
73339
+ // console.log("Hủy xóa tin nhắn")
73340
+ // }
73341
+ // } catch (error) {
73342
+ // console.error("Error deleting message:", error)
73343
+ // }
73344
+ // }, [deleteMessageApi, groupChatUsers?.id])
73345
+ // const handleRecall = useCallback(async (param: any) => {
73346
+ // try {
73347
+ // const result = await MySwal.fire({
73348
+ // title: "Xác nhận",
73349
+ // html: "Bạn có chắc muốn thu hồi tin nhắn này?<br>Tin nhắn sẽ bị ẩn với tất cả mọi người.",
73350
+ // allowOutsideClick: false,
73351
+ // showCancelButton: true,
73352
+ // confirmButtonText: "Thu hồi",
73353
+ // cancelButtonText: "Hủy",
73354
+ // customClass: {
73355
+ // confirmButton: "btn btn-primary",
73356
+ // cancelButton: "btn btn-danger ms-1"
73357
+ // },
73358
+ // buttonsStyling: false
73359
+ // })
73360
+ // if (result.value) {
73361
+ // const data = { id: param.id, chatRoomId: groupChatUsers.id }
73362
+ // await recallMessageApi(data)
73363
+ // } else if (result.dismiss === MySwal.DismissReason.cancel) {
73364
+ // console.log("Hủy thu hồi tin nhắn")
73365
+ // }
73366
+ // } catch (error) {
73367
+ // console.error("Error recalling message:", error)
73368
+ // }
73369
+ // }, [recallMessageApi, groupChatUsers?.id])
73370
+ // const contextMenuClick = useCallback(async (val: any) => {
73371
+ // switch (val.id) {
73372
+ // case "copyImage":
73373
+ // try {
73374
+ // // Ưu tiên ảnh được click, fallback về ảnh đầu tiên
73375
+ // const targetFile = clickedImageFile || val?.currentMessage?.path?.[0]
73376
+ // const imagePath = targetFile?.path
73377
+ // if (!imagePath) {
73378
+ // console.error('Không tìm thấy đường dẫn ảnh')
73379
+ // return
73380
+ // }
73381
+ // const imgUrl = `${CDN_URL_VIEW}/${imagePath}`
73382
+ // const response = await fetch(imgUrl)
73383
+ // const blob = await response.blob()
73384
+ // await navigator.clipboard.write([
73385
+ // new ClipboardItem({
73386
+ // [blob.type]: blob
73387
+ // })
73388
+ // ])
73389
+ // } catch (error) {
73390
+ // console.error('Lỗi khi copy ảnh:', error)
73391
+ // }
73392
+ // break
73393
+ // case "copyText":
73394
+ // navigator.clipboard.writeText(val?.currentMessage.msg)
73395
+ // break
73396
+ // case "reply":
73397
+ // setReplyMessage(val)
73398
+ // break
73399
+ // case "save":
73400
+ // handleDownloadClick(val.currentMessage)
73401
+ // break
73402
+ // case "delete":
73403
+ // handleDelete(val.currentMessage)
73404
+ // break
73405
+ // case "recall":
73406
+ // handleRecall(val.currentMessage)
73407
+ // break
73408
+ // default:
73409
+ // break
73410
+ // }
73411
+ // }, [clickedImageFile, handleDelete, handleDownloadClick, handleRecall])
73412
+ // const handleFocus = useCallback(() => {
73413
+ // editor.focus()
73414
+ // }, [editor])
73415
+ // const handleReply = useCallback((data: any) => {
73416
+ // handleFocus()
73417
+ // setReplyMessage({ id: "reply", currentMessage: data })
73418
+ // }, [handleFocus])
73419
+ // const handleEnterMultiSelectMode = useCallback((message: any) => {
73420
+ // setIsMultiSelectMode(true)
73421
+ // setSelectedMessages(new Set([message.id]))
73422
+ // }, [])
73423
+ // const handleExitMultiSelectMode = useCallback(() => {
73424
+ // setIsMultiSelectMode(false)
73425
+ // setSelectedMessages(new Set())
73426
+ // }, [])
73427
+ // const handleToggleMessageSelection = useCallback((messageId: string) => {
73428
+ // setSelectedMessages(prev => {
73429
+ // const newSet = new Set(prev)
73430
+ // if (newSet.has(messageId)) {
73431
+ // newSet.delete(messageId)
73432
+ // } else {
73433
+ // newSet.add(messageId)
73434
+ // }
73435
+ // return newSet
73436
+ // })
73437
+ // }, [])
73438
+ // const handleBatchDelete = useCallback(async () => {
73439
+ // if (selectedMessages.size === 0) { return }
73440
+ // MySwal.fire({
73441
+ // title: t("Confirm"),
73442
+ // html: `Bạn có chắc muốn xóa ${selectedMessages.size} tin nhắn đã chọn?`,
73443
+ // allowOutsideClick: false,
73444
+ // showCancelButton: true,
73445
+ // confirmButtonText: t("Delete"),
73446
+ // cancelButtonText: t("Cancel"),
73447
+ // customClass: {
73448
+ // confirmButton: "btn btn-primary",
73449
+ // cancelButton: "btn btn-danger ms-1"
73450
+ // },
73451
+ // buttonsStyling: false
73452
+ // }).then(async (result) => {
73453
+ // if (result.value) {
73454
+ // try {
73455
+ // const deletePromises = Array.from(selectedMessages).map(id => deleteMessageApi({ id, chatRoomId: groupChatUsers?.id })
73456
+ // )
73457
+ // await Promise.all(deletePromises)
73458
+ // handleExitMultiSelectMode()
73459
+ // } catch (error) {
73460
+ // console.error('Error deleting messages:', error)
73461
+ // }
73462
+ // }
73463
+ // })
73464
+ // }, [selectedMessages, deleteMessageApi, groupChatUsers?.id, handleExitMultiSelectMode, t])
73465
+ // const handleBatchRecall = useCallback(async () => {
73466
+ // if (selectedMessages.size === 0) { return }
73467
+ // MySwal.fire({
73468
+ // title: t("Confirm"),
73469
+ // html: `Bạn có chắc muốn thu hồi ${selectedMessages.size} tin nhắn đã chọn?`,
73470
+ // allowOutsideClick: false,
73471
+ // showCancelButton: true,
73472
+ // confirmButtonText: t("Recall"),
73473
+ // cancelButtonText: t("Cancel"),
73474
+ // customClass: {
73475
+ // confirmButton: "btn btn-primary",
73476
+ // cancelButton: "btn btn-danger ms-1"
73477
+ // },
73478
+ // buttonsStyling: false
73479
+ // }).then(async (result) => {
73480
+ // if (result.value) {
73481
+ // try {
73482
+ // const recallPromises = Array.from(selectedMessages).map(id => recallMessageApi({ id, chatRoomId: groupChatUsers?.id }))
73483
+ // await Promise.all(recallPromises)
73484
+ // handleExitMultiSelectMode()
73485
+ // } catch (error) {
73486
+ // console.error('Error recalling messages:', error)
73487
+ // }
73488
+ // }
73489
+ // })
73490
+ // }, [selectedMessages, recallMessageApi, groupChatUsers?.id, handleExitMultiSelectMode, t])
73491
+ // const handleBatchCopy = useCallback(async () => {
73492
+ // if (selectedMessages.size === 0) { return }
73493
+ // const getMessageContent = (msg: any) => {
73494
+ // if (!msg) { return '' }
73495
+ // const content = msg.msg || msg.content || ''
73496
+ // switch (msg.type) {
73497
+ // case "text":
73498
+ // return content
73499
+ // case "image":
73500
+ // return "[Hình ảnh]"
73501
+ // case "file":
73502
+ // const fileName = msg.path?.[0]?.name || ''
73503
+ // return `[File] ${fileName}`
73504
+ // case "reminder":
73505
+ // try {
73506
+ // const parsed = JSON.parse(content)
73507
+ // return parsed.content || content
73508
+ // } catch {
73509
+ // return content
73510
+ // }
73511
+ // default:
73512
+ // return content
73513
+ // }
73514
+ // }
73515
+ // const messages = Array.from(selectedMessages).map(id => {
73516
+ // // Find message in messageByGroup.items
73517
+ // if (!messageByGroup?.items) { return '' }
73518
+ // const msg = messageByGroup.items?.find((m: any) => m.id === id)
73519
+ // if (msg) { return getMessageContent(msg) }
73520
+ // return ''
73521
+ // }).filter(Boolean).join('\n\n')
73522
+ // if (!messages) {
73523
+ // notificationError('Không có nội dung để sao chép')
73524
+ // return
73525
+ // }
73526
+ // try {
73527
+ // // Tạo HTML content với line breaks rõ ràng cho Lexical
73528
+ // const htmlLines = messages.split('\n\n').map(msg => {
73529
+ // // Mỗi tin nhắn là một paragraph
73530
+ // return `<p class="editor-paragraph" dir="ltr"><span style="white-space: pre-wrap;">${msg.replace(/\n/g, '</span><br><span style="white-space: pre-wrap;">')}</span></p>`
73531
+ // }).join('')
73532
+ // const htmlContent = `<div>${htmlLines}</div>`
73533
+ // // Copy cả plain text và HTML
73534
+ // const html = new Blob([htmlContent], { type: 'text/html' })
73535
+ // const text = new Blob([messages], { type: 'text/plain' })
73536
+ // await navigator.clipboard.write([
73537
+ // new ClipboardItem({
73538
+ // 'text/html': html,
73539
+ // 'text/plain': text
73540
+ // })
73541
+ // ])
73542
+ // notificationSuccess('Đã sao chép tin nhắn')
73543
+ // } catch (err) {
73544
+ // // Fallback sang phương pháp cũ nếu Clipboard API thất bại
73545
+ // console.warn('Clipboard API failed, using fallback:', err)
73546
+ // try {
73547
+ // const textarea = document.createElement('textarea')
73548
+ // textarea.value = messages
73549
+ // textarea.style.position = 'fixed'
73550
+ // textarea.style.left = '-9999px'
73551
+ // textarea.style.top = '0'
73552
+ // textarea.setAttribute('readonly', '')
73553
+ // document.body.appendChild(textarea)
73554
+ // textarea.focus()
73555
+ // textarea.select()
73556
+ // const successful = document.execCommand('copy')
73557
+ // document.body.removeChild(textarea)
73558
+ // if (successful) {
73559
+ // notificationSuccess('Đã sao chép tin nhắn')
73560
+ // } else {
73561
+ // notificationError('Không thể sao chép tin nhắn')
73562
+ // }
73563
+ // } catch (fallbackErr) {
73564
+ // console.error('Fallback copy failed:', fallbackErr)
73565
+ // notificationError('Không thể sao chép tin nhắn')
73566
+ // }
73567
+ // } finally {
73568
+ // handleExitMultiSelectMode()
73569
+ // }
73570
+ // }, [selectedMessages, messageByGroup, handleExitMultiSelectMode])
73571
+ // const isNotificationType = (chatType: string) => {
73572
+ // return ["notifyAddUser", "notifyLeaveGroup", "reminder"].includes(chatType)
73573
+ // }
73574
+ // const renderChatBlock = useCallback((item: any) => {
73575
+ // const userAvatar2 = item && item.avatar ? item.avatar : DEFAULT_AVATAR
73576
+ // if (!item?.messages) { return null }
73577
+ // return (
73578
+ // <>
73579
+ // {item.messages?.map((chat: any, i: number) => {
73580
+ // const messageKey = chat?.id || `${item.id}-${i}`
73581
+ // return (
73582
+ // <div
73583
+ // key={messageKey}
73584
+ // className={classnames("chat", {
73585
+ // "chat-left": item.senderId !== dataProfile.id,
73586
+ // "chat-selected": isMultiSelectMode && selectedMessages.has(chat.id)
73587
+ // })}
73588
+ // style={{ position: 'relative' }}
73589
+ // onClick={() => {
73590
+ // if (isMultiSelectMode && chat.id && !isNotificationType(chat.type)) {
73591
+ // handleToggleMessageSelection(chat.id)
73592
+ // }
73593
+ // }}
73594
+ // >
73595
+ // {item.senderId !== dataProfile.id && i === item?.messages.length - 1 && (
73596
+ // <div className="chat-avatar " style={{ position: 'absolute', top: 10 }}>
73597
+ // <AvatarDefault
73598
+ // imgWidth={36}
73599
+ // imgHeight={36}
73600
+ // color="light-secondary"
73601
+ // className="cursor-pointer"
73602
+ // img={userAvatar2}
73603
+ // />
73604
+ // </div>
73605
+ // )}
73606
+ // {isMultiSelectMode && chat.id && !isNotificationType(chat.type) && (
73607
+ // <div
73608
+ // className="message-checkbox"
73609
+ // style={{
73610
+ // position: 'absolute',
73611
+ // left: item.senderId !== dataProfile.id ? '50px' : 'auto',
73612
+ // right: item.senderId === dataProfile.id ? '10px' : 'auto',
73613
+ // top: '50%',
73614
+ // transform: 'translateY(-50%)',
73615
+ // zIndex: 5
73616
+ // }}
73617
+ // onClick={(e) => {
73618
+ // e.stopPropagation()
73619
+ // handleToggleMessageSelection(chat.id)
73620
+ // }}
73621
+ // >
73622
+ // <div
73623
+ // style={{
73624
+ // width: 22,
73625
+ // height: 22,
73626
+ // borderRadius: '50%',
73627
+ // border: selectedMessages.has(chat.id) ? '2px solid #7367f0' : '2px solid #d8d6de',
73628
+ // backgroundColor: selectedMessages.has(chat.id) ? '#7367f0' : '#fff',
73629
+ // display: 'flex',
73630
+ // alignItems: 'center',
73631
+ // justifyContent: 'center',
73632
+ // cursor: 'pointer',
73633
+ // transition: 'all 0.2s ease'
73634
+ // }}
73635
+ // >
73636
+ // {selectedMessages.has(chat.id) && (
73637
+ // <svg width="14" height="14" viewBox="0 0 24 24" fill="none">
73638
+ // <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" fill="white"/>
73639
+ // </svg>
73640
+ // )}
73641
+ // </div>
73642
+ // </div>
73643
+ // )}
73644
+ // <div className="chat-body">
73645
+ // <div
73646
+ // key={i}
73647
+ // id={chat.id ? `msg-${chat.id}` : undefined}
73648
+ // className={classnames(
73649
+ // "d-flex align-items-end chat-message-item",
73650
+ // {
73651
+ // "justify-content-end": item.senderId === dataProfile.id && !isNotificationType(chat.type),
73652
+ // "justify-content-center": isNotificationType(chat.type),
73653
+ // 'ms-3': true
73654
+ // }
73655
+ // )}
73656
+ // >
73657
+ // {!isNotificationType(chat.type) && (
73658
+ // <div
73659
+ // className="message-action"
73660
+ // style={{
73661
+ // order: item.senderId !== dataProfile.id ? 1 : 0
73662
+ // }}
73663
+ // >
73664
+ // <div
73665
+ // className={classnames(
73666
+ // "d-flex align-items-center px-1 py-50 mb-75 ",
73667
+ // {
73668
+ // "me-1": item.senderId === dataProfile.id,
73669
+ // "ms-1": item.senderId !== dataProfile.id
73670
+ // }
73671
+ // )}
73672
+ // style={{
73673
+ // background: "#fff",
73674
+ // borderRadius: 6
73675
+ // }}
73676
+ // >
73677
+ // <QuoteRight
73678
+ // onClick={() => handleReply(chat)}
73679
+ // fontSize={14}
73680
+ // className="me-1 cursor-pointer btn-action"
73681
+ // />
73682
+ // <OutlineReply
73683
+ // fontSize={20}
73684
+ // className="me-1 cursor-pointer btn-action"
73685
+ // onClick={() => {
73686
+ // setShareItem(chat)
73687
+ // setOpenModalShare(true)
73688
+ // }}
73689
+ // />
73690
+ // <DMenuContainer
73691
+ // label=""
73692
+ // customLabel={<MoreHorizontal />}
73693
+ // className="btn-action"
73694
+ // >
73695
+ // {chat.type === "LeaveApplication" && (
73696
+ // <DMenuItem
73697
+ // label="Duyệt"
73698
+ // icon={
73699
+ // <CheckSquare
73700
+ // color="gray"
73701
+ // fontSize={16}
73702
+ // className="me-50"
73703
+ // />
73704
+ // }
73705
+ // />
73706
+ // )}
73707
+ // {chat.type !== "LeaveApplication" && (
73708
+ // <DMenuItem
73709
+ // onClick={() => navigator.clipboard.writeText(chat?.msg)
73710
+ // }
73711
+ // label="Copy tin nhắn"
73712
+ // icon={
73713
+ // <Copy
73714
+ // color="gray"
73715
+ // fontSize={16}
73716
+ // className="me-50"
73717
+ // />
73718
+ // }
73719
+ // />
73720
+ // )}
73721
+ // <hr style={{ margin: "3px 12px" }} />
73722
+ // <DMenuItem
73723
+ // label="Ghim tin nhắn"
73724
+ // icon={
73725
+ // <Clock
73726
+ // color="gray"
73727
+ // fontSize={16}
73728
+ // className="me-50"
73729
+ // />
73730
+ // }
73731
+ // onClick={() => {
73732
+ // if (chat?.id && chatRoomId) {
73733
+ // const item = {
73734
+ // id: chatRoomId,
73735
+ // content: JSON.stringify(chat)
73736
+ // }
73737
+ // pinMessageChatRoom(item)
73738
+ // }
73739
+ // }}
73740
+ // />
73741
+ // <DMenuItem
73742
+ // label="Đánh dấu tin nhắn"
73743
+ // icon={
73744
+ // <Star
73745
+ // color="gray"
73746
+ // fontSize={16}
73747
+ // className="me-50"
73748
+ // />
73749
+ // }
73750
+ // />
73751
+ // <DMenuItem
73752
+ // label="Lưu về máy"
73753
+ // icon={
73754
+ // <Download
73755
+ // color="gray"
73756
+ // fontSize={16}
73757
+ // className="me-50"
73758
+ // />
73759
+ // }
73760
+ // onClick={() => handleDownloadClick(chat)}
73761
+ // />
73762
+ // <DMenuItem
73763
+ // label="Chọn nhiều tin nhắn"
73764
+ // icon={
73765
+ // <ListCheck
73766
+ // color="gray"
73767
+ // fontSize={16}
73768
+ // className="me-50"
73769
+ // />
73770
+ // }
73771
+ // onClick={() => handleEnterMultiSelectMode(chat)}
73772
+ // />
73773
+ // <DMenuItem
73774
+ // label="Xem chi tiết"
73775
+ // icon={
73776
+ // <InfoCircle
73777
+ // color="gray"
73778
+ // fontSize={16}
73779
+ // className="me-50"
73780
+ // />
73781
+ // }
73782
+ // />
73783
+ // <DMenu label="Tùy chọn khác">
73784
+ // <DMenuItem
73785
+ // label="Giao việc"
73786
+ // icon={
73787
+ // <CheckSquare
73788
+ // color="gray"
73789
+ // fontSize={16}
73790
+ // className="me-50"
73791
+ // />
73792
+ // }
73793
+ // />
73794
+ // <DMenuItem
73795
+ // label="Tạo nhắc hẹn"
73796
+ // icon={
73797
+ // <Clock
73798
+ // color="gray"
73799
+ // fontSize={16}
73800
+ // className="me-50"
73801
+ // />
73802
+ // }
73803
+ // onClick={() => setOpenModalReminder(true)}
73804
+ // />
73805
+ // </DMenu>
73806
+ // <hr style={{ margin: "3px 12px" }} />
73807
+ // <DMenuItem
73808
+ // label="Xóa tin nhắn"
73809
+ // icon={
73810
+ // <Trash2
73811
+ // color="red"
73812
+ // fontSize={16}
73813
+ // className="me-50"
73814
+ // />
73815
+ // }
73816
+ // style={{ color: "red" }}
73817
+ // onClick={() => handleDelete(chat)}
73818
+ // />
73819
+ // </DMenuContainer>
73820
+ // </div>
73821
+ // </div>
73822
+ // )}
73823
+ // <div
73824
+ // id={chat.type === "attachment" ? `image-${i}` : `text-${i}`}
73825
+ // className={
73826
+ // chat.type === "notifyAddUser" ? classnames("chat-content px-1") : classnames("chat-content p-1")
73827
+ // }
73828
+ // onContextMenu={(event: any) => onContextMenu(event, chat)}
73829
+ // >
73830
+ // {item?.senderId !== dataProfile?.id &&
73831
+ // groupChatUsers?.type === "multi" &&
73832
+ // !isNotificationType(chat.type) && (
73833
+ // <div>
73834
+ // <span style={{ color: "gray" }}>
73835
+ // {item?.user?.name}
73836
+ // </span>
73837
+ // </div>
73838
+ // )}
73839
+ // {chat.replyContent && renderReplyContent(chat.replyContent)}
73840
+ // {chat.status === 1 ? (
73841
+ // <div className="chat-message" style={{
73842
+ // fontStyle: 'italic',
73843
+ // color: '#999',
73844
+ // padding: '8px 12px'
73845
+ // }}>
73846
+ // Tin nhắn đã được thu hồi
73847
+ // </div>
73848
+ // ) : (
73849
+ // <>
73850
+ // {chat.type === "text" && (
73851
+ // <div className="chat-message">{renderChatText(chat)}</div>
73852
+ // )}
73853
+ // {chat.type === "file" && (
73854
+ // <div className="chat-message__image">
73855
+ // {renderChatFile(chat)}
73856
+ // </div>
73857
+ // )}
73858
+ // </>
73859
+ // )}
73860
+ // {chat.type === "notifyLeaveGroup" && (
73861
+ // <div className="" style={{ marginTop: "5px" }}>
73862
+ // {renderNotifyLeaveGroup(chat)}
73863
+ // </div>
73864
+ // )}
73865
+ // {chat.type === "notifyAddUser" && (
73866
+ // <div className="" style={{ marginTop: "5px" }}>
73867
+ // {renderChatNotification(chat)}
73868
+ // </div>
73869
+ // )}
73870
+ // {chat.status !== 1 && (
73871
+ // <>
73872
+ // {chat.type === "image" && (
73873
+ // <div className="chat-message__image">
73874
+ // {renderChatImage(chat)}
73875
+ // </div>
73876
+ // )}
73877
+ // {/* {chat.type === "leaveApplication" && (
73878
+ // <div className="chat-message__image">
73879
+ // {renderChatApplication(chat)}
73880
+ // </div>
73881
+ // )}
73882
+ // {chat.type === "lateEarly" && (
73883
+ // <div className="chat-message__image">
73884
+ // {renderChatApplication(chat)}
73885
+ // </div>
73886
+ // )}
73887
+ // {chat.type === "registerCars" && (
73888
+ // <div className="chat-message__image">
73889
+ // {renderChatApplication(chat)}
73890
+ // </div>
73891
+ // )}
73892
+ // {chat.type === "mission" && (
73893
+ // <div className="chat-message__image">
73894
+ // {renderChatApplication(chat)}
73895
+ // </div>
73896
+ // )}
73897
+ // {chat.type === "overtime" && (
73898
+ // <div className="chat-message__image">
73899
+ // {renderChatApplication(chat)}
73900
+ // </div>
73901
+ // )}
73902
+ // {chat.type === "advancePays" && (
73903
+ // <div className="chat-message__image">
73904
+ // {renderChatApplication(chat)}
73905
+ // </div>
73906
+ // )}
73907
+ // {chat.type === "pay" && (
73908
+ // <div className="chat-message__image">
73909
+ // {renderChatApplication(chat)}
73910
+ // </div>
73911
+ // )}
73912
+ // {chat.type === "shiftChange" && (
73913
+ // <div className="chat-message__image">
73914
+ // {renderChatApplication(chat)}
73915
+ // </div>
73916
+ // )}
73917
+ // {chat.type === "attendanceExplanation" && (
73918
+ // <div className="chat-message__image">
73919
+ // {renderChatApplication(chat)}
73920
+ // </div>
73921
+ // )} */}
73922
+ // {(chat.type === "TASK" || chat.type === "voucher") && (
73923
+ // <div className="chat-message__image">
73924
+ // {renderTaskApplication(chat)}
73925
+ // </div>
73926
+ // )}
73927
+ // {chat.type === "reminder" && (
73928
+ // <div className="chat-message__image">
73929
+ // {renderChatReminder(chat)}
73930
+ // </div>
73931
+ // )}
73932
+ // </>
73933
+ // )}
73934
+ // </div>
73935
+ // </div>
73936
+ // </div>
73937
+ // </div>
73938
+ // )
73939
+ // })}
73940
+ // </>
73941
+ // )
73942
+ // }, [
73943
+ // dataProfile?.id,
73944
+ // groupChatUsers?.type,
73945
+ // handleDelete,
73946
+ // handleDownloadClick,
73947
+ // handleReply,
73948
+ // isNotificationType,
73949
+ // onContextMenu,
73950
+ // //renderChatApplication,
73951
+ // renderChatFile,
73952
+ // renderChatImage,
73953
+ // renderChatNotification,
73954
+ // renderChatText,
73955
+ // renderNotifyLeaveGroup,
73956
+ // renderReplyContent,
73957
+ // renderChatReminder,
73958
+ // isMultiSelectMode,
73959
+ // selectedMessages,
73960
+ // handleToggleMessageSelection,
73961
+ // handleEnterMultiSelectMode
73962
+ // ])
73963
+ // const handleOpenAddMember = () => {
73964
+ // setTypeOpenModalAdd(!typeOpenModalAdd)
73965
+ // if (groupChatUsers && groupChatUsers.type === "single") {
73966
+ // handleModalGroup()
73967
+ // } else {
73968
+ // handleModalAddUserGroup()
73969
+ // }
73970
+ // }
73971
+ // const handlePaste = (event: any) => {
73972
+ // event.preventDefault()
73973
+ // const items = event.clipboardData.items
73974
+ // // Duyệt qua các item trong clipboard
73975
+ // // eslint-disable-next-line no-restricted-syntax
73976
+ // for (const item of items) {
73977
+ // // Nếu item là dạng file (image)
73978
+ // if (item.type.indexOf("image") !== -1) {
73979
+ // const file = item.getAsFile()
73980
+ // const reader = new FileReader()
73981
+ // reader.onload = function onLoad(e) {
73982
+ // setImgCopy((prevImages: any) => [...prevImages, { id: newGuid(), data: e?.target?.result, name: file?.name }])
73983
+ // }
73984
+ // if (file) {
73985
+ // reader.readAsDataURL(file)
73986
+ // }
73987
+ // }
73988
+ // }
73989
+ // }
73990
+ // const virtualList = useMemo(() => {
73991
+ // const grouped = formatMessage(sortByDateFast(messageByGroup?.items, 'createdDate') || [], groupChatUsers)
73992
+ // const result: Array<{
73993
+ // type: "header" | "item";
73994
+ // header?: string;
73995
+ // item?: any;
73996
+ // }> = []
73997
+ // grouped.forEach((d: any) => {
73998
+ // d.items.forEach((it: any) => result.push({ type: "item", item: it }))
73999
+ // result.push({
74000
+ // type: "header",
74001
+ // header: formatGroupDate(d.day)
74002
+ // })
74003
+ // })
74004
+ // return result
74005
+ // }, [messageByGroup, groupChatUsers])
74006
+ // const loadMore = useCallback(() => {
74007
+ // setScroll(true)
74008
+ // if (!hasMore || !chatRoomId) { return }
74009
+ // setIsFetching(true)
74010
+ // setHasMore(false)
74011
+ // get_message_by_group_cursor_api({
74012
+ // chatRoomId,
74013
+ // after: messageByGroup?.cursor?.afterCursor,
74014
+ // size: 20
74015
+ // })
74016
+ // .unwrap()
74017
+ // .then((response: any) => {
74018
+ // dispatch(setMessageByGroup(response))
74019
+ // })
74020
+ // .finally(() => {
74021
+ // setIsFetching(false)
74022
+ // setHasMore(true)
74023
+ // })
74024
+ // if (messageByGroup?.totalCount) {
74025
+ // setHasMore(false)
74026
+ // }
74027
+ // }, [
74028
+ // chatRoomId,
74029
+ // dispatch,
74030
+ // get_message_by_group_cursor_api,
74031
+ // hasMore,
74032
+ // messageByGroup,
74033
+ // setScroll
74034
+ // ])
74035
+ // const currentMessageCount = messageByGroup?.items?.length ?? 0
74036
+ // const totalMessageCount = messageByGroup?.totalCount ?? 0
74037
+ // const canLoadMore = useMemo(() => {
74038
+ // return hasMore && currentMessageCount < totalMessageCount
74039
+ // }, [hasMore, currentMessageCount, totalMessageCount])
74040
+ // const handleClearAllImages = () => {
74041
+ // setImgCopy([])
74042
+ // }
74043
+ // const isFileLike = (v: any) => v && typeof v === 'object' && 'name' in v && ('size' in v || 'type' in v)
74044
+ // const getFileExtension = (item: any): string => {
74045
+ // if (!item) { return '' }
74046
+ // // Data URL
74047
+ // if (typeof item === 'string' && item.startsWith('data:')) {
74048
+ // const semi = item.indexOf(';')
74049
+ // if (semi === -1) { return '' }
74050
+ // const mime = item.slice(5, semi).toLowerCase()
74051
+ // return MIME_EXT_MAP[mime] || mime.split('/').pop() || ''
74052
+ // }
74053
+ // // Real File or file-like object
74054
+ // if (item instanceof File || isFileLike(item)) {
74055
+ // // Prefer name
74056
+ // const name: string = item.name || ''
74057
+ // const m = name.match(/(\.[a-z0-9]+)$/)
74058
+ // if (m) { return m[1].toLowerCase() }
74059
+ // // Fallback to MIME if name has no dot
74060
+ // const mime: string = (item.type || '').toLowerCase()
74061
+ // if (mime) { return MIME_EXT_MAP[mime] || mime.split('/').pop() || '' }
74062
+ // }
74063
+ // return ''
74064
+ // }
74065
+ // const isImageItem = (item: any) => {
74066
+ // const data = item?.data || item
74067
+ // if (typeof data === 'string') { return data.startsWith('data:image') }
74068
+ // return data instanceof File ? data.type?.startsWith('image') : false
74069
+ // }
74070
+ // const previewCounts = useMemo(() => {
74071
+ // let image = 0
74072
+ // let file = 0
74073
+ // imgCopy.forEach((it: any) => (isImageItem(it) ? image++ : file++))
74074
+ // return { image, file }
74075
+ // }, [imgCopy])
74076
+ // const handlePickAny = (e: React.ChangeEvent<HTMLInputElement>) => {
74077
+ // const files = Array.from(e.target.files || [])
74078
+ // if (files.length) {
74079
+ // const filesWithId = files.map(file => ({ id: newGuid(), data: file }))
74080
+ // setImgCopy((prev: any[]) => [...prev, ...filesWithId])
74081
+ // }
74082
+ // // reset để lần sau chọn cùng file vẫn trigger onChange
74083
+ // e.target.value = ''
74084
+ // }
74085
+ // const allPaths = useMemo(() => {
74086
+ // if (!openModalPreview) { return [] }
74087
+ // const collected: any[] = []
74088
+ // // Add imgCopy items (pending images before sending)
74089
+ // if (imgCopy && imgCopy.length > 0) {
74090
+ // imgCopy.forEach((item: any) => {
74091
+ // const data = item?.data || item
74092
+ // const isImage = (typeof data === 'string' && data.startsWith('data:image')) || (data instanceof File && data.type?.startsWith('image'))
74093
+ // if (isImage) {
74094
+ // let path = ''
74095
+ // if (typeof data === 'string') {
74096
+ // path = data
74097
+ // } else if (data instanceof File) {
74098
+ // path = URL.createObjectURL(data)
74099
+ // }
74100
+ // if (path) {
74101
+ // collected.push({
74102
+ // id: item.id || newGuid(),
74103
+ // path,
74104
+ // type: '.jpg',
74105
+ // name: (data instanceof File ? data.name : 'image'),
74106
+ // isBase64: true,
74107
+ // createdDate: new Date().toISOString()
74108
+ // })
74109
+ // }
74110
+ // }
74111
+ // })
74112
+ // }
74113
+ // // Add existing messages from chat
74114
+ // virtualList.forEach((entry: any) => {
74115
+ // if (entry.type !== 'item' || !entry.item?.messages) { return }
74116
+ // entry.item.messages.forEach((msg: any) => {
74117
+ // if (!Array.isArray(msg.path) || msg.path.length === 0) { return }
74118
+ // const sortedPaths = [...msg.path].sort(
74119
+ // (a: any, b: any) => new Date(a.createdDate).getTime() - new Date(b.createdDate).getTime()
74120
+ // )
74121
+ // sortedPaths.forEach((p: any) => collected.push({ ...p }))
74122
+ // })
74123
+ // })
74124
+ // return collected.reverse()
74125
+ // }, [openModalPreview, virtualList, imgCopy])
74126
+ // const handleChatScroll = useCallback(() => {
74127
+ // const container = document.getElementById("scrollableDivChat")
74128
+ // if (!container) { return }
74129
+ // const threshold = -(window.innerHeight - 250)
74130
+ // if (container.scrollTop < threshold) {
74131
+ // setIsAtBottom(false)
74132
+ // }
74133
+ // if (container.scrollTop > threshold) {
74134
+ // setIsAtBottom(true)
74135
+ // }
74136
+ // }, [])
74137
+ // // Thêm state mới
74138
+ // const chatListContent = useMemo(() => (
74139
+ // <InfiniteScroll
74140
+ // //dataLength={totalMessages}
74141
+ // dataLength={messageByGroup?.items ? messageByGroup?.items.length : 0}
74142
+ // next={loadMore}
74143
+ // inverse
74144
+ // hasMore={canLoadMore}
74145
+ // scrollableTarget="scrollableDivChat"
74146
+ // onScroll={handleChatScroll}
74147
+ // scrollThreshold={20}
74148
+ // loader={
74149
+ // isFetching ? (
74150
+ // <div
74151
+ // style={{
74152
+ // padding: "1rem",
74153
+ // textAlign: "center"
74154
+ // }}
74155
+ // >
74156
+ // {"Đang tải tin nhắn..."}
74157
+ // </div>
74158
+ // ) : (
74159
+ // <></>
74160
+ // )
74161
+ // }
74162
+ // style={{
74163
+ // display: "flex", // Khi collapsed (true) thì hiển thị
74164
+ // flexDirection: "column-reverse"
74165
+ // }}
74166
+ // initialScrollY={0}
74167
+ // className={'chats'}
74168
+ // >
74169
+ // {virtualList.map((it, index) => {
74170
+ // if (it.type === "header") {
74171
+ // return <DateHeader key={`header-${index}`} label={it.header as string} />
74172
+ // }
74173
+ // return renderChatBlock(it.item)
74174
+ // })}
74175
+ // </InfiniteScroll>
74176
+ // ), [canLoadMore, handleChatScroll, isFetching, loadMore, renderChatBlock, virtualList, isPinnedCollapsed])
74177
+ // // Handler cho collapse change
74178
+ // const handlePinnedCollapseChange = useCallback((collapsed: boolean) => {
74179
+ // setIsPinnedCollapsed(collapsed)
74180
+ // }, [])
74181
+ // const renderAvatarGroup = () => {
74182
+ // if (groupChatUsers) {
74183
+ // const { type, avatar, users } = groupChatUsers
74184
+ // if (type === 'single' || (type === 'multi' && avatar)) {
74185
+ // return (
74186
+ // <AvatarDefault
74187
+ // imgHeight={56}
74188
+ // imgWidth={56}
74189
+ // img={avatar}
74190
+ // color={'light-secondary'}
74191
+ // className='avatar-border pull-up user-profile-toggle m-0'
74192
+ // //onClick={handleModalGroupInfo}
74193
+ // />
74194
+ // )
74195
+ // }
74196
+ // if (type === 'multi' && users) {
74197
+ // return (
74198
+ // <AvatarGroup2
74199
+ // groupClassName={'avatar-group-chat'}
74200
+ // avatarClassName={'pull-up'}
74201
+ // data={users.map((it: any) => ({ ...it, img: it.avatar }))}
74202
+ // containerWidth={56}
74203
+ // />
74204
+ // )
74205
+ // }
74206
+ // }
74207
+ // return null
74208
+ // }
71795
74209
  return (jsx("div", { id: "chat-app-window", className: "chat-app-window", ref: containerChatRef, children: jsxs("div", { className: classnames("start-chat-area", {
71796
74210
  "d-none": contactId || chatRoomId
71797
74211
  }), children: [jsx("div", { className: "start-chat-icon mb-1", children: jsx(SvgMessageSquare, {}) }), jsx("h4", { className: "sidebar-toggle start-chat-text", children: "B\u1EAFt \u0111\u1EA7u tr\u00F2 chuy\u1EC7n" })] }) }));