@esvndev/es-react-template-chat 0.0.92 → 0.0.94

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.js CHANGED
@@ -21,6 +21,14 @@ require('@draft-js-plugins/mention/lib/plugin.css');
21
21
  require('@draft-js-plugins/emoji/lib/plugin.css');
22
22
  var reactRedux = require('react-redux');
23
23
  var configureStore$1 = require('@store/configureStore');
24
+ var photo = require('@core/assets/images/icons/file-icons/icon-photo.svg');
25
+ var word = require('@core/assets/images/icons/file-icons/icon-word.svg');
26
+ var excel = require('@core/assets/images/icons/file-icons/icon-excel.svg');
27
+ var ppt = require('@core/assets/images/icons/file-icons/icon-powerpoint.svg');
28
+ var music = require('@core/assets/images/icons/file-icons/icon-music.svg');
29
+ var video = require('@core/assets/images/icons/file-icons/icon-video.svg');
30
+ var pdf = require('@core/assets/images/icons/file-icons/icon-pdf.svg');
31
+ var zip = require('@core/assets/images/icons/file-icons/icon-zip.svg');
24
32
  var reactRouterDom = require('react-router-dom');
25
33
 
26
34
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -49,6 +57,14 @@ var ReactDOM__namespace = /*#__PURE__*/_interopNamespace(ReactDOM);
49
57
  var ReactDOM__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOM);
50
58
  var toast__default = /*#__PURE__*/_interopDefaultLegacy(toast);
51
59
  var avatarDefault__default = /*#__PURE__*/_interopDefaultLegacy(avatarDefault);
60
+ var photo__default = /*#__PURE__*/_interopDefaultLegacy(photo);
61
+ var word__default = /*#__PURE__*/_interopDefaultLegacy(word);
62
+ var excel__default = /*#__PURE__*/_interopDefaultLegacy(excel);
63
+ var ppt__default = /*#__PURE__*/_interopDefaultLegacy(ppt);
64
+ var music__default = /*#__PURE__*/_interopDefaultLegacy(music);
65
+ var video__default = /*#__PURE__*/_interopDefaultLegacy(video);
66
+ var pdf__default = /*#__PURE__*/_interopDefaultLegacy(pdf);
67
+ var zip__default = /*#__PURE__*/_interopDefaultLegacy(zip);
52
68
 
53
69
  var instances = 'ej2_instances';
54
70
  var uid = 0;
@@ -27397,6 +27413,16 @@ const encodeUUID = (uuid) => {
27397
27413
  return uuid;
27398
27414
  }
27399
27415
  };
27416
+ const formatBytes = (props, decimals = 2) => {
27417
+ if (!+props.size) {
27418
+ return '0 Bytes';
27419
+ }
27420
+ const k = 1024;
27421
+ const dm = decimals < 0 ? 0 : decimals;
27422
+ const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
27423
+ const i = Math.floor(Math.log(props.size) / Math.log(k));
27424
+ return `${parseFloat((props.size / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
27425
+ };
27400
27426
  const isValidUrl = (string) => {
27401
27427
  try {
27402
27428
  // eslint-disable-next-line no-new
@@ -36746,6 +36772,14 @@ var SvgBell = function (_a) {
36746
36772
  React__namespace.createElement("path", { d: "M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9M13.73 21a2 2 0 0 1-3.46 0" })));
36747
36773
  };
36748
36774
 
36775
+ var SvgClock = function (_a) {
36776
+ var title = _a.title, titleId = _a.titleId, props = __rest(_a, ["title", "titleId"]);
36777
+ return (React__namespace.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: "clock_svg__feather clock_svg__feather-clock", "aria-labelledby": titleId }, props),
36778
+ title ? React__namespace.createElement("title", { id: titleId }, title) : null,
36779
+ React__namespace.createElement("circle", { cx: 12, cy: 12, r: 10 }),
36780
+ React__namespace.createElement("path", { d: "M12 6v6l4 2" })));
36781
+ };
36782
+
36749
36783
  var SvgCopy = function (_a) {
36750
36784
  var title = _a.title, titleId = _a.titleId, props = __rest(_a, ["title", "titleId"]);
36751
36785
  return (React__namespace.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: "copy_svg__feather copy_svg__feather-copy", "aria-labelledby": titleId }, props),
@@ -72044,6 +72078,167 @@ const useUploadFile = () => {
72044
72078
  };
72045
72079
  };
72046
72080
 
72081
+ const IconFileTypeColor = (props) => {
72082
+ const { fileType, width, height } = props;
72083
+ const normalizedType = typeof fileType === 'string' ? fileType.toLowerCase() : '';
72084
+ let icon;
72085
+ switch (normalizedType) {
72086
+ case '.jpg':
72087
+ case '.jpeg':
72088
+ case '.png':
72089
+ icon = photo__default["default"];
72090
+ break;
72091
+ case '.mp3':
72092
+ case '.wma':
72093
+ case '.wma9':
72094
+ case '.wav':
72095
+ case '.flac':
72096
+ case '.aac':
72097
+ case '.aac+':
72098
+ case '.ogg':
72099
+ case '.aiff':
72100
+ case '.lossless':
72101
+ case '.amr':
72102
+ case '.ac3':
72103
+ icon = music__default["default"];
72104
+ break;
72105
+ case '.avi':
72106
+ case '.mp4':
72107
+ case '.mkv':
72108
+ case '.wmv':
72109
+ case '.vob':
72110
+ case '.flv':
72111
+ case '.webm':
72112
+ case '.3gp':
72113
+ case '.mpeg':
72114
+ icon = video__default["default"];
72115
+ break;
72116
+ case '.pdf':
72117
+ icon = pdf__default["default"];
72118
+ break;
72119
+ case '.ppt':
72120
+ icon = ppt__default["default"];
72121
+ break;
72122
+ case '.xlsx':
72123
+ icon = excel__default["default"];
72124
+ break;
72125
+ case '.doc':
72126
+ case '.docx':
72127
+ icon = word__default["default"];
72128
+ break;
72129
+ case '.zip':
72130
+ case '.rar':
72131
+ icon = zip__default["default"];
72132
+ break;
72133
+ default:
72134
+ icon = '';
72135
+ break;
72136
+ }
72137
+ // if (fileType === "aac") {
72138
+ // icon = "FiletypeAac"
72139
+ // } else if (fileType === ".ai") {
72140
+ // icon = "FiletypeAi"
72141
+ // } else if (fileType === ".bmp") {
72142
+ // icon = "FiletypeBmp"
72143
+ // } else if (fileType === ".cs") {
72144
+ // icon = "FiletypeCs"
72145
+ // } else if (fileType === ".css") {
72146
+ // icon = "FiletypeCss"
72147
+ // } else if (fileType === ".csv") {
72148
+ // icon = "FiletypeCsv"
72149
+ // } else if (fileType === ".doc") {
72150
+ // icon = "FiletypeDoc"
72151
+ // } else if (fileType === ".docx") {
72152
+ // icon = "FiletypeDocx"
72153
+ // } else if (fileType === ".exe") {
72154
+ // icon = "FiletypeExe"
72155
+ // } else if (fileType === ".gif") {
72156
+ // icon = "FiletypeGif"
72157
+ // } else if (fileType === ".heic") {
72158
+ // icon = "FiletypeHeic"
72159
+ // } else if (fileType === ".html") {
72160
+ // icon = "FiletypeHtml"
72161
+ // } else if (fileType === ".java") {
72162
+ // icon = "FiletypeJava"
72163
+ // } else if (fileType === ".jpg" || fileType === ".jpeg") {
72164
+ // icon = "Image"
72165
+ // } else if (fileType === ".js") {
72166
+ // icon = "FiletypeJs"
72167
+ // } else if (fileType === ".json") {
72168
+ // icon = "FiletypeJson"
72169
+ // } else if (fileType === ".jsx") {
72170
+ // icon = "FiletypeJsx"
72171
+ // } else if (fileType === ".key") {
72172
+ // icon = "FiletypeKey"
72173
+ // } else if (fileType === ".m4p") {
72174
+ // icon = "FiletypeM4p"
72175
+ // } else if (fileType === ".md") {
72176
+ // icon = "FiletypeMd"
72177
+ // } else if (fileType === ".mdx") {
72178
+ // icon = "FiletypeMdx"
72179
+ // } else if (fileType === ".mov") {
72180
+ // icon = "FiletypeMov"
72181
+ // } else if (fileType === ".mp3") {
72182
+ // icon = "FiletypeMp3"
72183
+ // } else if (fileType === ".mp4") {
72184
+ // icon = "FiletypeMp4"
72185
+ // } else if (fileType === ".otf") {
72186
+ // icon = "FiletypeOtf"
72187
+ // } else if (fileType === ".pdf") {
72188
+ // icon = "FiletypePdf"
72189
+ // } else if (fileType === ".php") {
72190
+ // icon = "FiletypePhp"
72191
+ // } else if (fileType === ".png") {
72192
+ // icon = "Image"
72193
+ // } else if (fileType === ".ppt") {
72194
+ // icon = "FiletypePpt"
72195
+ // } else if (fileType === ".pptx") {
72196
+ // icon = "FiletypePptx"
72197
+ // } else if (fileType === ".psd") {
72198
+ // icon = "FiletypePsd"
72199
+ // } else if (fileType === ".py") {
72200
+ // icon = "FiletypePy"
72201
+ // } else if (fileType === ".raw") {
72202
+ // icon = "FiletypeRaw"
72203
+ // } else if (fileType === ".rb") {
72204
+ // icon = "FiletypeRb"
72205
+ // } else if (fileType === ".sass") {
72206
+ // icon = "FiletypeSass"
72207
+ // } else if (fileType === ".scss") {
72208
+ // icon = "FiletypeScss"
72209
+ // } else if (fileType === ".sh") {
72210
+ // icon = "FiletypeSh"
72211
+ // } else if (fileType === ".sql") {
72212
+ // icon = "FiletypeSql"
72213
+ // } else if (fileType === ".svg") {
72214
+ // icon = "FiletypeSvg"
72215
+ // } else if (fileType === ".tiff") {
72216
+ // icon = "FiletypeTiff"
72217
+ // } else if (fileType === ".tsx") {
72218
+ // icon = "FiletypeTsx"
72219
+ // } else if (fileType === ".ttf") {
72220
+ // icon = "FiletypeTtf"
72221
+ // } else if (fileType === ".txt") {
72222
+ // icon = "FiletypeTxt"
72223
+ // } else if (fileType === ".wav") {
72224
+ // icon = "FiletypeWav"
72225
+ // } else if (fileType === ".woff") {
72226
+ // icon = "FiletypeWoff"
72227
+ // } else if (fileType === ".xls") {
72228
+ // icon = "FiletypeXls"
72229
+ // } else if (fileType === ".xlsx") {
72230
+ // icon = "FiletypeXlsx"
72231
+ // } else if (fileType === ".xml") {
72232
+ // icon = "FiletypeXml"
72233
+ // } else if (fileType === ".yml") {
72234
+ // icon = "FiletypeYml"
72235
+ // } else if (fileType === ".zip" || fileType === ".rar") {
72236
+ // icon = "FileZip"
72237
+ // }
72238
+ // @ts-ignore
72239
+ return jsxRuntime.jsx("img", { ...props, src: icon, style: { width: width ? width : 24, height: height ? height : 'auto', ...props.style } });
72240
+ };
72241
+
72047
72242
  const DateHeader = React.memo(({ label }) => (jsxRuntime.jsx("div", { className: "d-flex justify-content-center", children: jsxRuntime.jsx("div", { style: {
72048
72243
  backgroundColor: "rgba(0,0,0,0.2)",
72049
72244
  padding: "2px 15px",
@@ -72503,399 +72698,205 @@ const ChatLog = (props) => {
72503
72698
  const extraCount = Math.max(0, dataParse.length - displayedItems.length);
72504
72699
  return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs("div", { children: [displayedItems.map((item, index) => (jsxRuntime.jsxs("strong", { children: [item.name, index < displayedItems.length - 1 && ", "] }, index))), dataParse.length > 3 && (jsxRuntime.jsxs("strong", { children: [jsxRuntime.jsx("span", { style: { fontWeight: "normal" }, children: " và " }), " ", extraCount, " ng\u01B0\u1EDDi kh\u00E1c"] })), " được ", chat?.createdBy?.id === dataProfile?.id ? (jsxRuntime.jsx("span", { children: "b\u1EA1n " })) : (jsxRuntime.jsx("strong", { style: { marginRight: "5px" }, children: chat?.createdByName })), "th\u00EAm v\u00E0o nh\u00F3m"] }) }));
72505
72700
  }, [dataProfile]);
72506
- // const renderChatImage = useCallback((chat: any) => {
72507
- // const files = chat.path
72508
- // if (!files || !Array.isArray(files) || files.length === 0) {
72509
- // return null
72510
- // }
72511
- // // Ảnh đơn lẻ
72512
- // if (files.length === 1) {
72513
- // const imagePath = files[0]?.path?.trim()
72514
- // if (!imagePath) { return null }
72515
- // return (
72516
- // <>
72517
- // <div className="image-container" style={{ maxWidth: "100%", position: "relative" }}>
72518
- // <img
72519
- // src={`${CDN_URL_VIEW}/${imagePath}`}
72520
- // alt={`Chat image ${chat.id + 1}`}
72521
- // data-file-index={chat.id}
72522
- // style={{
72523
- // maxWidth: "100%",
72524
- // maxHeight: 400,
72525
- // borderRadius: 8,
72526
- // cursor: "pointer"
72527
- // }}
72528
- // onClick={() => handlePreview(files[0])}
72529
- // />
72530
- // {/* HD Badge */}
72531
- // <div
72532
- // style={{
72533
- // position: "absolute",
72534
- // top: 6,
72535
- // left: 6,
72536
- // backgroundColor: "rgba(0, 0, 0, 0.6)",
72537
- // color: "white",
72538
- // padding: "2px 6px",
72539
- // borderRadius: 4,
72540
- // fontSize: "10px",
72541
- // fontWeight: "bold"
72542
- // }}
72543
- // >
72544
- // HD
72545
- // </div>
72546
- // </div>
72547
- // <div className="px-1 py-75">{moment(chat.time).format("HH:mm")}</div>
72548
- // </>
72549
- // )
72550
- // }
72551
- // // Nhiều ảnh - hiển thị dạng grid 2 cột, tối đa 6 ảnh
72552
- // const imagesToShow = files.slice(0, 6)
72553
- // const remainingCount = files.length - 6
72554
- // return (
72555
- // <>
72556
- // <div
72557
- // className="images-grid-container"
72558
- // style={{
72559
- // display: "flex",
72560
- // flexWrap: "wrap",
72561
- // maxWidth: "600px",
72562
- // gap: "4px"
72563
- // }}
72564
- // >
72565
- // {imagesToShow.map((file: any, index: number) => {
72566
- // const imagePath = file?.path?.trim()
72567
- // if (!imagePath) { return null }
72568
- // const imageUrl = `${CDN_URL_VIEW}/${imagePath}`
72569
- // const isLastImage = index === 5 && remainingCount > 0
72570
- // // ✅ THÊM: Kiểm tra ảnh cuối khi số lượng lẻ
72571
- // const isOddCount = imagesToShow.length % 2 !== 0
72572
- // const isLastItem = index === imagesToShow.length - 1
72573
- // const isFullWidth = isOddCount && isLastItem && !isLastImage
72574
- // return (
72575
- // <div
72576
- // key={`image-${chat.id}-${index}`}
72577
- // style={{
72578
- // width: isFullWidth ? "100%" : "calc(50% - 2px)",
72579
- // height: "140px",
72580
- // position: "relative",
72581
- // overflow: "hidden",
72582
- // borderRadius: 8,
72583
- // border: "1px solid #e0e0e0"
72584
- // }}
72585
- // >
72586
- // <img
72587
- // src={imageUrl}
72588
- // alt={`Chat image ${index + 1}`}
72589
- // style={{
72590
- // width: "100%",
72591
- // height: "100%",
72592
- // objectFit: "cover",
72593
- // borderRadius: 8,
72594
- // display: "block",
72595
- // cursor: "pointer"
72596
- // }}
72597
- // onClick={() => handlePreview(file)}
72598
- // />
72599
- // {/* HD Badge */}
72600
- // <div
72601
- // style={{
72602
- // position: "absolute",
72603
- // top: 6,
72604
- // left: 6,
72605
- // backgroundColor: "rgba(0, 0, 0, 0.6)",
72606
- // color: "white",
72607
- // padding: "2px 6px",
72608
- // borderRadius: 4,
72609
- // fontSize: "10px",
72610
- // fontWeight: "bold",
72611
- // zIndex: 1
72612
- // }}
72613
- // >
72614
- // HD
72615
- // </div>
72616
- // {/* Overlay cho ảnh cuối nếu có nhiều hơn 6 ảnh */}
72617
- // {isLastImage && (
72618
- // <div
72619
- // style={{
72620
- // position: "absolute",
72621
- // top: 0,
72622
- // left: 0,
72623
- // right: 0,
72624
- // bottom: 0,
72625
- // backgroundColor: "rgba(0, 0, 0, 0.6)",
72626
- // display: "flex",
72627
- // alignItems: "center",
72628
- // justifyContent: "center",
72629
- // color: "white",
72630
- // fontSize: "20px",
72631
- // fontWeight: "bold",
72632
- // borderRadius: 8,
72633
- // cursor: "pointer"
72634
- // }}
72635
- // onClick={() => handlePreview(file)}
72636
- // >
72637
- // +{remainingCount}
72638
- // </div>
72639
- // )}
72640
- // </div>
72641
- // )
72642
- // })}
72643
- // </div>
72644
- // <div className="px-1 py-75">{moment(chat.time).format("HH:mm")}</div>
72645
- // </>
72646
- // )
72647
- // }, [handlePreview])
72648
- // const renderChatFile = useCallback((chat: any) => {
72649
- // const files = chat?.path
72650
- // return (
72651
- // <>
72652
- // {files?.map((file: any, index: number) => {
72653
- // return (
72654
- // <div key={index}>
72655
- // <div className="d-flex p-50">
72656
- // <div className="me-1" onClick={() => handlePreview(file)}>
72657
- // {/*<IconFileType fileType={file?.type} fontSize={50} />*/}
72658
- // <IconFileTypeColor fileType={file?.type} width={35} />
72659
- // </div>
72660
- // <div>
72661
- // <p className="file-name-chat">{file.name}</p>
72662
- // <p>{formatBytes({ size: file.size })}</p>
72663
- // </div>
72664
- // </div>
72665
- // {index + 1 === files.length && (
72666
- // <div className="px-1 pb-75">
72667
- // {moment(chat.time).format("HH:mm")}
72668
- // </div>
72669
- // )}
72670
- // </div>
72671
- // )
72672
- // })}
72673
- // </>
72674
- // )
72675
- // }, [handlePreview])
72676
- // const renderTaskApplication = useCallback((chat: any) => {
72677
- // const safeParse = (str: any) => {
72678
- // if (!str) { return {} }
72679
- // try {
72680
- // return typeof str === 'string' ? JSON.parse(str) : str
72681
- // } catch (err) {
72682
- // //console.error('JSON parse error:', err)
72683
- // return {}
72684
- // }
72685
- // }
72686
- // // Helper function to strip HTML tags and get clean text
72687
- // const stripHtml = (html: string) => {
72688
- // if (!html) { return '' }
72689
- // const tmp = document.createElement('div')
72690
- // tmp.innerHTML = html
72691
- // return tmp.textContent || tmp.innerText || ''
72692
- // }
72693
- // const taskData = safeParse(chat.msg)
72694
- // const cleanDescription = taskData.description ? stripHtml(taskData.description) : ''
72695
- // return (
72696
- // <div
72697
- // style={{
72698
- // width: 320,
72699
- // backgroundColor: "#f8f9fa",
72700
- // borderRadius: 12,
72701
- // border: "1px solid #e3e8ef",
72702
- // padding: "12px",
72703
- // boxShadow: "0 2px 4px rgba(0,0,0,0.04)"
72704
- // }}
72705
- // >
72706
- // {/* Header với icon và tiêu đề */}
72707
- // <div className="d-flex align-items-start" style={{ marginBottom: 10 }}>
72708
- // <div style={{
72709
- // backgroundColor: "#e7f3ff",
72710
- // borderRadius: 8,
72711
- // padding: 6,
72712
- // display: "flex",
72713
- // alignItems: "center",
72714
- // justifyContent: "center",
72715
- // marginRight: 8,
72716
- // flexShrink: 0
72717
- // }}>
72718
- // <BecoxyWriting color="#006edc" fontSize={24} />
72719
- // </div>
72720
- // <div style={{ flex: 1, minWidth: 0 }}>
72721
- // <div style={{ fontSize: 10, color: "#8b92a7", marginBottom: 2, fontWeight: 500 }}>
72722
- // Công việc
72723
- // </div>
72724
- // <div style={{
72725
- // fontWeight: 600,
72726
- // fontSize: 14,
72727
- // color: "#283046",
72728
- // lineHeight: "1.4",
72729
- // wordBreak: "break-word"
72730
- // }}>
72731
- // {taskData.subject || 'Không có tiêu đề'}
72732
- // </div>
72733
- // </div>
72734
- // </div>
72735
- // {/* Nội dung */}
72736
- // {cleanDescription && (
72737
- // <div
72738
- // style={{
72739
- // marginBottom: 10,
72740
- // padding: "8px 10px",
72741
- // backgroundColor: "white",
72742
- // borderRadius: 8,
72743
- // fontSize: 12,
72744
- // color: "#5e5873",
72745
- // lineHeight: "1.5",
72746
- // border: "1px solid #eff1f5",
72747
- // wordBreak: "break-word",
72748
- // whiteSpace: "pre-wrap"
72749
- // }}
72750
- // dangerouslySetInnerHTML={{ __html: taskData.description }}
72751
- // />
72752
- // )}
72753
- // {/* Thông tin người tham gia */}
72754
- // <div style={{
72755
- // backgroundColor: "white",
72756
- // borderRadius: 8,
72757
- // padding: "8px 10px",
72758
- // marginBottom: 8,
72759
- // border: "1px solid #eff1f5"
72760
- // }}>
72761
- // {/* Người tạo phiếu */}
72762
- // {taskData.createdByName && (
72763
- // <div style={{ marginBottom: taskData.hostPerson?.length > 0 || taskData.thePerformer?.length > 0 ? 8 : 0 }}>
72764
- // <div style={{ fontSize: 10, color: "#8b92a7", marginBottom: 4, fontWeight: 500 }}>
72765
- // Người tạo phiếu
72766
- // </div>
72767
- // <div className="d-flex align-items-center">
72768
- // <AvatarDefault
72769
- // imgWidth={20}
72770
- // imgHeight={20}
72771
- // color="light-primary"
72772
- // className="me-50"
72773
- // img={taskData?.createdByImg}
72774
- // />
72775
- // <span style={{ fontSize: 12, color: "#283046", fontWeight: 500 }}>
72776
- // {taskData.createdByName}
72777
- // </span>
72778
- // </div>
72779
- // </div>
72780
- // )}
72781
- // {/* Người chủ trì */}
72782
- // {taskData.hostPerson && taskData.hostPerson.length > 0 && (
72783
- // <div style={{ marginBottom: taskData.thePerformer?.length > 0 ? 8 : 0 }}>
72784
- // <div style={{ fontSize: 10, color: "#8b92a7", marginBottom: 4, fontWeight: 500 }}>
72785
- // Người chủ trì
72786
- // </div>
72787
- // <div className="d-flex align-items-center flex-wrap" style={{ gap: 4 }}>
72788
- // {taskData.hostPerson.slice(0, 2).map((person: any, index: number) => (
72789
- // <div key={index} className="d-flex align-items-center" style={{
72790
- // backgroundColor: "#f8f9fa",
72791
- // borderRadius: 6,
72792
- // padding: "3px 6px",
72793
- // marginRight: 4
72794
- // }}>
72795
- // <AvatarDefault
72796
- // imgWidth={18}
72797
- // imgHeight={18}
72798
- // color="light-info"
72799
- // className="me-50"
72800
- // img={person.img}
72801
- // />
72802
- // <span style={{ fontSize: 11, color: "#5e5873", fontWeight: 500 }}>
72803
- // {person.name || person.fullName || 'N/A'}
72804
- // </span>
72805
- // </div>
72806
- // ))}
72807
- // {taskData.hostPerson.length > 2 && (
72808
- // <span style={{
72809
- // fontSize: 11,
72810
- // color: "#8b92a7",
72811
- // backgroundColor: "#f8f9fa",
72812
- // padding: "3px 8px",
72813
- // borderRadius: 6,
72814
- // fontWeight: 500
72815
- // }}>
72816
- // +{taskData.hostPerson.length - 2}
72817
- // </span>
72818
- // )}
72819
- // </div>
72820
- // </div>
72821
- // )}
72822
- // {/* Người thực hiện */}
72823
- // {taskData.thePerformer && taskData.thePerformer.length > 0 && (
72824
- // <div>
72825
- // <div style={{ fontSize: 10, color: "#8b92a7", marginBottom: 4, fontWeight: 500 }}>
72826
- // Người thực hiện
72827
- // </div>
72828
- // <div className="d-flex align-items-center flex-wrap" style={{ gap: 4 }}>
72829
- // {taskData.thePerformer.slice(0, 2).map((performer: any, index: number) => (
72830
- // <div key={index} className="d-flex align-items-center" style={{
72831
- // backgroundColor: "#f8f9fa",
72832
- // borderRadius: 6,
72833
- // padding: "3px 6px",
72834
- // marginRight: 4
72835
- // }}>
72836
- // <AvatarDefault
72837
- // imgWidth={18}
72838
- // imgHeight={18}
72839
- // color="light-secondary"
72840
- // className="me-50"
72841
- // img={performer.img}
72842
- // />
72843
- // <span style={{ fontSize: 11, color: "#5e5873", fontWeight: 500 }}>
72844
- // {performer.name || performer.fullName || 'N/A'}
72845
- // </span>
72846
- // </div>
72847
- // ))}
72848
- // {taskData.thePerformer.length > 2 && (
72849
- // <span style={{
72850
- // fontSize: 11,
72851
- // color: "#8b92a7",
72852
- // backgroundColor: "#f8f9fa",
72853
- // padding: "3px 8px",
72854
- // borderRadius: 6,
72855
- // fontWeight: 500
72856
- // }}>
72857
- // +{taskData.thePerformer.length - 2}
72858
- // </span>
72859
- // )}
72860
- // </div>
72861
- // </div>
72862
- // )}
72863
- // </div>
72864
- // {/* Hạn hoàn thành */}
72865
- // {taskData.dueDate && (
72866
- // <div style={{
72867
- // display: "flex",
72868
- // alignItems: "center",
72869
- // justifyContent: "space-between",
72870
- // backgroundColor: "#fff5f5",
72871
- // padding: "6px 10px",
72872
- // borderRadius: 8,
72873
- // marginBottom: 8,
72874
- // border: "1px solid #ffe5e5"
72875
- // }}>
72876
- // <div style={{ display: "flex", alignItems: "center" }}>
72877
- // <Clock fontSize={14} style={{ color: "#ea5455", marginRight: 6 }} />
72878
- // <span style={{ fontSize: 10, color: "#8b92a7", fontWeight: 500 }}>
72879
- // Hạn hoàn thành
72880
- // </span>
72881
- // </div>
72882
- // <span style={{ fontSize: 12, color: "#ea5455", fontWeight: 600 }}>
72883
- // {moment(taskData.dueDate).format('DD/MM/YYYY HH:mm')}
72884
- // </span>
72885
- // </div>
72886
- // )}
72887
- // {/* Footer time */}
72888
- // <div style={{
72889
- // fontSize: 11,
72890
- // color: "#adb5bd",
72891
- // textAlign: "right",
72892
- // fontWeight: 500
72893
- // }}>
72894
- // {moment(chat.time).format("HH:mm")}
72895
- // </div>
72896
- // </div>
72897
- // )
72898
- // }, [])
72701
+ React.useCallback((chat) => {
72702
+ const files = chat.path;
72703
+ if (!files || !Array.isArray(files) || files.length === 0) {
72704
+ return null;
72705
+ }
72706
+ // Ảnh đơn lẻ
72707
+ if (files.length === 1) {
72708
+ const imagePath = files[0]?.path?.trim();
72709
+ if (!imagePath) {
72710
+ return null;
72711
+ }
72712
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "image-container", style: { maxWidth: "100%", position: "relative" }, children: [jsxRuntime.jsx("img", { src: `${CDN_URL_VIEW}/${imagePath}`, alt: `Chat image ${chat.id + 1}`, "data-file-index": chat.id, style: {
72713
+ maxWidth: "100%",
72714
+ maxHeight: 400,
72715
+ borderRadius: 8,
72716
+ cursor: "pointer"
72717
+ }, onClick: () => handlePreview(files[0]) }), jsxRuntime.jsx("div", { style: {
72718
+ position: "absolute",
72719
+ top: 6,
72720
+ left: 6,
72721
+ backgroundColor: "rgba(0, 0, 0, 0.6)",
72722
+ color: "white",
72723
+ padding: "2px 6px",
72724
+ borderRadius: 4,
72725
+ fontSize: "10px",
72726
+ fontWeight: "bold"
72727
+ }, children: "HD" })] }), jsxRuntime.jsx("div", { className: "px-1 py-75", children: moment(chat.time).format("HH:mm") })] }));
72728
+ }
72729
+ // Nhiều ảnh - hiển thị dạng grid 2 cột, tối đa 6 ảnh
72730
+ const imagesToShow = files.slice(0, 6);
72731
+ const remainingCount = files.length - 6;
72732
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: "images-grid-container", style: {
72733
+ display: "flex",
72734
+ flexWrap: "wrap",
72735
+ maxWidth: "600px",
72736
+ gap: "4px"
72737
+ }, children: imagesToShow.map((file, index) => {
72738
+ const imagePath = file?.path?.trim();
72739
+ if (!imagePath) {
72740
+ return null;
72741
+ }
72742
+ const imageUrl = `${CDN_URL_VIEW}/${imagePath}`;
72743
+ const isLastImage = index === 5 && remainingCount > 0;
72744
+ // ✅ THÊM: Kiểm tra ảnh cuối khi số lượng lẻ
72745
+ const isOddCount = imagesToShow.length % 2 !== 0;
72746
+ const isLastItem = index === imagesToShow.length - 1;
72747
+ const isFullWidth = isOddCount && isLastItem && !isLastImage;
72748
+ return (jsxRuntime.jsxs("div", { style: {
72749
+ width: isFullWidth ? "100%" : "calc(50% - 2px)",
72750
+ height: "140px",
72751
+ position: "relative",
72752
+ overflow: "hidden",
72753
+ borderRadius: 8,
72754
+ border: "1px solid #e0e0e0"
72755
+ }, children: [jsxRuntime.jsx("img", { src: imageUrl, alt: `Chat image ${index + 1}`, style: {
72756
+ width: "100%",
72757
+ height: "100%",
72758
+ objectFit: "cover",
72759
+ borderRadius: 8,
72760
+ display: "block",
72761
+ cursor: "pointer"
72762
+ }, onClick: () => handlePreview(file) }), jsxRuntime.jsx("div", { style: {
72763
+ position: "absolute",
72764
+ top: 6,
72765
+ left: 6,
72766
+ backgroundColor: "rgba(0, 0, 0, 0.6)",
72767
+ color: "white",
72768
+ padding: "2px 6px",
72769
+ borderRadius: 4,
72770
+ fontSize: "10px",
72771
+ fontWeight: "bold",
72772
+ zIndex: 1
72773
+ }, children: "HD" }), isLastImage && (jsxRuntime.jsxs("div", { style: {
72774
+ position: "absolute",
72775
+ top: 0,
72776
+ left: 0,
72777
+ right: 0,
72778
+ bottom: 0,
72779
+ backgroundColor: "rgba(0, 0, 0, 0.6)",
72780
+ display: "flex",
72781
+ alignItems: "center",
72782
+ justifyContent: "center",
72783
+ color: "white",
72784
+ fontSize: "20px",
72785
+ fontWeight: "bold",
72786
+ borderRadius: 8,
72787
+ cursor: "pointer"
72788
+ }, onClick: () => handlePreview(file), children: ["+", remainingCount] }))] }, `image-${chat.id}-${index}`));
72789
+ }) }), jsxRuntime.jsx("div", { className: "px-1 py-75", children: moment(chat.time).format("HH:mm") })] }));
72790
+ }, [handlePreview]);
72791
+ React.useCallback((chat) => {
72792
+ const files = chat?.path;
72793
+ return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: files?.map((file, index) => {
72794
+ return (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { className: "d-flex p-50", children: [jsxRuntime.jsx("div", { className: "me-1", onClick: () => handlePreview(file), children: jsxRuntime.jsx(IconFileTypeColor, { fileType: file?.type, width: 35 }) }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("p", { className: "file-name-chat", children: file.name }), jsxRuntime.jsx("p", { children: formatBytes({ size: file.size }) })] })] }), index + 1 === files.length && (jsxRuntime.jsx("div", { className: "px-1 pb-75", children: moment(chat.time).format("HH:mm") }))] }, index));
72795
+ }) }));
72796
+ }, [handlePreview]);
72797
+ React.useCallback((chat) => {
72798
+ const safeParse = (str) => {
72799
+ if (!str) {
72800
+ return {};
72801
+ }
72802
+ try {
72803
+ return typeof str === 'string' ? JSON.parse(str) : str;
72804
+ }
72805
+ catch (err) {
72806
+ //console.error('JSON parse error:', err)
72807
+ return {};
72808
+ }
72809
+ };
72810
+ // Helper function to strip HTML tags and get clean text
72811
+ const stripHtml = (html) => {
72812
+ if (!html) {
72813
+ return '';
72814
+ }
72815
+ const tmp = document.createElement('div');
72816
+ tmp.innerHTML = html;
72817
+ return tmp.textContent || tmp.innerText || '';
72818
+ };
72819
+ const taskData = safeParse(chat.msg);
72820
+ const cleanDescription = taskData.description ? stripHtml(taskData.description) : '';
72821
+ return (jsxRuntime.jsxs("div", { style: {
72822
+ width: 320,
72823
+ backgroundColor: "#f8f9fa",
72824
+ borderRadius: 12,
72825
+ border: "1px solid #e3e8ef",
72826
+ padding: "12px",
72827
+ boxShadow: "0 2px 4px rgba(0,0,0,0.04)"
72828
+ }, children: [jsxRuntime.jsxs("div", { className: "d-flex align-items-start", style: { marginBottom: 10 }, children: [jsxRuntime.jsx("div", { style: {
72829
+ backgroundColor: "#e7f3ff",
72830
+ borderRadius: 8,
72831
+ padding: 6,
72832
+ display: "flex",
72833
+ alignItems: "center",
72834
+ justifyContent: "center",
72835
+ marginRight: 8,
72836
+ flexShrink: 0
72837
+ }, children: jsxRuntime.jsx(SvgBecoxyWriting, { color: "#006edc", fontSize: 24 }) }), jsxRuntime.jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [jsxRuntime.jsx("div", { style: { fontSize: 10, color: "#8b92a7", marginBottom: 2, fontWeight: 500 }, children: "C\u00F4ng vi\u1EC7c" }), jsxRuntime.jsx("div", { style: {
72838
+ fontWeight: 600,
72839
+ fontSize: 14,
72840
+ color: "#283046",
72841
+ lineHeight: "1.4",
72842
+ wordBreak: "break-word"
72843
+ }, children: taskData.subject || 'Không có tiêu đề' })] })] }), cleanDescription && (jsxRuntime.jsx("div", { style: {
72844
+ marginBottom: 10,
72845
+ padding: "8px 10px",
72846
+ backgroundColor: "white",
72847
+ borderRadius: 8,
72848
+ fontSize: 12,
72849
+ color: "#5e5873",
72850
+ lineHeight: "1.5",
72851
+ border: "1px solid #eff1f5",
72852
+ wordBreak: "break-word",
72853
+ whiteSpace: "pre-wrap"
72854
+ }, dangerouslySetInnerHTML: { __html: taskData.description } })), jsxRuntime.jsxs("div", { style: {
72855
+ backgroundColor: "white",
72856
+ borderRadius: 8,
72857
+ padding: "8px 10px",
72858
+ marginBottom: 8,
72859
+ border: "1px solid #eff1f5"
72860
+ }, children: [taskData.createdByName && (jsxRuntime.jsxs("div", { style: { marginBottom: taskData.hostPerson?.length > 0 || taskData.thePerformer?.length > 0 ? 8 : 0 }, children: [jsxRuntime.jsx("div", { style: { fontSize: 10, color: "#8b92a7", marginBottom: 4, fontWeight: 500 }, children: "Ng\u01B0\u1EDDi t\u1EA1o phi\u1EBFu" }), jsxRuntime.jsxs("div", { className: "d-flex align-items-center", children: [jsxRuntime.jsx(AvatarDefault, { imgWidth: 20, imgHeight: 20, color: "light-primary", className: "me-50", img: taskData?.createdByImg }), jsxRuntime.jsx("span", { style: { fontSize: 12, color: "#283046", fontWeight: 500 }, children: taskData.createdByName })] })] })), taskData.hostPerson && taskData.hostPerson.length > 0 && (jsxRuntime.jsxs("div", { style: { marginBottom: taskData.thePerformer?.length > 0 ? 8 : 0 }, children: [jsxRuntime.jsx("div", { style: { fontSize: 10, color: "#8b92a7", marginBottom: 4, fontWeight: 500 }, children: "Ng\u01B0\u1EDDi ch\u1EE7 tr\u00EC" }), jsxRuntime.jsxs("div", { className: "d-flex align-items-center flex-wrap", style: { gap: 4 }, children: [taskData.hostPerson.slice(0, 2).map((person, index) => (jsxRuntime.jsxs("div", { className: "d-flex align-items-center", style: {
72861
+ backgroundColor: "#f8f9fa",
72862
+ borderRadius: 6,
72863
+ padding: "3px 6px",
72864
+ marginRight: 4
72865
+ }, children: [jsxRuntime.jsx(AvatarDefault, { imgWidth: 18, imgHeight: 18, color: "light-info", className: "me-50", img: person.img }), jsxRuntime.jsx("span", { style: { fontSize: 11, color: "#5e5873", fontWeight: 500 }, children: person.name || person.fullName || 'N/A' })] }, index))), taskData.hostPerson.length > 2 && (jsxRuntime.jsxs("span", { style: {
72866
+ fontSize: 11,
72867
+ color: "#8b92a7",
72868
+ backgroundColor: "#f8f9fa",
72869
+ padding: "3px 8px",
72870
+ borderRadius: 6,
72871
+ fontWeight: 500
72872
+ }, children: ["+", taskData.hostPerson.length - 2] }))] })] })), taskData.thePerformer && taskData.thePerformer.length > 0 && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("div", { style: { fontSize: 10, color: "#8b92a7", marginBottom: 4, fontWeight: 500 }, children: "Ng\u01B0\u1EDDi th\u1EF1c hi\u1EC7n" }), jsxRuntime.jsxs("div", { className: "d-flex align-items-center flex-wrap", style: { gap: 4 }, children: [taskData.thePerformer.slice(0, 2).map((performer, index) => (jsxRuntime.jsxs("div", { className: "d-flex align-items-center", style: {
72873
+ backgroundColor: "#f8f9fa",
72874
+ borderRadius: 6,
72875
+ padding: "3px 6px",
72876
+ marginRight: 4
72877
+ }, children: [jsxRuntime.jsx(AvatarDefault, { imgWidth: 18, imgHeight: 18, color: "light-secondary", className: "me-50", img: performer.img }), jsxRuntime.jsx("span", { style: { fontSize: 11, color: "#5e5873", fontWeight: 500 }, children: performer.name || performer.fullName || 'N/A' })] }, index))), taskData.thePerformer.length > 2 && (jsxRuntime.jsxs("span", { style: {
72878
+ fontSize: 11,
72879
+ color: "#8b92a7",
72880
+ backgroundColor: "#f8f9fa",
72881
+ padding: "3px 8px",
72882
+ borderRadius: 6,
72883
+ fontWeight: 500
72884
+ }, children: ["+", taskData.thePerformer.length - 2] }))] })] }))] }), taskData.dueDate && (jsxRuntime.jsxs("div", { style: {
72885
+ display: "flex",
72886
+ alignItems: "center",
72887
+ justifyContent: "space-between",
72888
+ backgroundColor: "#fff5f5",
72889
+ padding: "6px 10px",
72890
+ borderRadius: 8,
72891
+ marginBottom: 8,
72892
+ border: "1px solid #ffe5e5"
72893
+ }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center" }, children: [jsxRuntime.jsx(SvgClock, { fontSize: 14, style: { color: "#ea5455", marginRight: 6 } }), jsxRuntime.jsx("span", { style: { fontSize: 10, color: "#8b92a7", fontWeight: 500 }, children: "H\u1EA1n ho\u00E0n th\u00E0nh" })] }), jsxRuntime.jsx("span", { style: { fontSize: 12, color: "#ea5455", fontWeight: 600 }, children: moment(taskData.dueDate).format('DD/MM/YYYY HH:mm') })] })), jsxRuntime.jsx("div", { style: {
72894
+ fontSize: 11,
72895
+ color: "#adb5bd",
72896
+ textAlign: "right",
72897
+ fontWeight: 500
72898
+ }, children: moment(chat.time).format("HH:mm") })] }));
72899
+ }, []);
72899
72900
  // const renderChatReminder = useCallback((chat: any) => {
72900
72901
  // let msgContent = chat.msg
72901
72902
  // let timeDisplay = chat.time