@esic-lab/data-core-ui 0.0.45 → 0.0.47

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
@@ -3681,7 +3681,13 @@ function AntDModal({ children, isOpen, width, onCancel }) {
3681
3681
  }
3682
3682
 
3683
3683
  // src/Indicator/Indicator/Indicator.tsx
3684
- import { IconCheck as IconCheck3, IconCirclePlus as IconCirclePlus2, IconPencil as IconPencil2, IconTrash as IconTrash4, IconX as IconX3 } from "@tabler/icons-react";
3684
+ import {
3685
+ IconCheck as IconCheck3,
3686
+ IconCirclePlus as IconCirclePlus2,
3687
+ IconPencil as IconPencil2,
3688
+ IconTrash as IconTrash4,
3689
+ IconX as IconX3
3690
+ } from "@tabler/icons-react";
3685
3691
  import { useState as useState15 } from "react";
3686
3692
  import { Input as Input4 } from "antd";
3687
3693
  import { Fragment as Fragment7, jsx as jsx40, jsxs as jsxs34 } from "react/jsx-runtime";
@@ -3692,41 +3698,66 @@ function Indicator({
3692
3698
  ],
3693
3699
  type,
3694
3700
  arrayData,
3695
- setArrayData
3701
+ setArrayData,
3702
+ canEdit,
3703
+ onDeleteClick
3696
3704
  }) {
3697
3705
  const [valueSwitch, setValueSwitch] = useState15("TEXT");
3698
3706
  const [cacheData, setCacheData] = useState15({
3699
3707
  indicatorType: type,
3700
3708
  inputType: valueSwitch,
3701
3709
  textValue: "",
3702
- numberValue: "",
3710
+ numberValue: 0,
3703
3711
  unit: ""
3704
3712
  });
3705
3713
  const [cacheEditData, setCacheEditData] = useState15({
3706
3714
  indicatorType: type,
3707
3715
  inputType: valueSwitch,
3708
3716
  textValue: "",
3709
- numberValue: "",
3717
+ numberValue: 0,
3710
3718
  unit: ""
3711
3719
  });
3712
3720
  const [editIndex, setEditIndex] = useState15(null);
3721
+ const [addError, setAddError] = useState15({});
3722
+ const [editError, setEditError] = useState15({});
3713
3723
  const handleAddIndicator = () => {
3714
- if (cacheData.textValue.trim() === "") return;
3715
- setArrayData([
3716
- ...arrayData,
3717
- valueSwitch === "TEXT" ? {
3718
- indicatorType: type,
3719
- inputType: "TEXT",
3720
- textValue: cacheData.textValue
3721
- } : cacheData
3722
- ]);
3724
+ const nextErr = {};
3725
+ const textValue = (cacheData.textValue ?? "").trim();
3726
+ const unit = (cacheData.unit ?? "").trim();
3727
+ if (textValue === "") {
3728
+ nextErr.textValue = "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E23\u0E30\u0E1A\u0E38\u0E0A\u0E37\u0E48\u0E2D\u0E15\u0E31\u0E27\u0E0A\u0E35\u0E49\u0E27\u0E31\u0E14";
3729
+ }
3730
+ if (valueSwitch === "NUMBER") {
3731
+ const num = cacheData.numberValue;
3732
+ if (num === void 0 || num === null || Number(num) <= 0) {
3733
+ nextErr.numberValue = "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E23\u0E30\u0E1A\u0E38\u0E04\u0E48\u0E32\u0E15\u0E31\u0E27\u0E40\u0E25\u0E02";
3734
+ }
3735
+ if (unit === "") {
3736
+ nextErr.unit = "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E23\u0E30\u0E1A\u0E38\u0E2B\u0E19\u0E48\u0E27\u0E22";
3737
+ }
3738
+ }
3739
+ setAddError(nextErr);
3740
+ if (Object.keys(nextErr).length > 0) return;
3741
+ const newItem = valueSwitch === "TEXT" ? {
3742
+ indicatorType: type,
3743
+ inputType: "TEXT",
3744
+ textValue
3745
+ } : {
3746
+ indicatorType: type,
3747
+ inputType: "NUMBER",
3748
+ textValue,
3749
+ numberValue: Number(cacheData.numberValue),
3750
+ unit
3751
+ };
3752
+ setArrayData([...arrayData, newItem]);
3723
3753
  setCacheData({
3724
3754
  indicatorType: type,
3725
3755
  inputType: valueSwitch,
3726
3756
  textValue: "",
3727
- numberValue: "",
3757
+ numberValue: 0,
3728
3758
  unit: ""
3729
3759
  });
3760
+ setAddError({});
3730
3761
  };
3731
3762
  const handleChangeCashData = (key, value) => {
3732
3763
  setCacheData((prev) => ({
@@ -3752,11 +3783,32 @@ function Indicator({
3752
3783
  setEditIndex(null);
3753
3784
  };
3754
3785
  const handleConfirmEditIndicator = (index) => {
3755
- if (cacheEditData.textValue.trim() === "") return;
3786
+ const nextErr = {};
3787
+ const textValue = (cacheEditData.textValue ?? "").trim();
3788
+ const unit = (cacheEditData.unit ?? "").trim();
3789
+ const num = cacheEditData.numberValue;
3790
+ if (textValue === "") {
3791
+ nextErr.textValue = "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E23\u0E30\u0E1A\u0E38\u0E0A\u0E37\u0E48\u0E2D\u0E15\u0E31\u0E27\u0E0A\u0E35\u0E49\u0E27\u0E31\u0E14";
3792
+ }
3793
+ if (cacheEditData.inputType === "NUMBER") {
3794
+ if (num === void 0 || num === null || Number(num) <= 0) {
3795
+ nextErr.numberValue = "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E23\u0E30\u0E1A\u0E38\u0E04\u0E48\u0E32\u0E15\u0E31\u0E27\u0E40\u0E25\u0E02";
3796
+ }
3797
+ if (unit === "") {
3798
+ nextErr.unit = "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E23\u0E30\u0E1A\u0E38\u0E2B\u0E19\u0E48\u0E27\u0E22";
3799
+ }
3800
+ }
3801
+ setEditError(nextErr);
3802
+ if (Object.keys(nextErr).length > 0) return;
3756
3803
  const newData = [...arrayData];
3757
- newData[index] = cacheEditData;
3804
+ newData[index] = {
3805
+ ...cacheEditData,
3806
+ textValue,
3807
+ ...cacheEditData.inputType === "NUMBER" ? { numberValue: Number(num), unit } : { numberValue: void 0, unit: void 0 }
3808
+ };
3758
3809
  setArrayData(newData);
3759
3810
  setEditIndex(null);
3811
+ setEditError({});
3760
3812
  };
3761
3813
  const handleChangeEditCashData = (e) => {
3762
3814
  const { name, value } = e.target;
@@ -3772,16 +3824,29 @@ function Indicator({
3772
3824
  {
3773
3825
  className: `space-x-2 grid ${valueSwitch === "TEXT" ? `grid-cols-[140px_1fr_50px]` : `grid-cols-[140px_1fr_200px_200px_50px]`} items-start`,
3774
3826
  children: [
3775
- /* @__PURE__ */ jsx40(SwitchSelect, { option, onClick: handleClick, value: valueSwitch, label: "\u0E1B\u0E23\u0E30\u0E40\u0E20\u0E17", required: true }),
3827
+ /* @__PURE__ */ jsx40(
3828
+ SwitchSelect,
3829
+ {
3830
+ option,
3831
+ onClick: handleClick,
3832
+ value: valueSwitch,
3833
+ label: "\u0E1B\u0E23\u0E30\u0E40\u0E20\u0E17",
3834
+ required: true
3835
+ }
3836
+ ),
3776
3837
  /* @__PURE__ */ jsx40(
3777
3838
  InputField,
3778
3839
  {
3779
3840
  label: `\u0E0A\u0E37\u0E48\u0E2D\u0E15\u0E31\u0E27\u0E0A\u0E35\u0E49\u0E27\u0E31\u0E14${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
3780
3841
  value: cacheData.textValue,
3781
3842
  className: "h-[32px]",
3782
- onChange: (e) => handleChangeCashData("textValue", String(e)),
3843
+ onChange: (val) => {
3844
+ handleChangeCashData("textValue", val ?? "");
3845
+ setAddError((p) => ({ ...p, textValue: void 0 }));
3846
+ },
3783
3847
  placeholder: `\u0E23\u0E30\u0E1A\u0E38\u0E0A\u0E37\u0E48\u0E2D\u0E15\u0E31\u0E27\u0E0A\u0E35\u0E49\u0E27\u0E31\u0E14${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
3784
- required: true
3848
+ required: true,
3849
+ error: addError.textValue
3785
3850
  }
3786
3851
  ),
3787
3852
  valueSwitch === "NUMBER" && /* @__PURE__ */ jsxs34(Fragment7, { children: [
@@ -3789,11 +3854,16 @@ function Indicator({
3789
3854
  InputFieldNumber,
3790
3855
  {
3791
3856
  label: `\u0E04\u0E48\u0E32\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
3792
- value: cacheData.numberValue ?? "",
3857
+ value: cacheData.numberValue ?? 0,
3793
3858
  className: "h-[32px]",
3794
- onChange: (e) => handleChangeCashData("numberValue", String(e)),
3859
+ onChange: (val) => {
3860
+ handleChangeCashData("numberValue", val ?? 0);
3861
+ setAddError((p) => ({ ...p, numberValue: void 0 }));
3862
+ },
3863
+ min: 0,
3795
3864
  placeholder: `\u0E23\u0E30\u0E1A\u0E38\u0E04\u0E48\u0E32\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
3796
- required: true
3865
+ required: true,
3866
+ error: addError.numberValue
3797
3867
  }
3798
3868
  ),
3799
3869
  /* @__PURE__ */ jsx40(
@@ -3802,53 +3872,83 @@ function Indicator({
3802
3872
  label: `\u0E2B\u0E19\u0E48\u0E27\u0E22`,
3803
3873
  value: cacheData.unit ?? "",
3804
3874
  className: "h-[32px]",
3805
- onChange: (e) => handleChangeCashData("unit", String(e)),
3875
+ onChange: (val) => {
3876
+ handleChangeCashData("unit", val ?? "");
3877
+ setAddError((p) => ({ ...p, unit: void 0 }));
3878
+ },
3806
3879
  placeholder: "\u0E23\u0E30\u0E1A\u0E38\u0E2B\u0E19\u0E48\u0E27\u0E22",
3807
- required: true
3880
+ required: true,
3881
+ error: addError.unit
3808
3882
  }
3809
3883
  )
3810
3884
  ] }),
3811
- /* @__PURE__ */ jsx40(IconCirclePlus2, { onClick: handleAddIndicator, className: "mt-7 cursor-pointer", size: 32 })
3885
+ /* @__PURE__ */ jsx40(
3886
+ IconCirclePlus2,
3887
+ {
3888
+ onClick: handleAddIndicator,
3889
+ className: "mt-8 cursor-pointer",
3890
+ size: 32
3891
+ }
3892
+ )
3812
3893
  ]
3813
3894
  }
3814
3895
  ),
3815
3896
  /* @__PURE__ */ jsx40(Fragment7, { children: arrayData.map((item, index) => /* @__PURE__ */ jsxs34(
3816
3897
  "div",
3817
3898
  {
3818
- className: `space-y-4 grid ${item.inputType === "TEXT" ? `grid-cols-[140px_1fr_50px_50px]` : `grid-cols-[140px_1fr_200px_150px_50px_50px]`} items-start`,
3899
+ className: `space-y-2 grid ${item.inputType === "TEXT" ? `grid-cols-[140px_1fr_50px_50px]` : `grid-cols-[140px_1fr_200px_150px_50px_50px]`} items-start`,
3819
3900
  children: [
3820
3901
  /* @__PURE__ */ jsx40("div", { className: "body-1 mt-2", children: item.inputType === "TEXT" ? "\u0E02\u0E49\u0E2D\u0E04\u0E27\u0E32\u0E21" : "\u0E15\u0E31\u0E27\u0E40\u0E25\u0E02" }),
3821
- index === editIndex ? /* @__PURE__ */ jsx40(
3822
- Input4,
3823
- {
3824
- className: "body-1 mt-2",
3825
- variant: "underlined",
3826
- value: cacheEditData.textValue,
3827
- name: "textValue",
3828
- onChange: (e) => handleChangeEditCashData(e)
3829
- }
3830
- ) : /* @__PURE__ */ jsx40("div", { className: "body-1 mt-2", children: item.textValue }),
3831
- item.inputType === "NUMBER" && /* @__PURE__ */ jsxs34(Fragment7, { children: [
3832
- index === editIndex ? /* @__PURE__ */ jsx40(
3833
- Input4,
3834
- {
3835
- className: "body-1 mt-2",
3836
- variant: "underlined",
3837
- value: cacheEditData.numberValue,
3838
- name: "numberValue",
3839
- onChange: (e) => handleChangeEditCashData(e)
3840
- }
3841
- ) : /* @__PURE__ */ jsx40("div", { className: "body-1 mt-2", children: item.numberValue }),
3842
- index === editIndex ? /* @__PURE__ */ jsx40(
3902
+ index === editIndex ? /* @__PURE__ */ jsxs34("div", { className: "flex flex-col gap-[8px]", children: [
3903
+ /* @__PURE__ */ jsx40(
3843
3904
  Input4,
3844
3905
  {
3845
3906
  className: "body-1 mt-2",
3846
3907
  variant: "underlined",
3847
- value: cacheEditData.unit,
3848
- name: "unit",
3849
- onChange: (e) => handleChangeEditCashData(e)
3908
+ value: cacheEditData.textValue,
3909
+ name: "textValue",
3910
+ onChange: (e) => {
3911
+ handleChangeEditCashData(e);
3912
+ setEditError((p) => ({ ...p, textValue: void 0 }));
3913
+ }
3850
3914
  }
3851
- ) : /* @__PURE__ */ jsx40("div", { className: "body-1 mt-2", children: item.unit })
3915
+ ),
3916
+ editError.textValue && /* @__PURE__ */ jsx40("p", { className: "text-red-500 caption-1", children: editError.textValue })
3917
+ ] }) : /* @__PURE__ */ jsx40("div", { className: "body-1 mt-2", children: item.textValue }),
3918
+ item.inputType === "NUMBER" && /* @__PURE__ */ jsxs34(Fragment7, { children: [
3919
+ index === editIndex ? /* @__PURE__ */ jsxs34("div", { className: "flex flex-col gap-[8px]", children: [
3920
+ /* @__PURE__ */ jsx40(
3921
+ Input4,
3922
+ {
3923
+ type: "number",
3924
+ className: "body-1 mt-2",
3925
+ variant: "underlined",
3926
+ value: cacheEditData.numberValue,
3927
+ name: "numberValue",
3928
+ onChange: (e) => {
3929
+ handleChangeEditCashData(e);
3930
+ setEditError((p) => ({ ...p, numberValue: void 0 }));
3931
+ }
3932
+ }
3933
+ ),
3934
+ editError.numberValue && /* @__PURE__ */ jsx40("p", { className: "text-red-500 caption-1", children: editError.numberValue })
3935
+ ] }) : /* @__PURE__ */ jsx40("div", { className: "body-1 mt-2", children: item.numberValue }),
3936
+ index === editIndex ? /* @__PURE__ */ jsxs34("div", { className: "flex flex-col gap-[8px]", children: [
3937
+ /* @__PURE__ */ jsx40(
3938
+ Input4,
3939
+ {
3940
+ className: "body-1 mt-2",
3941
+ variant: "underlined",
3942
+ value: cacheEditData.unit,
3943
+ name: "unit",
3944
+ onChange: (e) => {
3945
+ handleChangeEditCashData(e);
3946
+ setEditError((p) => ({ ...p, unit: void 0 }));
3947
+ }
3948
+ }
3949
+ ),
3950
+ editError.unit && /* @__PURE__ */ jsx40("p", { className: "text-red-500 caption-1", children: editError.unit })
3951
+ ] }) : /* @__PURE__ */ jsx40("div", { className: "body-1 mt-2", children: item.unit })
3852
3952
  ] }),
3853
3953
  /* @__PURE__ */ jsx40("div", { className: "body-1 mt-2 flex", children: editIndex !== null ? editIndex === index ? /* @__PURE__ */ jsxs34("div", { className: "flex", children: [
3854
3954
  /* @__PURE__ */ jsx40(
@@ -3858,11 +3958,36 @@ function Indicator({
3858
3958
  onClick: () => handleConfirmEditIndicator(index)
3859
3959
  }
3860
3960
  ),
3861
- /* @__PURE__ */ jsx40(IconX3, { className: "cursor-pointer text-red-600", onClick: handleCancelEditIndicator })
3862
- ] }) : void 0 : /* @__PURE__ */ jsx40(IconPencil2, { className: "cursor-pointer", onClick: () => handleEditIndicator(index) }) }),
3863
- /* @__PURE__ */ jsx40("div", { className: "body-1 mt-2 cursor-pointer", children: /* @__PURE__ */ jsx40(IconTrash4, { onClick: () => handleDeleteIndicator(index) }) })
3961
+ /* @__PURE__ */ jsx40(
3962
+ IconX3,
3963
+ {
3964
+ className: "cursor-pointer text-red-600",
3965
+ onClick: handleCancelEditIndicator
3966
+ }
3967
+ )
3968
+ ] }) : void 0 : canEdit && /* @__PURE__ */ jsx40(
3969
+ IconPencil2,
3970
+ {
3971
+ className: "cursor-pointer",
3972
+ onClick: () => handleEditIndicator(index)
3973
+ }
3974
+ ) }),
3975
+ /* @__PURE__ */ jsx40("div", { className: "body-1 mt-2 cursor-pointer", children: /* @__PURE__ */ jsx40(
3976
+ IconTrash4,
3977
+ {
3978
+ onClick: () => {
3979
+ const confirm = () => handleDeleteIndicator(index);
3980
+ if (onDeleteClick) {
3981
+ onDeleteClick({ index, item, confirm });
3982
+ } else {
3983
+ confirm();
3984
+ }
3985
+ }
3986
+ }
3987
+ ) })
3864
3988
  ]
3865
- }
3989
+ },
3990
+ index
3866
3991
  )) })
3867
3992
  ] });
3868
3993
  }
@@ -3904,6 +4029,406 @@ var FilterPopUp = (filter) => {
3904
4029
  ] }) : void 0
3905
4030
  ] });
3906
4031
  };
4032
+
4033
+ // src/ProfileSelect/ProfileSelect/ProfileSelect.tsx
4034
+ import { useEffect as useEffect7, useRef as useRef6, useState as useState17 } from "react";
4035
+ import { IconSearch, IconUsers, IconX as IconX4 } from "@tabler/icons-react";
4036
+ import { Input as Input5 } from "antd";
4037
+ import { Fragment as Fragment8, jsx as jsx42, jsxs as jsxs36 } from "react/jsx-runtime";
4038
+ function ProfileSelect({
4039
+ allUser,
4040
+ assignUser,
4041
+ mode,
4042
+ onUpdateAssignUser
4043
+ }) {
4044
+ const [maxVisible, setMaxVisible] = useState17(4);
4045
+ const [userNotAssign, setUserNotAssign] = useState17([]);
4046
+ const [search, setSearch] = useState17("");
4047
+ const [isShowSelect, setIsShowSelect] = useState17(false);
4048
+ const containerRef = useRef6(null);
4049
+ const selectRef = useRef6(null);
4050
+ const avatarSize = 30;
4051
+ const spacing = 8;
4052
+ useEffect7(() => {
4053
+ const handler = (e) => {
4054
+ if (!selectRef?.current?.contains(e.target) && !containerRef?.current?.contains(e.target)) {
4055
+ setIsShowSelect(false);
4056
+ }
4057
+ };
4058
+ document.addEventListener("mousedown", handler);
4059
+ return () => {
4060
+ document.removeEventListener("mousedown", handler);
4061
+ };
4062
+ }, []);
4063
+ useEffect7(() => {
4064
+ if (!containerRef.current) return;
4065
+ const updateWidth = () => {
4066
+ if (containerRef.current) {
4067
+ const rect = containerRef.current.getBoundingClientRect();
4068
+ const count = Math.floor(rect.width / (avatarSize + spacing));
4069
+ setMaxVisible(Math.max(1, count));
4070
+ }
4071
+ };
4072
+ const resizeObserver = new ResizeObserver(updateWidth);
4073
+ resizeObserver.observe(containerRef.current);
4074
+ updateWidth();
4075
+ return () => {
4076
+ resizeObserver.disconnect();
4077
+ };
4078
+ }, [allUser]);
4079
+ useEffect7(() => {
4080
+ setUserNotAssign(
4081
+ allUser.filter((u) => !assignUser.some((au) => au.id === u.id))
4082
+ );
4083
+ }, [allUser, assignUser]);
4084
+ const showPlus = assignUser.length > maxVisible;
4085
+ const visibleUsers = showPlus ? assignUser.slice(0, maxVisible - 1) : assignUser;
4086
+ const extraCount = assignUser.length - (maxVisible - 1);
4087
+ const normalizedSearch = search.trim().toLowerCase();
4088
+ const filteredAssigned = normalizedSearch ? assignUser.filter(
4089
+ (u) => u.name.toLowerCase().includes(normalizedSearch)
4090
+ ) : assignUser;
4091
+ const filteredUnassigned = normalizedSearch ? userNotAssign.filter(
4092
+ (u) => u.name.toLowerCase().includes(normalizedSearch)
4093
+ ) : userNotAssign;
4094
+ return /* @__PURE__ */ jsxs36("div", { ref: containerRef, className: "relative body-1", children: [
4095
+ mode === "icon" ? /* @__PURE__ */ jsx42("button", { children: /* @__PURE__ */ jsx42(
4096
+ IconUsers,
4097
+ {
4098
+ size: 40,
4099
+ className: "p-2 border rounded cursor-pointer",
4100
+ onClick: () => setIsShowSelect(!isShowSelect)
4101
+ }
4102
+ ) }) : mode === "showAssign" ? /* @__PURE__ */ jsxs36(
4103
+ "button",
4104
+ {
4105
+ className: "w-full h-[40px] flex -space-x-2 p-2 border-1 rounded-sm",
4106
+ onClick: () => setIsShowSelect(!isShowSelect),
4107
+ children: [
4108
+ visibleUsers.map((user) => /* @__PURE__ */ jsx42("div", { className: "flex items-center cursor-point", children: /* @__PURE__ */ jsxs36("label", { className: "relative group cursor-pointer", children: [
4109
+ /* @__PURE__ */ jsx42(
4110
+ "img",
4111
+ {
4112
+ src: user.profile,
4113
+ alt: user.name,
4114
+ style: {
4115
+ width: avatarSize,
4116
+ height: avatarSize,
4117
+ borderRadius: "50%"
4118
+ },
4119
+ className: "border border-white group-hover:border-2 group-hover:border-red-500 transition"
4120
+ }
4121
+ ),
4122
+ /* @__PURE__ */ jsx42(
4123
+ "span",
4124
+ {
4125
+ className: "absolute top-0 right-0 -translate-y-2 translate-x-2 \r\n rounded-full bg-white opacity-0 group-hover:opacity-100 \r\n border-2 border-red-500 flex items-center justify-center transition",
4126
+ onClick: () => onUpdateAssignUser(user, "remove"),
4127
+ children: /* @__PURE__ */ jsx42(IconX4, { className: "w-4 h-4 text-red-500" })
4128
+ }
4129
+ )
4130
+ ] }) }, user.id)),
4131
+ showPlus && /* @__PURE__ */ jsxs36(
4132
+ "div",
4133
+ {
4134
+ className: "border border-white flex items-center justify-center bg-gray-300 text-black text-sm",
4135
+ style: {
4136
+ width: avatarSize,
4137
+ height: avatarSize,
4138
+ borderRadius: "50%"
4139
+ },
4140
+ children: [
4141
+ "+",
4142
+ extraCount
4143
+ ]
4144
+ }
4145
+ )
4146
+ ]
4147
+ }
4148
+ ) : /* @__PURE__ */ jsxs36("div", { className: "w-full h-[40px] flex -space-x-2 p-2 border-1 rounded-sm", children: [
4149
+ visibleUsers.map((user) => /* @__PURE__ */ jsx42("div", { className: "flex items-center ", children: /* @__PURE__ */ jsx42("label", { className: "relative group ", children: /* @__PURE__ */ jsx42(
4150
+ "img",
4151
+ {
4152
+ src: user.profile,
4153
+ alt: user.name,
4154
+ style: {
4155
+ width: avatarSize,
4156
+ height: avatarSize,
4157
+ borderRadius: "50%"
4158
+ },
4159
+ className: "border border-white transition"
4160
+ }
4161
+ ) }) }, user.id)),
4162
+ showPlus && /* @__PURE__ */ jsxs36(
4163
+ "div",
4164
+ {
4165
+ className: "border border-white flex items-center justify-center bg-gray-300 text-black text-sm",
4166
+ style: {
4167
+ width: avatarSize,
4168
+ height: avatarSize,
4169
+ borderRadius: "50%"
4170
+ },
4171
+ children: [
4172
+ "+",
4173
+ extraCount
4174
+ ]
4175
+ }
4176
+ )
4177
+ ] }),
4178
+ isShowSelect ? /* @__PURE__ */ jsxs36(
4179
+ "div",
4180
+ {
4181
+ className: "absolute top-12 min-w-[261px] max-w-[400px] w-full h-[314px] p-2 text-xs border-1 rounded-sm ",
4182
+ ref: selectRef,
4183
+ children: [
4184
+ /* @__PURE__ */ jsxs36("div", { className: "flex border-1 rounded-md p-2 gap-2 items-center", children: [
4185
+ /* @__PURE__ */ jsx42(IconSearch, {}),
4186
+ /* @__PURE__ */ jsx42(
4187
+ Input5,
4188
+ {
4189
+ variant: "borderless",
4190
+ placeholder: "\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E0A\u0E37\u0E48\u0E2D",
4191
+ className: "body-3",
4192
+ value: search,
4193
+ onChange: (e) => setSearch(e.target.value)
4194
+ }
4195
+ )
4196
+ ] }),
4197
+ /* @__PURE__ */ jsxs36("div", { className: "overflow-y-auto h-[250px] pt-2 px-4 body-3", children: [
4198
+ filteredAssigned.length > 0 && /* @__PURE__ */ jsxs36(Fragment8, { children: [
4199
+ /* @__PURE__ */ jsx42("div", { children: "\u0E2A\u0E21\u0E32\u0E0A\u0E34\u0E01\u0E17\u0E35\u0E48\u0E40\u0E25\u0E37\u0E2D\u0E01" }),
4200
+ filteredAssigned.map((user) => /* @__PURE__ */ jsxs36(
4201
+ "button",
4202
+ {
4203
+ className: "flex items-center group my-1 w-full p-1 rounded hover:bg-gray-100",
4204
+ onClick: () => onUpdateAssignUser(user, "remove"),
4205
+ children: [
4206
+ /* @__PURE__ */ jsxs36("label", { className: "relative cursor-pointer", children: [
4207
+ /* @__PURE__ */ jsx42(
4208
+ "img",
4209
+ {
4210
+ src: user.profile,
4211
+ alt: user.name,
4212
+ style: {
4213
+ width: avatarSize,
4214
+ height: avatarSize,
4215
+ borderRadius: "50%"
4216
+ },
4217
+ className: "border-2 border-red-500"
4218
+ }
4219
+ ),
4220
+ /* @__PURE__ */ jsx42(
4221
+ "span",
4222
+ {
4223
+ className: "absolute top-0 right-0 -translate-y-2 translate-x-2 \r\n rounded-full bg-white opacity-0 group-hover:opacity-100 \r\n border-2 border-red-500 flex items-center justify-center transition",
4224
+ onClick: () => onUpdateAssignUser(user, "remove"),
4225
+ children: /* @__PURE__ */ jsx42(IconX4, { className: "text-red-500", size: 15 })
4226
+ }
4227
+ )
4228
+ ] }),
4229
+ /* @__PURE__ */ jsx42("span", { className: "ml-2", children: user.name })
4230
+ ]
4231
+ },
4232
+ user.id
4233
+ ))
4234
+ ] }),
4235
+ /* @__PURE__ */ jsx42("div", { children: "\u0E1C\u0E39\u0E49\u0E04\u0E19 " }),
4236
+ filteredUnassigned.map((user) => /* @__PURE__ */ jsxs36(
4237
+ "button",
4238
+ {
4239
+ className: "flex items-center my-1 hover:bg-gray-100 w-full p-1 rounded",
4240
+ onClick: () => onUpdateAssignUser(user),
4241
+ children: [
4242
+ /* @__PURE__ */ jsx42(
4243
+ "img",
4244
+ {
4245
+ src: user.profile,
4246
+ alt: user.name,
4247
+ style: {
4248
+ width: avatarSize,
4249
+ height: avatarSize,
4250
+ borderRadius: "50%"
4251
+ },
4252
+ className: "border "
4253
+ }
4254
+ ),
4255
+ /* @__PURE__ */ jsx42("span", { className: "ml-2", children: user.name })
4256
+ ]
4257
+ },
4258
+ user.id
4259
+ ))
4260
+ ] })
4261
+ ]
4262
+ }
4263
+ ) : null
4264
+ ] });
4265
+ }
4266
+
4267
+ // src/Button/QRCode/QRCode.tsx
4268
+ import { useEffect as useEffect8, useRef as useRef7, useState as useState18 } from "react";
4269
+ import QRCode from "qrcode";
4270
+ import { jsx as jsx43, jsxs as jsxs37 } from "react/jsx-runtime";
4271
+ var QRCodeGenerator = ({
4272
+ url,
4273
+ previewSize = 200,
4274
+ defaultExportSize = 512,
4275
+ fileBaseName = "qr-code"
4276
+ }) => {
4277
+ const canvasRef = useRef7(null);
4278
+ const [format3, setFormat] = useState18("png");
4279
+ const [exportSize, setExportSize] = useState18(defaultExportSize);
4280
+ const sizeOption = [
4281
+ {
4282
+ label: "64 x 64",
4283
+ value: "64"
4284
+ },
4285
+ {
4286
+ label: "128 x 128",
4287
+ value: "128"
4288
+ },
4289
+ {
4290
+ label: "256 x 256",
4291
+ value: "256"
4292
+ },
4293
+ {
4294
+ label: "512 x 512",
4295
+ value: "512"
4296
+ },
4297
+ {
4298
+ label: "1024 x 1024",
4299
+ value: "1024"
4300
+ },
4301
+ {
4302
+ label: "2048 x 2048",
4303
+ value: "2048"
4304
+ },
4305
+ {
4306
+ label: "4096 x 4096",
4307
+ value: "4096"
4308
+ }
4309
+ ];
4310
+ const typeOption = [
4311
+ {
4312
+ label: "PNG",
4313
+ value: "png"
4314
+ },
4315
+ {
4316
+ label: "SVG",
4317
+ value: "svg"
4318
+ },
4319
+ {
4320
+ label: "JPEG",
4321
+ value: "jpeg"
4322
+ }
4323
+ ];
4324
+ useEffect8(() => {
4325
+ if (!canvasRef.current) return;
4326
+ QRCode.toCanvas(canvasRef.current, url, { width: previewSize, margin: 1 }, (error) => {
4327
+ if (error) console.error(error);
4328
+ });
4329
+ }, [url, previewSize]);
4330
+ const download = async () => {
4331
+ try {
4332
+ if (format3 === "svg") {
4333
+ const svgString = await QRCode.toString(url, {
4334
+ type: "svg",
4335
+ width: exportSize,
4336
+ margin: 1
4337
+ });
4338
+ const blob = new Blob([svgString], { type: "image/svg+xml" });
4339
+ const objUrl = URL.createObjectURL(blob);
4340
+ triggerDownload(objUrl, `${fileBaseName}.svg`);
4341
+ URL.revokeObjectURL(objUrl);
4342
+ } else {
4343
+ const offscreen = document.createElement("canvas");
4344
+ await QRCode.toCanvas(offscreen, url, {
4345
+ width: exportSize,
4346
+ margin: 1
4347
+ });
4348
+ const mime = format3 === "png" ? "image/png" : "image/jpeg";
4349
+ const dataURL = format3 === "jpeg" ? offscreen.toDataURL(mime, 0.92) : offscreen.toDataURL(mime);
4350
+ triggerDownload(dataURL, `${fileBaseName}.${format3}`);
4351
+ }
4352
+ } catch (err) {
4353
+ console.error("Failed to generate QR export:", err);
4354
+ alert("Sorry, something went wrong creating the download.");
4355
+ }
4356
+ };
4357
+ const triggerDownload = (href, filename) => {
4358
+ const a = document.createElement("a");
4359
+ a.href = href;
4360
+ a.download = filename;
4361
+ document.body.appendChild(a);
4362
+ a.click();
4363
+ a.remove();
4364
+ };
4365
+ return /* @__PURE__ */ jsxs37("div", { style: { display: "inline-flex", flexDirection: "column", gap: 8 }, className: "justify-center items-center", children: [
4366
+ url === "" ? /* @__PURE__ */ jsx43("div", { className: "border-1 p-2 mb-2", style: { width: `${previewSize}px`, height: `${previewSize}px` } }) : /* @__PURE__ */ jsx43("canvas", { ref: canvasRef, className: "border-1 p-2 mb-2" }),
4367
+ /* @__PURE__ */ jsxs37(
4368
+ "div",
4369
+ {
4370
+ style: {
4371
+ display: "flex",
4372
+ gap: 8,
4373
+ alignItems: "center",
4374
+ flexWrap: "wrap"
4375
+ },
4376
+ className: "flex-col",
4377
+ children: [
4378
+ /* @__PURE__ */ jsxs37("div", { className: "flex gap-2 mx-2", children: [
4379
+ /* @__PURE__ */ jsx43("label", { className: "border-1 p-2 rounded-md flex flex-col w-1/2 text-sm text-gray-400", children: /* @__PURE__ */ jsx43(
4380
+ SelectField,
4381
+ {
4382
+ label: "\u0E23\u0E39\u0E1B\u0E41\u0E1A\u0E1A",
4383
+ value: format3,
4384
+ onChange: (e) => setFormat(e.target.value),
4385
+ options: typeOption
4386
+ }
4387
+ ) }),
4388
+ /* @__PURE__ */ jsx43("label", { className: "border-1 p-2 rounded-md flex flex-col w-1/2 text-sm text-gray-400", children: /* @__PURE__ */ jsx43(
4389
+ SelectField,
4390
+ {
4391
+ label: "\u0E02\u0E19\u0E32\u0E14 (px)",
4392
+ value: exportSize,
4393
+ onChange: (e) => setExportSize(Number(e.target.value)),
4394
+ options: sizeOption
4395
+ }
4396
+ ) })
4397
+ ] }),
4398
+ /* @__PURE__ */ jsx43(PrimaryButton, { onClick: download, disabled: url === "", textColor: "white", title: "\u0E14\u0E32\u0E27\u0E42\u0E2B\u0E25\u0E14\u0E23\u0E2B\u0E31\u0E2A QR" })
4399
+ ]
4400
+ }
4401
+ )
4402
+ ] });
4403
+ };
4404
+
4405
+ // src/TabPropject/Tabproject/TabProject.tsx
4406
+ import { Tabs } from "antd";
4407
+ import { jsx as jsx44, jsxs as jsxs38 } from "react/jsx-runtime";
4408
+ function TabProject({ tabOption, now, onChange }) {
4409
+ return /* @__PURE__ */ jsx44(
4410
+ Tabs,
4411
+ {
4412
+ activeKey: now,
4413
+ items: tabOption.map((item, i) => {
4414
+ return {
4415
+ key: item.key,
4416
+ label: /* @__PURE__ */ jsxs38(
4417
+ "button",
4418
+ {
4419
+ className: "tab-label flex gap-2 items-center body-1",
4420
+ onClick: () => onChange(item.key),
4421
+ children: [
4422
+ item.icon,
4423
+ /* @__PURE__ */ jsx44("span", { children: item.label })
4424
+ ]
4425
+ }
4426
+ )
4427
+ };
4428
+ })
4429
+ }
4430
+ );
4431
+ }
3907
4432
  export {
3908
4433
  AntDModal,
3909
4434
  AntDataTable,
@@ -3927,7 +4452,9 @@ export {
3927
4452
  Loader,
3928
4453
  MenuNavBar,
3929
4454
  PrimaryButton,
4455
+ ProfileSelect,
3930
4456
  ProgressBar,
4457
+ QRCodeGenerator,
3931
4458
  Radio,
3932
4459
  RadioGroup,
3933
4460
  SecondaryButton,
@@ -3941,6 +4468,7 @@ export {
3941
4468
  SortFilter,
3942
4469
  Switch,
3943
4470
  SwitchSelect,
4471
+ TabProject,
3944
4472
  TabSelectionButton,
3945
4473
  TextAreaInput,
3946
4474
  TextInput,