parent
							
								
									8b53f23835
								
							
						
					
					
						commit
						77863b959d
					
				@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					import {
 | 
				
			||||||
 | 
					  TAccounting,
 | 
				
			||||||
 | 
					  TAccountingHistory,
 | 
				
			||||||
 | 
					} from "../../types/Accounting/TAccounting";
 | 
				
			||||||
 | 
					import instance from "../api";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type TAccountingGetParams = {
 | 
				
			||||||
 | 
					  month: string;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const AccountingController = {
 | 
				
			||||||
 | 
					  async read(filterObject: TAccountingGetParams) {
 | 
				
			||||||
 | 
					    const params = { ...filterObject };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!!filterObject.month) params.month = filterObject.month;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const { data } = await instance.get<TAccounting[]>(`/employees-salaries/`, {
 | 
				
			||||||
 | 
					      params,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return data;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  async history() {
 | 
				
			||||||
 | 
					    const { data } = await instance.get<TAccountingHistory[]>(
 | 
				
			||||||
 | 
					      `/employees-salaries-history/`
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    return data;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					import { Tabs, Typography } from "antd";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import React, { useState } from "react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import TabPane from "antd/es/tabs/TabPane";
 | 
				
			||||||
 | 
					import AccountingCurrent from "./AccountingCurrent";
 | 
				
			||||||
 | 
					import AccountingLast from "./AccountingLast";
 | 
				
			||||||
 | 
					import AccountingHistory from "./AccountingHistory";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Accounting: React.FC = () => {
 | 
				
			||||||
 | 
					  const [activeTab, setActiveTab] = useState("1");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					      <div
 | 
				
			||||||
 | 
					        className="header d-flex  statistics-header"
 | 
				
			||||||
 | 
					        style={{ marginBottom: 16 }}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <Typography className="title">Accounting</Typography>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <Tabs
 | 
				
			||||||
 | 
					        defaultActiveKey="1"
 | 
				
			||||||
 | 
					        activeKey={activeTab}
 | 
				
			||||||
 | 
					        onChange={(key) => setActiveTab(key)}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <TabPane
 | 
				
			||||||
 | 
					          tab={
 | 
				
			||||||
 | 
					            <span style={{ display: "flex", alignItems: "center" }}>
 | 
				
			||||||
 | 
					              Current Month
 | 
				
			||||||
 | 
					            </span>
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          key="1"
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <AccountingCurrent />
 | 
				
			||||||
 | 
					        </TabPane>
 | 
				
			||||||
 | 
					        <TabPane
 | 
				
			||||||
 | 
					          tab={
 | 
				
			||||||
 | 
					            <span style={{ display: "flex", alignItems: "center" }}>
 | 
				
			||||||
 | 
					              Last Month
 | 
				
			||||||
 | 
					            </span>
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          key="2"
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <AccountingLast />
 | 
				
			||||||
 | 
					        </TabPane>
 | 
				
			||||||
 | 
					        <TabPane
 | 
				
			||||||
 | 
					          tab={
 | 
				
			||||||
 | 
					            <span style={{ display: "flex", alignItems: "center" }}>
 | 
				
			||||||
 | 
					              History
 | 
				
			||||||
 | 
					            </span>
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          key="3"
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <AccountingHistory />
 | 
				
			||||||
 | 
					        </TabPane>
 | 
				
			||||||
 | 
					      </Tabs>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Accounting;
 | 
				
			||||||
@ -0,0 +1,178 @@
 | 
				
			|||||||
 | 
					import { Table, Tooltip } from "antd";
 | 
				
			||||||
 | 
					import React from "react";
 | 
				
			||||||
 | 
					import tagIcon from "../../assets/tagIcon.png";
 | 
				
			||||||
 | 
					import { QuestionCircleOutlined } from "@ant-design/icons";
 | 
				
			||||||
 | 
					import { theme } from "antd";
 | 
				
			||||||
 | 
					import { useAccountingData } from "../../Hooks/Accounting";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const AccountingCurrent: React.FC = () => {
 | 
				
			||||||
 | 
					  const { data, refetch, isLoading } = useAccountingData({
 | 
				
			||||||
 | 
					    month: "current",
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const { token } = theme.useToken();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					      <Table
 | 
				
			||||||
 | 
					        size="small"
 | 
				
			||||||
 | 
					        loading={isLoading}
 | 
				
			||||||
 | 
					        dataSource={data?.map((u, i) => ({
 | 
				
			||||||
 | 
					          no: i + 1,
 | 
				
			||||||
 | 
					          ...u,
 | 
				
			||||||
 | 
					        }))}
 | 
				
			||||||
 | 
					        columns={[
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: <img src={tagIcon} alt="" />,
 | 
				
			||||||
 | 
					            dataIndex: "no",
 | 
				
			||||||
 | 
					            key: "no",
 | 
				
			||||||
 | 
					            width: "5%",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Username",
 | 
				
			||||||
 | 
					            dataIndex: "username",
 | 
				
			||||||
 | 
					            key: "username",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Tasks",
 | 
				
			||||||
 | 
					            dataIndex: "number_of_tasks",
 | 
				
			||||||
 | 
					            key: "number_of_tasks",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Points",
 | 
				
			||||||
 | 
					            dataIndex: "total_points",
 | 
				
			||||||
 | 
					            key: "total_points",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Salary Type",
 | 
				
			||||||
 | 
					            dataIndex: "salary_type",
 | 
				
			||||||
 | 
					            render: (value: any, record: any) => {
 | 
				
			||||||
 | 
					              if (record.salary_type === "task_based") {
 | 
				
			||||||
 | 
					                return <p>Task Based</p>;
 | 
				
			||||||
 | 
					              } else if (record.salary_type === "hybrid") {
 | 
				
			||||||
 | 
					                return <p>Hybrid</p>;
 | 
				
			||||||
 | 
					              } else {
 | 
				
			||||||
 | 
					                return <p>{record.salary_type}</p>; // Agar boshqa qiymat bo'lsa, oddiy qilib chiqariladi
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            filters: [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                text: "Hybrid",
 | 
				
			||||||
 | 
					                value: "hybrid",
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                text: "Task Based",
 | 
				
			||||||
 | 
					                value: "task_based",
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            filterMultiple: false,
 | 
				
			||||||
 | 
					            // defaultFilteredValue: ["hybrid"],
 | 
				
			||||||
 | 
					            onFilter: (value: any, record: any) => {
 | 
				
			||||||
 | 
					              return record.salary_type === value;
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Base Salary",
 | 
				
			||||||
 | 
					            dataIndex: "salary_base_amount",
 | 
				
			||||||
 | 
					            render: (text: string, record: any) => (
 | 
				
			||||||
 | 
					              <p>${record?.salary_base_amount}</p>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Performance Salary",
 | 
				
			||||||
 | 
					            dataIndex: "performance_salary",
 | 
				
			||||||
 | 
					            render: (text: string, record: any) => (
 | 
				
			||||||
 | 
					              <p>${record?.performance_salary}</p>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Charges",
 | 
				
			||||||
 | 
					            dataIndex: "total_charges",
 | 
				
			||||||
 | 
					            render: (text: string, record: any) => (
 | 
				
			||||||
 | 
					              <p>${record?.total_charges}</p>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Bonuses",
 | 
				
			||||||
 | 
					            dataIndex: "total_bonuses",
 | 
				
			||||||
 | 
					            render: (text: string, record: any) => (
 | 
				
			||||||
 | 
					              <p>${record?.total_bonuses}</p>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: (
 | 
				
			||||||
 | 
					              <div>
 | 
				
			||||||
 | 
					                <span>Salary</span>  
 | 
				
			||||||
 | 
					                <Tooltip title="The calculation of salary begins at the start of the month and continues to the current day. Select a month to review salary details for prior periods.">
 | 
				
			||||||
 | 
					                  <QuestionCircleOutlined />
 | 
				
			||||||
 | 
					                </Tooltip>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            dataIndex: "salary",
 | 
				
			||||||
 | 
					            key: "salary",
 | 
				
			||||||
 | 
					            render: (text: string, record: any) => (
 | 
				
			||||||
 | 
					              <Tooltip
 | 
				
			||||||
 | 
					                title={
 | 
				
			||||||
 | 
					                  <div>
 | 
				
			||||||
 | 
					                    {record.salary_type === "hybrid" ? (
 | 
				
			||||||
 | 
					                      <p>
 | 
				
			||||||
 | 
					                        <strong>Fixed Amount:</strong> $
 | 
				
			||||||
 | 
					                        {record.salary_base_amount}
 | 
				
			||||||
 | 
					                      </p>
 | 
				
			||||||
 | 
					                    ) : (
 | 
				
			||||||
 | 
					                      ""
 | 
				
			||||||
 | 
					                    )}
 | 
				
			||||||
 | 
					                    <p>
 | 
				
			||||||
 | 
					                      <strong>Performance based amount:</strong> $
 | 
				
			||||||
 | 
					                      {record.performance_based_amount}
 | 
				
			||||||
 | 
					                    </p>
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                overlayStyle={{
 | 
				
			||||||
 | 
					                  maxWidth: "700px",
 | 
				
			||||||
 | 
					                }}
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                <span>${record.salary}</span>
 | 
				
			||||||
 | 
					              </Tooltip>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            // sorter: (a: any, b: any) => a.salary - b.total_points,
 | 
				
			||||||
 | 
					            // sortDirections: ["ascend", "descend"],
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        ]}
 | 
				
			||||||
 | 
					        rowClassName={(record, index) =>
 | 
				
			||||||
 | 
					          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,
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // onRow={(record) => ({
 | 
				
			||||||
 | 
					        //   onClick: () => {
 | 
				
			||||||
 | 
					        //     if (record.user && record.user.id) {
 | 
				
			||||||
 | 
					        //       navigate(`/accounting/${record.user.id}`); // `user.id`ni olish
 | 
				
			||||||
 | 
					        //     } else {
 | 
				
			||||||
 | 
					        //       console.error("User ID mavjud emas");
 | 
				
			||||||
 | 
					        //     }
 | 
				
			||||||
 | 
					        //   },
 | 
				
			||||||
 | 
					        // })}
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default AccountingCurrent;
 | 
				
			||||||
@ -0,0 +1,188 @@
 | 
				
			|||||||
 | 
					import React, { useEffect, useState } from "react";
 | 
				
			||||||
 | 
					import { useParams } from "react-router-dom";
 | 
				
			||||||
 | 
					import axios from "axios";
 | 
				
			||||||
 | 
					import Typography from "antd/es/typography/Typography";
 | 
				
			||||||
 | 
					import { DatePicker, DatePickerProps, Table } from "antd";
 | 
				
			||||||
 | 
					import tagIcon from "../../assets/tagIcon.png";
 | 
				
			||||||
 | 
					import dayjs from "dayjs";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface User {
 | 
				
			||||||
 | 
					  id: number;
 | 
				
			||||||
 | 
					  first_name: string;
 | 
				
			||||||
 | 
					  last_name: string;
 | 
				
			||||||
 | 
					  username: string;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface Salary {
 | 
				
			||||||
 | 
					  id: number;
 | 
				
			||||||
 | 
					  month: string;
 | 
				
			||||||
 | 
					  year: number;
 | 
				
			||||||
 | 
					  number_of_tasks: number;
 | 
				
			||||||
 | 
					  total_points: number;
 | 
				
			||||||
 | 
					  salary_type: string;
 | 
				
			||||||
 | 
					  base_salary: number;
 | 
				
			||||||
 | 
					  performance_salary: number;
 | 
				
			||||||
 | 
					  total_salary: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface Data {
 | 
				
			||||||
 | 
					  user: User;
 | 
				
			||||||
 | 
					  salaries: Salary[];
 | 
				
			||||||
 | 
					  total: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const AccountingDetails = () => {
 | 
				
			||||||
 | 
					  const { id } = useParams();
 | 
				
			||||||
 | 
					  const [user, setUser] = useState<Data | null>(null);
 | 
				
			||||||
 | 
					  const [loading, setLoading] = useState(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const now = dayjs();
 | 
				
			||||||
 | 
					  const moment = require("moment");
 | 
				
			||||||
 | 
					  const currentDate = moment();
 | 
				
			||||||
 | 
					  // const defaultDate = `${currentDate.format("YYYY")}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const disabledDate = (current: any) => {
 | 
				
			||||||
 | 
					    return current && current.year() > moment().year();
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const [date, setDate] = useState<string | null>(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const onChangeDate: DatePickerProps["onChange"] = (date) => {
 | 
				
			||||||
 | 
					    if (!date) {
 | 
				
			||||||
 | 
					      setDate("");
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      const year = date.format("YYYY");
 | 
				
			||||||
 | 
					      setDate(year);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    const fetchUserDetails = async () => {
 | 
				
			||||||
 | 
					      const API_URL = `https://api.tteld.co/api/v1/user-salaries/${id}`;
 | 
				
			||||||
 | 
					      const AUTH_TOKEN = localStorage.getItem("access");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
 | 
					        const response = await axios.get(API_URL, {
 | 
				
			||||||
 | 
					          params: {
 | 
				
			||||||
 | 
					            user_id: id,
 | 
				
			||||||
 | 
					            year: date,
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          headers: {
 | 
				
			||||||
 | 
					            Authorization: `Bearer ${AUTH_TOKEN}`,
 | 
				
			||||||
 | 
					            "Content-Type": "application/json",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          maxRedirects: 0,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        setUser(response.data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        setLoading(false);
 | 
				
			||||||
 | 
					      } catch (error: any) {
 | 
				
			||||||
 | 
					        console.error("Error:", error.response?.status, error.response?.data);
 | 
				
			||||||
 | 
					        setLoading(false);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fetchUserDetails();
 | 
				
			||||||
 | 
					  }, [date]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <>
 | 
				
			||||||
 | 
					      <div
 | 
				
			||||||
 | 
					        className="header d-flex  statistics-header"
 | 
				
			||||||
 | 
					        style={{ marginBottom: 16 }}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <div
 | 
				
			||||||
 | 
					          style={{
 | 
				
			||||||
 | 
					            display: "flex",
 | 
				
			||||||
 | 
					            justifyContent: "center",
 | 
				
			||||||
 | 
					            flexDirection: "column",
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          {user?.user.first_name && user.user.last_name ? (
 | 
				
			||||||
 | 
					            <Typography className="title">
 | 
				
			||||||
 | 
					              {user?.user.first_name} {user?.user.last_name}
 | 
				
			||||||
 | 
					            </Typography>
 | 
				
			||||||
 | 
					          ) : (
 | 
				
			||||||
 | 
					            <Typography className="title">{user?.user.username}</Typography>
 | 
				
			||||||
 | 
					          )}
 | 
				
			||||||
 | 
					          <Typography style={{ fontSize: 18, fontWeight: 700, marginTop: 24 }}>
 | 
				
			||||||
 | 
					            Total: ${user?.total}
 | 
				
			||||||
 | 
					          </Typography>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div>
 | 
				
			||||||
 | 
					          <DatePicker
 | 
				
			||||||
 | 
					            onChange={onChangeDate}
 | 
				
			||||||
 | 
					            picker="year"
 | 
				
			||||||
 | 
					            format={"YYYY"}
 | 
				
			||||||
 | 
					            disabledDate={disabledDate}
 | 
				
			||||||
 | 
					            // defaultValue={now}
 | 
				
			||||||
 | 
					            style={{ marginRight: 10, width: 120, marginBottom: 10 }}
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <Table
 | 
				
			||||||
 | 
					        size="small"
 | 
				
			||||||
 | 
					        loading={loading}
 | 
				
			||||||
 | 
					        dataSource={user?.salaries?.map((u, i) => ({
 | 
				
			||||||
 | 
					          no: i + 1,
 | 
				
			||||||
 | 
					          ...u,
 | 
				
			||||||
 | 
					        }))}
 | 
				
			||||||
 | 
					        columns={[
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: <img src={tagIcon} alt="" />,
 | 
				
			||||||
 | 
					            dataIndex: "no",
 | 
				
			||||||
 | 
					            key: "no",
 | 
				
			||||||
 | 
					            width: "5%",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Salary",
 | 
				
			||||||
 | 
					            dataIndex: "total_salary",
 | 
				
			||||||
 | 
					            render(value, record, index) {
 | 
				
			||||||
 | 
					              return <p>${record?.total_salary}</p>;
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Salary Type",
 | 
				
			||||||
 | 
					            dataIndex: "salary_type",
 | 
				
			||||||
 | 
					            render: (value: any, record: any) => {
 | 
				
			||||||
 | 
					              if (record.salary_type === "task_based") {
 | 
				
			||||||
 | 
					                return <p>Task Based</p>;
 | 
				
			||||||
 | 
					              } else if (record.salary_type === "hybrid") {
 | 
				
			||||||
 | 
					                return <p>Hybrid</p>;
 | 
				
			||||||
 | 
					              } else {
 | 
				
			||||||
 | 
					                return <p>{record.salary_type}</p>; // Agar boshqa qiymat bo'lsa, oddiy qilib chiqariladi
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Base Salary",
 | 
				
			||||||
 | 
					            dataIndex: "base_salary",
 | 
				
			||||||
 | 
					            render(value, record, index) {
 | 
				
			||||||
 | 
					              return <p>${record?.base_salary}</p>;
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Performance Salary",
 | 
				
			||||||
 | 
					            dataIndex: "performance_salary",
 | 
				
			||||||
 | 
					            render(value, record, index) {
 | 
				
			||||||
 | 
					              return <p>${record?.performance_salary}</p>;
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Month",
 | 
				
			||||||
 | 
					            dataIndex: "month",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Year",
 | 
				
			||||||
 | 
					            dataIndex: "year",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        ]}
 | 
				
			||||||
 | 
					        bordered
 | 
				
			||||||
 | 
					        pagination={false}
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					    </>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default AccountingDetails;
 | 
				
			||||||
@ -0,0 +1,158 @@
 | 
				
			|||||||
 | 
					import { Table, Tooltip } from "antd";
 | 
				
			||||||
 | 
					import React from "react";
 | 
				
			||||||
 | 
					import tagIcon from "../../assets/tagIcon.png";
 | 
				
			||||||
 | 
					import { QuestionCircleOutlined } from "@ant-design/icons";
 | 
				
			||||||
 | 
					import { theme } from "antd";
 | 
				
			||||||
 | 
					import { useAccountingHistory } from "../../Hooks/Accounting";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const AccountingHistory: React.FC = () => {
 | 
				
			||||||
 | 
					  const { data, refetch, isLoading } = useAccountingHistory();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const { token } = theme.useToken();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					      <Table
 | 
				
			||||||
 | 
					        size="small"
 | 
				
			||||||
 | 
					        loading={isLoading}
 | 
				
			||||||
 | 
					        dataSource={data?.map((u, i) => ({
 | 
				
			||||||
 | 
					          no: i + 1,
 | 
				
			||||||
 | 
					          ...u,
 | 
				
			||||||
 | 
					        }))}
 | 
				
			||||||
 | 
					        columns={[
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: <img src={tagIcon} alt="" />,
 | 
				
			||||||
 | 
					            dataIndex: "no",
 | 
				
			||||||
 | 
					            key: "no",
 | 
				
			||||||
 | 
					            width: "5%",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Username",
 | 
				
			||||||
 | 
					            dataIndex: "username",
 | 
				
			||||||
 | 
					            key: "username",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Total Tasks",
 | 
				
			||||||
 | 
					            dataIndex: "total_number_of_tasks",
 | 
				
			||||||
 | 
					            key: "total_number_of_tasks",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Total Points",
 | 
				
			||||||
 | 
					            dataIndex: "total_earned_points",
 | 
				
			||||||
 | 
					            key: "total_earned_points",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Total worked months",
 | 
				
			||||||
 | 
					            dataIndex: "salary_months_count",
 | 
				
			||||||
 | 
					            key: "salary_months_count",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Salary Type",
 | 
				
			||||||
 | 
					            dataIndex: "salary_type",
 | 
				
			||||||
 | 
					            render: (value: any, record: any) => {
 | 
				
			||||||
 | 
					              if (record.salary_type === "task_based") {
 | 
				
			||||||
 | 
					                return <p>Task Based</p>;
 | 
				
			||||||
 | 
					              } else if (record.salary_type === "hybrid") {
 | 
				
			||||||
 | 
					                return <p>Hybrid</p>;
 | 
				
			||||||
 | 
					              } else {
 | 
				
			||||||
 | 
					                return <p>{record.salary_type}</p>;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            filters: [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                text: "Hybrid",
 | 
				
			||||||
 | 
					                value: "hybrid",
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                text: "Task Based",
 | 
				
			||||||
 | 
					                value: "task_based",
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            filterMultiple: false,
 | 
				
			||||||
 | 
					            onFilter: (value: any, record: any) => {
 | 
				
			||||||
 | 
					              return record.salary_type === value;
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Base Salary",
 | 
				
			||||||
 | 
					            dataIndex: "total_base_salary",
 | 
				
			||||||
 | 
					            render: (text: string, record: any) => (
 | 
				
			||||||
 | 
					              <p>${record?.total_base_salary}</p>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Performance Salary",
 | 
				
			||||||
 | 
					            dataIndex: "total_performance_salary",
 | 
				
			||||||
 | 
					            render: (text: string, record: any) => (
 | 
				
			||||||
 | 
					              <p>${record?.total_performance_salary}</p>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Total Charges",
 | 
				
			||||||
 | 
					            dataIndex: "total_charges",
 | 
				
			||||||
 | 
					            render: (text: string, record: any) => (
 | 
				
			||||||
 | 
					              <p>${record?.total_charges}</p>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Total Bonuses",
 | 
				
			||||||
 | 
					            dataIndex: "total_bonuses",
 | 
				
			||||||
 | 
					            render: (text: string, record: any) => (
 | 
				
			||||||
 | 
					              <p>${record?.total_bonuses}</p>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: (
 | 
				
			||||||
 | 
					              <div>
 | 
				
			||||||
 | 
					                <span>Total Salary</span> 
 | 
				
			||||||
 | 
					                <Tooltip title="The calculation of salary begins at the start of the month and continues to the current day. Select a month to review salary details for prior periods.">
 | 
				
			||||||
 | 
					                  <QuestionCircleOutlined />
 | 
				
			||||||
 | 
					                </Tooltip>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            dataIndex: "total_earned_salary",
 | 
				
			||||||
 | 
					            key: "total_earned_salary",
 | 
				
			||||||
 | 
					            render: (text: string, record: any) => (
 | 
				
			||||||
 | 
					              <span>${record.total_earned_salary}</span>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            // sorter: (a: any, b: any) => a.salary - b.total_points,
 | 
				
			||||||
 | 
					            // sortDirections: ["ascend", "descend"],
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        ]}
 | 
				
			||||||
 | 
					        rowClassName={(record, index) =>
 | 
				
			||||||
 | 
					          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,
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // onRow={(record) => ({
 | 
				
			||||||
 | 
					        //   onClick: () => {
 | 
				
			||||||
 | 
					        //     if (record.user && record.user.id) {
 | 
				
			||||||
 | 
					        //       navigate(`/accounting/${record.user.id}`); // `user.id`ni olish
 | 
				
			||||||
 | 
					        //     } else {
 | 
				
			||||||
 | 
					        //       console.error("User ID mavjud emas");
 | 
				
			||||||
 | 
					        //     }
 | 
				
			||||||
 | 
					        //   },
 | 
				
			||||||
 | 
					        // })}
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default AccountingHistory;
 | 
				
			||||||
@ -0,0 +1,161 @@
 | 
				
			|||||||
 | 
					import { Button, Table, Tooltip } from "antd";
 | 
				
			||||||
 | 
					import React, { useEffect, useState } from "react";
 | 
				
			||||||
 | 
					import api from "../../API/api";
 | 
				
			||||||
 | 
					import tagIcon from "../../assets/tagIcon.png";
 | 
				
			||||||
 | 
					import { QuestionCircleOutlined } from "@ant-design/icons";
 | 
				
			||||||
 | 
					import { theme } from "antd";
 | 
				
			||||||
 | 
					import { useAccountingData } from "../../Hooks/Accounting";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const AccountingCurrent: React.FC = () => {
 | 
				
			||||||
 | 
					  const { data, refetch, isLoading } = useAccountingData({
 | 
				
			||||||
 | 
					    month: "last",
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const { token } = theme.useToken();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					      <Table
 | 
				
			||||||
 | 
					        size="small"
 | 
				
			||||||
 | 
					        loading={isLoading}
 | 
				
			||||||
 | 
					        dataSource={data?.map((u, i) => ({
 | 
				
			||||||
 | 
					          no: i + 1,
 | 
				
			||||||
 | 
					          ...u,
 | 
				
			||||||
 | 
					        }))}
 | 
				
			||||||
 | 
					        columns={[
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: <img src={tagIcon} alt="" />,
 | 
				
			||||||
 | 
					            dataIndex: "no",
 | 
				
			||||||
 | 
					            key: "no",
 | 
				
			||||||
 | 
					            width: "5%",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Username",
 | 
				
			||||||
 | 
					            dataIndex: "username",
 | 
				
			||||||
 | 
					            key: "username",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Tasks",
 | 
				
			||||||
 | 
					            dataIndex: "number_of_tasks",
 | 
				
			||||||
 | 
					            key: "number_of_tasks",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Points",
 | 
				
			||||||
 | 
					            dataIndex: "total_points",
 | 
				
			||||||
 | 
					            key: "total_points",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Salary Type",
 | 
				
			||||||
 | 
					            dataIndex: "salary_type",
 | 
				
			||||||
 | 
					            render: (value: any, record: any) => {
 | 
				
			||||||
 | 
					              if (record.salary_type === "task_based") {
 | 
				
			||||||
 | 
					                return <p>Task Based</p>;
 | 
				
			||||||
 | 
					              } else if (record.salary_type === "hybrid") {
 | 
				
			||||||
 | 
					                return <p>Hybrid</p>;
 | 
				
			||||||
 | 
					              } else {
 | 
				
			||||||
 | 
					                return <p>{record.salary_type}</p>; // Agar boshqa qiymat bo'lsa, oddiy qilib chiqariladi
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            filters: [
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                text: "Hybrid",
 | 
				
			||||||
 | 
					                value: "hybrid",
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                text: "Task Based",
 | 
				
			||||||
 | 
					                value: "task_based",
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            filterMultiple: false,
 | 
				
			||||||
 | 
					            // defaultFilteredValue: ["hybrid"],
 | 
				
			||||||
 | 
					            onFilter: (value: any, record: any) => {
 | 
				
			||||||
 | 
					              return record.salary_type === value;
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Base Salary",
 | 
				
			||||||
 | 
					            dataIndex: "salary_base_amount",
 | 
				
			||||||
 | 
					            render: (text: string, record: any) => (
 | 
				
			||||||
 | 
					              <p>${record?.salary_base_amount}</p>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Performance Salary",
 | 
				
			||||||
 | 
					            dataIndex: "performance_salary",
 | 
				
			||||||
 | 
					            render: (text: string, record: any) => (
 | 
				
			||||||
 | 
					              <p>${record?.performance_salary}</p>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Charges",
 | 
				
			||||||
 | 
					            dataIndex: "total_charges",
 | 
				
			||||||
 | 
					            render: (text: string, record: any) => (
 | 
				
			||||||
 | 
					              <p>${record?.total_charges}</p>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Bonuses",
 | 
				
			||||||
 | 
					            dataIndex: "total_bonuses",
 | 
				
			||||||
 | 
					            render: (text: string, record: any) => (
 | 
				
			||||||
 | 
					              <p>${record?.total_bonuses}</p>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: (
 | 
				
			||||||
 | 
					              <div>
 | 
				
			||||||
 | 
					                <span>Salary</span>  
 | 
				
			||||||
 | 
					                <Tooltip title="The calculation of salary begins at the start of the month and continues to the current day. Select a month to review salary details for prior periods.">
 | 
				
			||||||
 | 
					                  <QuestionCircleOutlined />
 | 
				
			||||||
 | 
					                </Tooltip>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            dataIndex: "salary",
 | 
				
			||||||
 | 
					            key: "salary",
 | 
				
			||||||
 | 
					            render: (text: string, record: any) => (
 | 
				
			||||||
 | 
					              <span>${record.salary}</span>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            // sorter: (a: any, b: any) => a.salary - b.total_points,
 | 
				
			||||||
 | 
					            // sortDirections: ["ascend", "descend"],
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        ]}
 | 
				
			||||||
 | 
					        rowClassName={(record, index) =>
 | 
				
			||||||
 | 
					          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,
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // onRow={(record) => ({
 | 
				
			||||||
 | 
					        //   onClick: () => {
 | 
				
			||||||
 | 
					        //     if (record.user && record.user.id) {
 | 
				
			||||||
 | 
					        //       navigate(`/accounting/${record.user.id}`); // `user.id`ni olish
 | 
				
			||||||
 | 
					        //     } else {
 | 
				
			||||||
 | 
					        //       console.error("User ID mavjud emas");
 | 
				
			||||||
 | 
					        //     }
 | 
				
			||||||
 | 
					        //   },
 | 
				
			||||||
 | 
					        // })}
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      {/* <Button disabled={data?.some((item) => item.is_confirmed)} type="primary">
 | 
				
			||||||
 | 
					        Confirm
 | 
				
			||||||
 | 
					      </Button> */}
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default AccountingCurrent;
 | 
				
			||||||
@ -0,0 +1,79 @@
 | 
				
			|||||||
 | 
					import React from "react";
 | 
				
			||||||
 | 
					import { Table, Tag, Tooltip } from "antd";
 | 
				
			||||||
 | 
					import { theme } from "antd";
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  QueryObserverResult,
 | 
				
			||||||
 | 
					  RefetchOptions,
 | 
				
			||||||
 | 
					  RefetchQueryFilters,
 | 
				
			||||||
 | 
					} from "react-query";
 | 
				
			||||||
 | 
					import { TStatCreators } from "../../types/Statistic/TStat";
 | 
				
			||||||
 | 
					import tagIcon from "../../assets/tagIcon.png";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const StatisticsSupportTable = ({
 | 
				
			||||||
 | 
					  data,
 | 
				
			||||||
 | 
					  isLoading,
 | 
				
			||||||
 | 
					  refetch,
 | 
				
			||||||
 | 
					}: {
 | 
				
			||||||
 | 
					  refetch: <TPageData>(
 | 
				
			||||||
 | 
					    options?: (RefetchOptions & RefetchQueryFilters<TPageData>) | undefined
 | 
				
			||||||
 | 
					  ) => Promise<QueryObserverResult<TStatCreators[], unknown>>;
 | 
				
			||||||
 | 
					  data: TStatCreators[] | undefined;
 | 
				
			||||||
 | 
					  isLoading: boolean;
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
 | 
					  const { token } = theme.useToken();
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div style={{ maxHeight: "400px" }}>
 | 
				
			||||||
 | 
					      <Table
 | 
				
			||||||
 | 
					        loading={isLoading}
 | 
				
			||||||
 | 
					        size="small"
 | 
				
			||||||
 | 
					        dataSource={data?.map((u, i) => ({
 | 
				
			||||||
 | 
					          no: i + 1,
 | 
				
			||||||
 | 
					          ...u,
 | 
				
			||||||
 | 
					        }))}
 | 
				
			||||||
 | 
					        columns={[
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: <img src={tagIcon} alt="" />,
 | 
				
			||||||
 | 
					            dataIndex: "no",
 | 
				
			||||||
 | 
					            key: "no",
 | 
				
			||||||
 | 
					            width: "5%",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Support specialist",
 | 
				
			||||||
 | 
					            dataIndex: "username",
 | 
				
			||||||
 | 
					            render: (text, record) => {
 | 
				
			||||||
 | 
					              return record.full_name.trim()
 | 
				
			||||||
 | 
					                ? record.full_name
 | 
				
			||||||
 | 
					                : record.username;
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: "Total tasks",
 | 
				
			||||||
 | 
					            dataIndex: "number_of_tasks",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        ]}
 | 
				
			||||||
 | 
					        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,
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					        rowClassName={(record, index) =>
 | 
				
			||||||
 | 
					          index % 2 === 0 ? "odd-row" : "even-row"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        bordered
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default StatisticsSupportTable;
 | 
				
			||||||
@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					import { useQuery } from "react-query";
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  AccountingController,
 | 
				
			||||||
 | 
					  TAccountingGetParams,
 | 
				
			||||||
 | 
					} from "../../API/LayoutApi/accounting";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const useAccountingData = ({ month }: TAccountingGetParams) => {
 | 
				
			||||||
 | 
					  return useQuery(
 | 
				
			||||||
 | 
					    [`stats/all-users/`, month],
 | 
				
			||||||
 | 
					    () =>
 | 
				
			||||||
 | 
					      AccountingController.read({
 | 
				
			||||||
 | 
					        month,
 | 
				
			||||||
 | 
					      }),
 | 
				
			||||||
 | 
					    { refetchOnWindowFocus: false }
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const useAccountingHistory = () => {
 | 
				
			||||||
 | 
					  return useQuery(
 | 
				
			||||||
 | 
					    [`employees-salaries-history/`],
 | 
				
			||||||
 | 
					    () => AccountingController.history(),
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      refetchOnWindowFocus: false,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 1.6 KiB  | 
| 
		 After Width: | Height: | Size: 1.8 KiB  | 
| 
		 After Width: | Height: | Size: 1.5 KiB  | 
@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					export type TAccounting = {
 | 
				
			||||||
 | 
					  full_name: string;
 | 
				
			||||||
 | 
					  is_confirmed: boolean;
 | 
				
			||||||
 | 
					  id: number;
 | 
				
			||||||
 | 
					  number_of_tasks: number;
 | 
				
			||||||
 | 
					  performance_based_amount: string;
 | 
				
			||||||
 | 
					  salary: string;
 | 
				
			||||||
 | 
					  salary_base_amount: string;
 | 
				
			||||||
 | 
					  salary_type: string;
 | 
				
			||||||
 | 
					  total_bonuses: string;
 | 
				
			||||||
 | 
					  total_charges: string;
 | 
				
			||||||
 | 
					  total_points: number;
 | 
				
			||||||
 | 
					  username: string;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type TAccountingHistory = {
 | 
				
			||||||
 | 
					  id: number;
 | 
				
			||||||
 | 
					  full_name: string;
 | 
				
			||||||
 | 
					  username: string;
 | 
				
			||||||
 | 
					  total_number_of_tasks: number;
 | 
				
			||||||
 | 
					  salary_type: string;
 | 
				
			||||||
 | 
					  total_bonuses: string;
 | 
				
			||||||
 | 
					  total_charges: string;
 | 
				
			||||||
 | 
					  total_earned_points: string;
 | 
				
			||||||
 | 
					  total_base_salary: string;
 | 
				
			||||||
 | 
					  total_performance_salary: string;
 | 
				
			||||||
 | 
					  total_earned_salary: string;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
					Loading…
					
					
				
		Reference in new issue