|
|
|
@ -9,6 +9,7 @@ import {
|
|
|
|
|
message,
|
|
|
|
|
Modal,
|
|
|
|
|
Select,
|
|
|
|
|
Space,
|
|
|
|
|
Table,
|
|
|
|
|
Tooltip,
|
|
|
|
|
Typography,
|
|
|
|
@ -24,8 +25,10 @@ import {
|
|
|
|
|
EditOutlined,
|
|
|
|
|
EllipsisOutlined,
|
|
|
|
|
InfoCircleOutlined,
|
|
|
|
|
LeftOutlined,
|
|
|
|
|
PlusOutlined,
|
|
|
|
|
QuestionCircleOutlined,
|
|
|
|
|
RightOutlined,
|
|
|
|
|
SearchOutlined,
|
|
|
|
|
} from "@ant-design/icons";
|
|
|
|
|
import { theme } from "antd";
|
|
|
|
@ -36,6 +39,7 @@ import dayjs from "dayjs";
|
|
|
|
|
import "dayjs/locale/en";
|
|
|
|
|
import localizedFormat from "dayjs/plugin/localizedFormat";
|
|
|
|
|
import { useTeamData } from "../../Hooks/Teams";
|
|
|
|
|
import { useRoleData } from "../../Hooks/Role";
|
|
|
|
|
|
|
|
|
|
type Employee = {
|
|
|
|
|
id: number;
|
|
|
|
@ -86,6 +90,28 @@ const AccountingCurrent: React.FC = () => {
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const [page, setPage] = useState(1);
|
|
|
|
|
const [pageSize, setPageSize] = useState(10);
|
|
|
|
|
|
|
|
|
|
const pageSizeOptions = [10, 20, 30, 40, 50];
|
|
|
|
|
|
|
|
|
|
const handlePageSizeChange = (value: number) => {
|
|
|
|
|
setPageSize(value);
|
|
|
|
|
setPage(1);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const Next = () => {
|
|
|
|
|
const a = Number(page) + 1;
|
|
|
|
|
setPage(a);
|
|
|
|
|
};
|
|
|
|
|
const Previos = () => {
|
|
|
|
|
Number(page);
|
|
|
|
|
if (page > 1) {
|
|
|
|
|
const a = Number(page) - 1;
|
|
|
|
|
setPage(a);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const [selectedUserId, setSelectedUserId] = useState(null);
|
|
|
|
|
const [selectedDate, setSelectedDate] = useState<dayjs.Dayjs | null>(null);
|
|
|
|
|
|
|
|
|
@ -98,8 +124,12 @@ const AccountingCurrent: React.FC = () => {
|
|
|
|
|
const [chargesData, setChargesData] = useState([]);
|
|
|
|
|
|
|
|
|
|
const [search, setSearch] = useState<string>("");
|
|
|
|
|
|
|
|
|
|
const [team, setTeam] = useState<any>("");
|
|
|
|
|
|
|
|
|
|
const [role, setRole] = useState<any>("");
|
|
|
|
|
const [salaryType, setSalaryType] = useState<any>("");
|
|
|
|
|
|
|
|
|
|
const showBonusModal = (userId: any) => {
|
|
|
|
|
setSelectedUserId(userId); // Tanlangan user_id ni saqlash
|
|
|
|
|
setIsBonusModalVisible(true);
|
|
|
|
@ -119,6 +149,10 @@ const AccountingCurrent: React.FC = () => {
|
|
|
|
|
month: "last",
|
|
|
|
|
search: search,
|
|
|
|
|
team: team,
|
|
|
|
|
page: page,
|
|
|
|
|
page_size: pageSize,
|
|
|
|
|
role: role,
|
|
|
|
|
salary_type: salaryType,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const handleDateChange = (date: dayjs.Dayjs | null) => {
|
|
|
|
@ -502,17 +536,25 @@ const AccountingCurrent: React.FC = () => {
|
|
|
|
|
|
|
|
|
|
const teamData = useTeamData({});
|
|
|
|
|
const teamOptions: { label: string; value: any }[] | undefined =
|
|
|
|
|
teamData?.data?.map((item) => ({
|
|
|
|
|
teamData?.data?.map((item: any) => ({
|
|
|
|
|
label: item?.name,
|
|
|
|
|
value: item?.name,
|
|
|
|
|
}));
|
|
|
|
|
const additionalOption = {
|
|
|
|
|
label: "all",
|
|
|
|
|
value: "",
|
|
|
|
|
};
|
|
|
|
|
if (teamOptions) {
|
|
|
|
|
teamOptions.unshift(additionalOption);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const roleData = useRoleData();
|
|
|
|
|
|
|
|
|
|
const roleOptions: { label: string; value: any }[] | undefined =
|
|
|
|
|
roleData?.data?.map((item: any) => ({
|
|
|
|
|
label: item?.name,
|
|
|
|
|
value: item?.id,
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
const salaryTypeOptions = [
|
|
|
|
|
{ label: "Hybrid", value: "hybrid" },
|
|
|
|
|
{ label: "Task Based", value: "task_based" },
|
|
|
|
|
{ label: "Fixed", value: "fixed" },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const { token } = theme.useToken();
|
|
|
|
|
|
|
|
|
|
const deleteFunctionBonus = (record: any) => {
|
|
|
|
@ -573,10 +615,11 @@ const AccountingCurrent: React.FC = () => {
|
|
|
|
|
style={{
|
|
|
|
|
display: "flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
gap: 12,
|
|
|
|
|
// marginBottom: 10,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div style={{ marginRight: 12 }}>
|
|
|
|
|
<div>
|
|
|
|
|
<Input
|
|
|
|
|
placeholder="Search"
|
|
|
|
|
prefix={<SearchOutlined />}
|
|
|
|
@ -589,11 +632,25 @@ const AccountingCurrent: React.FC = () => {
|
|
|
|
|
onChange={(value: any) => setTeam(value)}
|
|
|
|
|
options={teamOptions}
|
|
|
|
|
/>
|
|
|
|
|
<Select
|
|
|
|
|
style={{ width: 260 }}
|
|
|
|
|
placeholder="Role"
|
|
|
|
|
onChange={(value: any) => setRole(value)}
|
|
|
|
|
options={roleOptions}
|
|
|
|
|
allowClear
|
|
|
|
|
/>
|
|
|
|
|
<Select
|
|
|
|
|
style={{ width: 260 }}
|
|
|
|
|
placeholder="Salary Type"
|
|
|
|
|
onChange={(value: string) => setSalaryType(value)}
|
|
|
|
|
options={salaryTypeOptions}
|
|
|
|
|
allowClear
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
disabled={data?.some((item) => item.is_confirmed)}
|
|
|
|
|
disabled={data?.data?.some((item: any) => item.is_confirmed)}
|
|
|
|
|
type="primary"
|
|
|
|
|
onClick={() =>
|
|
|
|
|
Modal.confirm({
|
|
|
|
@ -689,7 +746,7 @@ const AccountingCurrent: React.FC = () => {
|
|
|
|
|
<Table
|
|
|
|
|
size="small"
|
|
|
|
|
loading={isLoading}
|
|
|
|
|
dataSource={data?.map((u, i) => ({
|
|
|
|
|
dataSource={data?.data?.map((u: any, i: any) => ({
|
|
|
|
|
no: i + 1,
|
|
|
|
|
...u,
|
|
|
|
|
}))}
|
|
|
|
@ -722,24 +779,6 @@ const AccountingCurrent: React.FC = () => {
|
|
|
|
|
title: "Role",
|
|
|
|
|
dataIndex: "role",
|
|
|
|
|
key: "role",
|
|
|
|
|
filters: [
|
|
|
|
|
{
|
|
|
|
|
text: "Tech Support",
|
|
|
|
|
value: "Tech Support",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
text: "Checker",
|
|
|
|
|
value: "Checker",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
text: "Accountant",
|
|
|
|
|
value: "Accountant",
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
filterMultiple: false,
|
|
|
|
|
onFilter: (value: any, record: any) => {
|
|
|
|
|
return record.role === value;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: "Team",
|
|
|
|
@ -770,25 +809,6 @@ const AccountingCurrent: React.FC = () => {
|
|
|
|
|
return <p>{record.salary_type}</p>;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
filters: [
|
|
|
|
|
{
|
|
|
|
|
text: "Hybrid",
|
|
|
|
|
value: "hybrid",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
text: "Task Based",
|
|
|
|
|
value: "task_based",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
text: "Fixed",
|
|
|
|
|
value: "fixed",
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
filterMultiple: false,
|
|
|
|
|
// defaultFilteredValue: ["hybrid"],
|
|
|
|
|
onFilter: (value: any, record: any) => {
|
|
|
|
|
return record.salary_type === value;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: "Base Salary",
|
|
|
|
@ -841,7 +861,7 @@ const AccountingCurrent: React.FC = () => {
|
|
|
|
|
<Dropdown
|
|
|
|
|
overlay={menu(record.employee_id)}
|
|
|
|
|
trigger={["click"]}
|
|
|
|
|
disabled={data?.some((item) => item.is_confirmed)}
|
|
|
|
|
disabled={data?.data?.some((item: any) => item.is_confirmed)}
|
|
|
|
|
>
|
|
|
|
|
<Button
|
|
|
|
|
icon={<EllipsisOutlined />}
|
|
|
|
@ -855,23 +875,24 @@ const AccountingCurrent: React.FC = () => {
|
|
|
|
|
index % 2 === 0 ? "odd-row" : "even-row"
|
|
|
|
|
}
|
|
|
|
|
bordered
|
|
|
|
|
pagination={{
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
size: "default",
|
|
|
|
|
style: {
|
|
|
|
|
margin: 0,
|
|
|
|
|
justifyContent: "end",
|
|
|
|
|
position: "fixed",
|
|
|
|
|
bottom: 0,
|
|
|
|
|
left: 0,
|
|
|
|
|
width: "100%",
|
|
|
|
|
backgroundColor: token.colorBgContainer,
|
|
|
|
|
boxShadow: "0 4px 8px rgba(0, 0, 0, 0.4)",
|
|
|
|
|
padding: "10px 0",
|
|
|
|
|
zIndex: 1000,
|
|
|
|
|
},
|
|
|
|
|
showLessItems: true,
|
|
|
|
|
}}
|
|
|
|
|
// pagination={{
|
|
|
|
|
// pageSize: 10,
|
|
|
|
|
// size: "default",
|
|
|
|
|
// style: {
|
|
|
|
|
// margin: 0,
|
|
|
|
|
// justifyContent: "end",
|
|
|
|
|
// position: "fixed",
|
|
|
|
|
// bottom: 0,
|
|
|
|
|
// left: 0,
|
|
|
|
|
// width: "100%",
|
|
|
|
|
// backgroundColor: token.colorBgContainer,
|
|
|
|
|
// boxShadow: "0 4px 8px rgba(0, 0, 0, 0.4)",
|
|
|
|
|
// padding: "10px 0",
|
|
|
|
|
// zIndex: 1000,
|
|
|
|
|
// },
|
|
|
|
|
// showLessItems: true,
|
|
|
|
|
// }}
|
|
|
|
|
pagination={false}
|
|
|
|
|
onRow={(record) => ({
|
|
|
|
|
onClick: (e) => handleRowClick(record, e),
|
|
|
|
|
})}
|
|
|
|
@ -1123,7 +1144,9 @@ const AccountingCurrent: React.FC = () => {
|
|
|
|
|
<>
|
|
|
|
|
<Button
|
|
|
|
|
icon={<EditOutlined />}
|
|
|
|
|
disabled={data?.some((item) => item.is_confirmed)}
|
|
|
|
|
disabled={data?.data?.some(
|
|
|
|
|
(item: any) => item.is_confirmed
|
|
|
|
|
)}
|
|
|
|
|
onClick={() => showModalBonusEdit(record)}
|
|
|
|
|
style={{ marginRight: 8 }}
|
|
|
|
|
/>
|
|
|
|
@ -1134,7 +1157,9 @@ const AccountingCurrent: React.FC = () => {
|
|
|
|
|
}}
|
|
|
|
|
icon={<DeleteOutlined />}
|
|
|
|
|
onClick={() => deleteFunctionBonus(record)}
|
|
|
|
|
disabled={data?.some((item) => item.is_confirmed)}
|
|
|
|
|
disabled={data?.data?.some(
|
|
|
|
|
(item: any) => item.is_confirmed
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
</>
|
|
|
|
|
),
|
|
|
|
@ -1191,7 +1216,9 @@ const AccountingCurrent: React.FC = () => {
|
|
|
|
|
<>
|
|
|
|
|
<Button
|
|
|
|
|
icon={<EditOutlined />}
|
|
|
|
|
disabled={data?.some((item) => item.is_confirmed)}
|
|
|
|
|
disabled={data?.data?.some(
|
|
|
|
|
(item: any) => item.is_confirmed
|
|
|
|
|
)}
|
|
|
|
|
onClick={() => showModal(record)}
|
|
|
|
|
style={{ marginRight: 8 }}
|
|
|
|
|
/>
|
|
|
|
@ -1202,7 +1229,9 @@ const AccountingCurrent: React.FC = () => {
|
|
|
|
|
}}
|
|
|
|
|
icon={<DeleteOutlined />}
|
|
|
|
|
onClick={() => deleteFunctionCharge(record)}
|
|
|
|
|
disabled={data?.some((item) => item.is_confirmed)}
|
|
|
|
|
disabled={data?.data?.some(
|
|
|
|
|
(item: any) => item.is_confirmed
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
</>
|
|
|
|
|
),
|
|
|
|
@ -1435,6 +1464,73 @@ const AccountingCurrent: React.FC = () => {
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Form>
|
|
|
|
|
</Modal>
|
|
|
|
|
<Space style={{ width: "100%", marginTop: 40 }} direction="vertical">
|
|
|
|
|
<Space
|
|
|
|
|
style={{
|
|
|
|
|
justifyContent: "end",
|
|
|
|
|
position: "fixed",
|
|
|
|
|
bottom: 0,
|
|
|
|
|
left: 0,
|
|
|
|
|
width: "100%",
|
|
|
|
|
backgroundColor: token.colorBgContainer,
|
|
|
|
|
boxShadow: "0 4px 8px rgba(0, 0, 0, 0.4)",
|
|
|
|
|
padding: "10px 0",
|
|
|
|
|
zIndex: 1000,
|
|
|
|
|
}}
|
|
|
|
|
wrap
|
|
|
|
|
>
|
|
|
|
|
<Select
|
|
|
|
|
value={pageSize}
|
|
|
|
|
onChange={handlePageSizeChange}
|
|
|
|
|
style={{ width: 65, marginRight: 16 }}
|
|
|
|
|
options={pageSizeOptions.map((size) => ({
|
|
|
|
|
label: `${size}`,
|
|
|
|
|
value: size,
|
|
|
|
|
}))}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
onClick={Previos}
|
|
|
|
|
disabled={data?.previous ? false : true}
|
|
|
|
|
style={{
|
|
|
|
|
backgroundColor: token.colorBgContainer,
|
|
|
|
|
color: token.colorText,
|
|
|
|
|
border: "none",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<LeftOutlined />
|
|
|
|
|
</Button>
|
|
|
|
|
<Input
|
|
|
|
|
disabled
|
|
|
|
|
style={{
|
|
|
|
|
width: 40,
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
background: token.colorBgContainer,
|
|
|
|
|
border: "1px solid",
|
|
|
|
|
borderColor: token.colorText,
|
|
|
|
|
color: token.colorText,
|
|
|
|
|
}}
|
|
|
|
|
value={page}
|
|
|
|
|
onChange={(e) => {
|
|
|
|
|
let num = e.target.value;
|
|
|
|
|
if (Number(num) && num !== "0") {
|
|
|
|
|
setPage(Number(num));
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<Button
|
|
|
|
|
onClick={Next}
|
|
|
|
|
disabled={data?.next ? false : true}
|
|
|
|
|
style={{
|
|
|
|
|
backgroundColor: token.colorBgContainer,
|
|
|
|
|
color: token.colorText,
|
|
|
|
|
border: "none",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<RightOutlined />
|
|
|
|
|
</Button>
|
|
|
|
|
</Space>
|
|
|
|
|
</Space>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|