diff --git a/src/API/LayoutApi/statistic.ts b/src/API/LayoutApi/statistic.ts index 76071fd..277e52a 100644 --- a/src/API/LayoutApi/statistic.ts +++ b/src/API/LayoutApi/statistic.ts @@ -6,6 +6,7 @@ export type TStatGetParams = { team?: string; start_date?: string; end_date?: string; + for_salary?: boolean; }; export type TStatTeamGetParams = { diff --git a/src/API/api.ts b/src/API/api.ts index 7fc24f1..104c181 100644 --- a/src/API/api.ts +++ b/src/API/api.ts @@ -5,6 +5,7 @@ import axios from "axios"; // }); const instance = axios.create({ baseURL: "https://api.tteld.co/api/v1/", + // baseURL: "http://10.10.10.64:8000/api/v1/", }); const token: string | null = localStorage.getItem("access"); diff --git a/src/App.tsx b/src/App.tsx index 2f629ef..ab3194b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -278,6 +278,7 @@ const App: React.FC = () => { // taskSocket = new WebSocket(`wss://api.tteld.co/global/?user_id=${admin_id}`); taskSocket = new WebSocket( `wss://ontime-socket.tteld.co/global/?user_id=${admin_id}` + // `ws://10.10.10.64:8000/global/?user_id=${admin_id}` ); taskSocket.addEventListener("open", (event) => { @@ -481,7 +482,7 @@ const App: React.FC = () => { > - +
e.preventDefault()} diff --git a/src/Components/Statistics/Statistic.tsx b/src/Components/Statistics/Statistic.tsx index e8ecced..e6e4e35 100644 --- a/src/Components/Statistics/Statistic.tsx +++ b/src/Components/Statistics/Statistic.tsx @@ -22,6 +22,16 @@ import { import TabPane from "antd/es/tabs/TabPane"; // @ts-ignore import IconSearch from "../../assets/searchIcon.png"; +import { + CartesianGrid, + Legend, + Line, + LineChart, + ResponsiveContainer, + Tooltip, + XAxis, + YAxis, +} from "recharts"; const Stat = () => { const now = dayjs(); @@ -37,6 +47,8 @@ const Stat = () => { const [startDate, setStartDate] = useState(start_date); const [endDate, setEndDate] = useState(end_date); + const [forSalary, setForSalary] = useState(true); + const teamData = useTeamData({}); const teamOptions: { label: string; value: any }[] | undefined = teamData?.data?.map((item) => ({ @@ -84,14 +96,21 @@ const Stat = () => { setStartDate(`${yearStart}-${monthStart}-01 00:00:00`); setEndDate(`${yearEnd}-${monthEnd}-01 00:00:00`); + setForSalary(true); } }; + const clearDatePcker = () => { + setStartDate(""); + setEndDate(""); + }; + const { data, refetch, isLoading } = useStatsData({ search: search, team: team, start_date: startDate, end_date: endDate, + for_salary: forSalary, }); interface DataType { data?: TStatTeam[]; @@ -118,6 +137,83 @@ const Stat = () => { }, 1000); }; const theme = localStorage.getItem("theme") === "true" ? true : false; + + // const chartData = [ + // { + // date: "2024-12-01", + // ABM: { points: 4500, count: 20 }, + // ZNX: { points: 2500, count: 18 }, + // TYP: { points: 3900, count: 24 }, + // LMO: { points: 3100, count: 16 }, + // QWE: { points: 2800, count: 21 }, + // RST: { points: 4400, count: 19 }, + // UVX: { points: 3950, count: 22 }, + // WYZ: { points: 4100, count: 20 }, + // ERT: { points: 3700, count: 17 }, + // KLM: { points: 4200, count: 25 }, + // LBS: { points: 1200, count: 25 }, + // }, + // { + // date: "2024-12-02", + // ABM: { points: 4600, count: 21 }, + // ZNX: { points: 2400, count: 17 }, + // TYP: { points: 3850, count: 23 }, + // LMO: { points: 3200, count: 15 }, + // QWE: { points: 2750, count: 20 }, + // RST: { points: 4450, count: 18 }, + // UVX: { points: 4000, count: 23 }, + // WYZ: { points: 4200, count: 19 }, + // ERT: { points: 3750, count: 16 }, + // KLM: { points: 4250, count: 24 }, + // LBS: { points: 1250, count: 26 }, + // }, + // { + // date: "2024-12-03", + // ABM: { points: 4550, count: 19 }, + // ZNX: { points: 2550, count: 19 }, + // TYP: { points: 3950, count: 25 }, + // LMO: { points: 3150, count: 17 }, + // QWE: { points: 2850, count: 22 }, + // RST: { points: 4500, count: 20 }, + // UVX: { points: 3900, count: 21 }, + // WYZ: { points: 4300, count: 21 }, + // ERT: { points: 3800, count: 18 }, + // KLM: { points: 4300, count: 26 }, + // LBS: { points: 1300, count: 27 }, + // }, + // ]; + + // const lines = [ + // { key: "ABM.points", color: "#FF5733" }, // orange-red + // { key: "ZNX.points", color: "#00b822" }, // lime-green + // { key: "TYP.points", color: "#5733FF" }, // blue-purple + // { key: "LMO.points", color: "#FFC300" }, // gold + // { key: "QWE.points", color: "#009790" }, // turquoise + // { key: "RST.points", color: "#FF33A1" }, // hot pink + // { key: "UVX.points", color: "#8D33FF" }, // violet + // { key: "WYZ.points", color: "#FF8D33" }, // orange + // { key: "ERT.points", color: "#33A1FF" }, // sky blue + // { key: "KLM.points", color: "#4a8a01" }, // light green + // ]; + + // console.log(chartData, ); + + // const predefinedColors = ["#FF5733", "#00b822"]; + + // function updateLines(chartData: any, predefinedColors: any) { + // const keys = Object.keys(chartData[0]).filter((key) => key !== "date"); + + // const newLines = keys.map((key, index) => { + // const color = predefinedColors[index % predefinedColors.length]; // Ranglarni aylantirib foydalanadi + // return { key: `${key}.points`, color, name: `${key}` }; + // }); + + // return newLines; + // } + + // lines massivini yangilash + // const lines = updateLines(chartData, predefinedColors); + return (
{ + + {/* + + + + + + + + {lines.map((line, index) => ( + + ))} + + */}
diff --git a/src/Components/Statistics/StatisticTable.tsx b/src/Components/Statistics/StatisticTable.tsx index 06f469f..873e2ae 100644 --- a/src/Components/Statistics/StatisticTable.tsx +++ b/src/Components/Statistics/StatisticTable.tsx @@ -1,4 +1,4 @@ -import { Table } from "antd"; +import { Table, Tooltip } from "antd"; import { TStat } from "../../types/Statistic/TStat"; import { QueryObserverResult, @@ -49,11 +49,43 @@ const StatTable = ({ dataIndex: "team_name", key: "team_name ", }, + { + title: "Tasks", + dataIndex: "number_of_tasks", + key: "number_of_tasks", + }, { title: "Points", dataIndex: "total_points", key: "total_points", }, + { + title: "Salary", + dataIndex: "salary", + key: "salary", + render: (text: string, record: any) => ( + + {record.salary_type === "Hybrid" ? ( +

+ Base Amount:{" "} + ${record.salary_base_amount} +

+ ) : ( + "" + )} +

+ Performance based amount:{" "} + ${record.salary - record.salary_base_amount} +

+
+ } + > + ${record.salary} + + ), + }, ]} pagination={{ pageSize: 10, diff --git a/src/Components/Statistics/StatisticTeamTable.tsx b/src/Components/Statistics/StatisticTeamTable.tsx index 236369d..8c4c002 100644 --- a/src/Components/Statistics/StatisticTeamTable.tsx +++ b/src/Components/Statistics/StatisticTeamTable.tsx @@ -5,6 +5,8 @@ import { RefetchOptions, RefetchQueryFilters, } from "react-query"; + +import { theme } from "antd"; // @ts-ignore import tagIcon from "../../assets/tagIcon.png"; const StatTeamTable = ({ @@ -18,6 +20,7 @@ const StatTeamTable = ({ data: TStatTeam[] | undefined; isLoading: boolean; }) => { + const { token } = theme.useToken(); return (
index % 2 === 0 ? "odd-row" : "even-row" diff --git a/src/Components/Users/UserEdit.tsx b/src/Components/Users/UserEdit.tsx index 155e7dd..0237e8a 100644 --- a/src/Components/Users/UserEdit.tsx +++ b/src/Components/Users/UserEdit.tsx @@ -21,7 +21,9 @@ import Notfound from "../../Utils/Notfound"; import { useTeamData } from "../../Hooks/Teams"; import { useRoleData } from "../../Hooks/Role"; import { role } from "../../App"; -import { useState } from "react"; +import { useEffect, useState } from "react"; +import { DollarOutlined } from "@ant-design/icons"; + const TabPane = Tabs.TabPane; type params = { readonly id: string; @@ -29,13 +31,20 @@ type params = { const UserEdit = () => { const { id } = useParams(); + const { Option } = Select; const { data, refetch, status } = useUserOne(id); + const initialUsername = data?.username; const roleData = useRoleData(); + const techSupport = roleData.data?.find( (item) => item.name === "Tech Support" ); + const onSubmit = async (value: any) => { + if (initialUsername === value.username) { + value.username = undefined; + } if (value.role_id === techSupport?.id) { value.team_id = null; @@ -44,6 +53,11 @@ const UserEdit = () => { id && (await userController.userPatch(value, id)); } + if (!value.salary_type) { + console.error("Salary type tanlanmagan!"); + return; + } + refetch(); document.location.replace("/#/users/"); }; @@ -69,6 +83,20 @@ const UserEdit = () => { } }; const [activeTab, setActiveTab] = useState("1"); + + const [showInput, setShowInput] = useState(false); + + const handleChange = (value: string) => { + // Agar Hybrid bo'lsa, inputni ko'rsatish; Task based bo'lsa, yashirish + setShowInput(value === "hybrid"); + }; + + useEffect(() => { + if (data?.salary_type === "hybrid") { + setShowInput(true); + } + }, [data]); + return (
@@ -169,6 +197,34 @@ const UserEdit = () => { )} + + {data.role.name === "Checker" && ( +
+ + + + + )} + + {showInput && ( + + } /> + + )} {role !== "Checker" && ( diff --git a/src/Hooks/Stats/index.ts b/src/Hooks/Stats/index.ts index 65e09b2..d91d274 100644 --- a/src/Hooks/Stats/index.ts +++ b/src/Hooks/Stats/index.ts @@ -1,43 +1,52 @@ import { useQuery } from "react-query"; import { TStatGetParams, statController } from "../../API/LayoutApi/statistic"; -export const useStatsData = ({search, team, start_date, end_date}: TStatGetParams) => { - return useQuery( - [`stats/all-users/`, search, team, start_date, end_date], - () => statController.read({search, team, start_date, end_date}), - { refetchOnWindowFocus: false } - ); +export const useStatsData = ({ + search, + team, + start_date, + end_date, + for_salary, +}: TStatGetParams) => { + return useQuery( + [`stats/all-users/`, search, team, start_date, end_date, for_salary], + () => + statController.read({ search, team, start_date, end_date, for_salary }), + { refetchOnWindowFocus: false } + ); }; -export const useStatTeamData = ({search, start_date, end_date}: TStatGetParams) => { - return useQuery( - [`stats/all-teams/`, search, start_date, end_date], - () => statController.team({search, start_date, end_date}), - { refetchOnWindowFocus: false } - ); +export const useStatTeamData = ({ + search, + start_date, + end_date, +}: TStatGetParams) => { + return useQuery( + [`stats/all-teams/`, search, start_date, end_date], + () => statController.team({ search, start_date, end_date }), + { refetchOnWindowFocus: false } + ); }; -export const useCreatorsData = ({ start_date, end_date}: TStatGetParams) => { - return useQuery( - [`stats/task-creators/`, start_date, end_date], - () => statController.creators({ start_date, end_date}), - { refetchOnWindowFocus: false } - ); +export const useCreatorsData = ({ start_date, end_date }: TStatGetParams) => { + return useQuery( + [`stats/task-creators/`, start_date, end_date], + () => statController.creators({ start_date, end_date }), + { refetchOnWindowFocus: false } + ); }; -export const useCardData = ({ start_date, end_date}: TStatGetParams) => { - return useQuery( - [`stats/tasks-comparison/`, start_date, end_date], - () => statController.cards({ start_date, end_date}), - { refetchOnWindowFocus: false } - ); +export const useCardData = ({ start_date, end_date }: TStatGetParams) => { + return useQuery( + [`stats/tasks-comparison/`, start_date, end_date], + () => statController.cards({ start_date, end_date }), + { refetchOnWindowFocus: false } + ); }; -export const useStatOne = ( - statId: number | string | undefined -): any => { - return useQuery( - [`stat/${statId || "all"}`, statId], - () => statController.statOne(statId), - { refetchOnWindowFocus: false } - ); +export const useStatOne = (statId: number | string | undefined): any => { + return useQuery( + [`stat/${statId || "all"}`, statId], + () => statController.statOne(statId), + { refetchOnWindowFocus: false } + ); }; diff --git a/src/types/Statistic/TStat.ts b/src/types/Statistic/TStat.ts index c3aa5e6..de65e1d 100644 --- a/src/types/Statistic/TStat.ts +++ b/src/types/Statistic/TStat.ts @@ -1,21 +1,22 @@ export type TStat = { - id: number; - full_name: string; - username: string; - team_id: number | null; - total_points: number; -} + id: number; + full_name: string; + username: string; + team_id: number | null; + total_points: number; + for_salary: boolean; +}; export type TStatTeam = { - id: number; - name: string; - is_active: boolean; - total_points: number; -} + id: number; + name: string; + is_active: boolean; + total_points: number; +}; -export type TCard = { - all_tasks: number; - active_tasks: number; - active_tasks_percentage: number; - inactive_tasks: number; - inactive_tasks_percentage: number; -} \ No newline at end of file +export type TCard = { + all_tasks: number; + active_tasks: number; + active_tasks_percentage: number; + inactive_tasks: number; + inactive_tasks_percentage: number; +}; diff --git a/src/types/User/TUser.ts b/src/types/User/TUser.ts index 4fc8883..e945509 100644 --- a/src/types/User/TUser.ts +++ b/src/types/User/TUser.ts @@ -7,4 +7,6 @@ export type TUser = { last_name: string | ''; is_active: boolean; is_superuser: boolean; + salary_type: string; + salary_base_amount: number; } \ No newline at end of file