genral page owner statistics

dilmurod
Dilmurod 1 week ago
parent f7f12035b9
commit 8b53f23835

@ -89,8 +89,7 @@ const Profile = () => {
tasks: stat.number_of_tasks,
}));
const firstDayOfMonth = dayjs().startOf("month"); // Oyning birinchi kuni
// const lastDayOfMonth = dayjs().endOf("month");
const firstDayOfMonth = dayjs().startOf("month");
const today = dayjs();
const dateFormat = "YYYY-MM-DD";

@ -1,4 +1,4 @@
import { useRef, useState } from "react";
import { useEffect, useRef, useState } from "react";
import {
QueryObserverResult,
RefetchOptions,
@ -23,6 +23,8 @@ import TabPane from "antd/es/tabs/TabPane";
// @ts-ignore
import IconSearch from "../../assets/searchIcon.png";
import {
Bar,
BarChart,
CartesianGrid,
Legend,
Line,
@ -33,6 +35,15 @@ import {
YAxis,
} from "recharts";
import generalActive from "../../assets/generalActive.svg";
import general from "../../assets/general.svg";
import checkersIcon from "../../assets/checkerIcon.svg";
import chekersIconActive from "../../assets/checkersIconActive.svg";
import teamsIcon from "../../assets/teamsIcon.svg";
import teamsIconActive from "../../assets/teamsIconActive.svg";
import axios from "axios";
const Stat = () => {
const now = dayjs();
const { RangePicker } = DatePicker;
@ -40,7 +51,10 @@ const Stat = () => {
const currentDate = moment();
const nextMonth = currentDate.clone().add(1, "months");
const start_date = `${currentDate.format("YYYY-MM")}-01 00:00:00`;
const end_date = `${nextMonth.format("YYYY-MM")}-01 00:00:00`;
const end_date = `${currentDate
.clone()
.endOf("month")
.format("YYYY-MM-DD")} 23:59:59`;
const [search, setSearch] = useState<string>("");
const [team, setTeam] = useState<any>("");
@ -87,8 +101,8 @@ const Stat = () => {
setStartDate("");
setEndDate("");
} else {
const firstDate = date;
const secondDate = date?.add(1, "month");
const firstDate = date.startOf("month");
const secondDate = date?.add(1, "month").startOf("month");
// const yearStart = Number(firstDate?.year());
// const monthStart = Number(firstDate?.month()) + 1;
// const yearEnd = Number(secondDate?.year());
@ -97,8 +111,10 @@ const Stat = () => {
// setStartDate(`${yearStart}-${monthStart}-01 00:00:00`);
// setEndDate(`${yearEnd}-${monthEnd}-01 00:00:00`);
const formattedStartDate = firstDate.format("YYYY-MM-DD");
const formattedEndDate = secondDate.format("YYYY-MM-DD");
const formattedStartDate = firstDate.format("YYYY-MM-01 00:00:00");
const formattedEndDate = secondDate
.subtract(1, "day")
.format("YYYY-MM-DD 23:59:59");
setStartDate(formattedStartDate);
setEndDate(formattedEndDate);
setForSalary(true);
@ -138,6 +154,8 @@ const Stat = () => {
};
const theme = localStorage.getItem("theme") === "true" ? true : false;
const [activeTab, setActiveTab] = useState("1");
const disabledDate = (current: any) => {
return current && current >= moment().add(1, "month").startOf("month");
};
@ -218,6 +236,59 @@ const Stat = () => {
// lines massivini yangilash
// const lines = updateLines(chartData, predefinedColors);
const [chartData, setChartData] = useState([]);
const [summaryData, setSummaryData] = useState<Record<string, any> | null>(
null
);
const token = localStorage.getItem("access");
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
try {
const today = dayjs().endOf("day");
let finalEndDate = dayjs(endDate);
if (finalEndDate.isAfter(today)) {
finalEndDate = today;
}
const formattedEndDate = finalEndDate.format("YYYY-MM-DD HH:mm:ss");
const response = await axios.get(
"https://api.tteld.co/api/v1/stats/general-stats",
{
params: { start_date: startDate, end_date: formattedEndDate },
headers: { Authorization: `Bearer ${token}` },
}
);
if (response.data.daily_stats) {
setChartData(response.data.daily_stats);
}
if (response.data.summary) {
setSummaryData(response.data.summary);
}
setLoading(false);
} catch (error) {
console.error("Error fetching daily stats:", error);
setLoading(false);
}
};
fetchData();
}, [token, startDate, endDate]);
if (loading) return <p>Loading...</p>;
const formatDate = (dateString: string): string => {
const date = new Date(dateString);
return new Intl.DateTimeFormat("en-EN", {
day: "2-digit",
month: "short",
}).format(date);
};
return (
<div>
<div
@ -239,8 +310,145 @@ const Stat = () => {
<RangePicker style={{ width: 260 }} onCalendarChange={datePick} />
</div>
</div>
<Tabs defaultActiveKey="1">
<TabPane tab={<span>Users</span>} key="1">
<Tabs
defaultActiveKey="1"
activeKey={activeTab}
onChange={(key) => setActiveTab(key)}
>
<TabPane
tab={
<span style={{ display: "flex", alignItems: "center" }}>
<img
style={{ marginRight: 5 }}
src={activeTab === "1" ? generalActive : general}
alt="icon"
/>
General
</span>
}
key="1"
>
<div
style={{
display: "flex",
alignItems: "center",
gap: 20,
marginTop: 40,
}}
>
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-around",
flexDirection: "column",
gap: 20,
flexWrap: "wrap",
}}
>
{summaryData && (
<div
className="card_stat"
style={{
backgroundColor: "#F99E2C",
}}
>
<p>Total</p>
<span>{summaryData.total}</span>
<p>Tasks</p>
</div>
)}
{summaryData && (
<div
className="card_stat"
style={{
backgroundColor: "#27AE60",
}}
>
<p>Active</p>
<span>{summaryData.total_completed}</span>
<p>Tasks</p>
</div>
)}
{summaryData && (
<div
className="card_stat"
style={{
backgroundColor: "#F64747",
}}
>
<p>Inactive</p>
<span>{summaryData.total_incomplete}</span>
<p>Tasks</p>
</div>
)}
</div>
<ResponsiveContainer
width="100%"
height={517}
style={{ textTransform: "capitalize" }}
>
<LineChart
data={chartData}
// margin={{
// top: 5,
// right: 30,
// left: 20,
// bottom: 5,
// }}
>
<CartesianGrid vertical={false} stroke="#D7D8E080" />
<XAxis
dataKey="task_date"
style={{
color: "#9B9DAA",
fontSize: 10,
lineHeight: "12.4px",
fontWeight: 400,
}}
tickFormatter={formatDate}
/>
<YAxis
style={{
color: "#9B9DAA",
fontSize: 10,
fontWeight: 400,
}}
/>
<Tooltip />
<Legend />
<Line
dataKey="total_tasks"
stroke="#F99E2C"
name="Total Tasks"
/>
<Line
dataKey="completed_tasks"
stroke="#27AE60"
name="Active tasks"
/>
<Line
dataKey="incomplete_tasks"
stroke="#F64747"
name="Inactive Tasks"
/>
</LineChart>
</ResponsiveContainer>
</div>
</TabPane>
<TabPane
tab={
<span style={{ display: "flex", alignItems: "center" }}>
<img
style={{ marginRight: 5 }}
src={activeTab === "2" ? chekersIconActive : checkersIcon}
alt="icon"
/>
Checkers
</span>
}
key="2"
>
<span
style={{
display: "flex",
@ -277,13 +485,29 @@ const Stat = () => {
Save as file
</Button>
</TabPane>
<TabPane tab={<span>Teams</span>} key="2">
<TabPane
tab={
<span style={{ display: "flex", alignItems: "center" }}>
<img
style={{ marginRight: 5 }}
src={activeTab === "3" ? teamsIconActive : teamsIcon}
alt="icon"
/>
Teams
</span>
}
key="3"
>
<StatTeamTable
data={TeamData?.data}
isLoading={TeamData?.isLoading}
refetch={TeamData?.refetch}
/>
<Button type="primary" onClick={(e) => handleSave("")}>
<Button
type="primary"
onClick={(e) => handleSave("")}
style={{ marginTop: 10 }}
>
Save as file
</Button>

@ -77,7 +77,7 @@ const StatTable = ({
<div>
{record.salary_type === "hybrid" ? (
<p>
<strong>Base Amount:</strong> $
<strong>Fixed Amount:</strong> $
{record.salary_base_amount}
</p>
) : (
@ -89,6 +89,9 @@ const StatTable = ({
</p>
</div>
}
overlayStyle={{
maxWidth: "700px",
}}
>
<span>${record.salary}</span>
</Tooltip>

@ -92,6 +92,8 @@ const UserEdit = () => {
}
};
const [form] = Form.useForm();
useEffect(() => {
if (data?.role.name === "Checker" && data?.salary_type === "hybrid") {
setShowInput(true);
@ -136,6 +138,7 @@ const UserEdit = () => {
style={{ display: "flex" }}
>
<Form
form={form}
name="basic"
layout="vertical"
wrapperCol={{ span: 16 }}
@ -201,7 +204,8 @@ const UserEdit = () => {
</Col>
)}
{data?.role?.name === "Checker" && (
{data?.role?.name === "Checker" &&
form.getFieldsValue().role_id !== 3 && (
<Col span={4}>
<Form.Item
wrapperCol={{ span: "100%" }}
@ -218,11 +222,10 @@ const UserEdit = () => {
</Form.Item>
</Col>
)}
{showInput && (
<Form.Item
wrapperCol={{ span: "100%" }}
label="Base amount"
label="Fixed Amount"
name="salary_base_amount"
>
<Input prefix={<DollarOutlined />} />

@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.7917 2.5C16.2874 2.5 17.5 3.71256 17.5 5.20833V14.7917C17.5 16.2874 16.2874 17.5 14.7917 17.5H5.20833C3.71256 17.5 2.5 16.2874 2.5 14.7917V5.20833C2.5 3.71256 3.71256 2.5 5.20833 2.5H14.7917ZM16.25 7.08333H3.75V14.7917C3.75 15.5971 4.40292 16.25 5.20833 16.25H14.7917C15.5971 16.25 16.25 15.5971 16.25 14.7917V7.08333ZM6.45833 12.0833C7.03363 12.0833 7.5 12.5497 7.5 13.125C7.5 13.7003 7.03363 14.1667 6.45833 14.1667C5.88304 14.1667 5.41667 13.7003 5.41667 13.125C5.41667 12.5497 5.88304 12.0833 6.45833 12.0833ZM10 12.0833C10.5753 12.0833 11.0417 12.5497 11.0417 13.125C11.0417 13.7003 10.5753 14.1667 10 14.1667C9.4247 14.1667 8.95833 13.7003 8.95833 13.125C8.95833 12.5497 9.4247 12.0833 10 12.0833ZM6.45833 8.75C7.03363 8.75 7.5 9.21637 7.5 9.79167C7.5 10.367 7.03363 10.8333 6.45833 10.8333C5.88304 10.8333 5.41667 10.367 5.41667 9.79167C5.41667 9.21637 5.88304 8.75 6.45833 8.75ZM10 8.75C10.5753 8.75 11.0417 9.21637 11.0417 9.79167C11.0417 10.367 10.5753 10.8333 10 10.8333C9.4247 10.8333 8.95833 10.367 8.95833 9.79167C8.95833 9.21637 9.4247 8.75 10 8.75ZM13.5417 8.75C14.117 8.75 14.5833 9.21637 14.5833 9.79167C14.5833 10.367 14.117 10.8333 13.5417 10.8333C12.9664 10.8333 12.5 10.367 12.5 9.79167C12.5 9.21637 12.9664 8.75 13.5417 8.75ZM14.7917 3.75H5.20833C4.40292 3.75 3.75 4.40292 3.75 5.20833V5.83333H16.25V5.20833C16.25 4.40292 15.5971 3.75 14.7917 3.75Z" fill="#A1A2AB"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.5 7.08333V14.7917C17.5 16.2874 16.2874 17.5 14.7917 17.5H5.20833C3.71256 17.5 2.5 16.2874 2.5 14.7917V7.08333H17.5ZM6.04167 12.5C5.46637 12.5 5 12.9664 5 13.5417C5 14.117 5.46637 14.5833 6.04167 14.5833C6.61696 14.5833 7.08333 14.117 7.08333 13.5417C7.08333 12.9664 6.61696 12.5 6.04167 12.5ZM10 12.5C9.4247 12.5 8.95833 12.9664 8.95833 13.5417C8.95833 14.117 9.4247 14.5833 10 14.5833C10.5753 14.5833 11.0417 14.117 11.0417 13.5417C11.0417 12.9664 10.5753 12.5 10 12.5ZM6.04167 8.75C5.46637 8.75 5 9.21637 5 9.79167C5 10.367 5.46637 10.8333 6.04167 10.8333C6.61696 10.8333 7.08333 10.367 7.08333 9.79167C7.08333 9.21637 6.61696 8.75 6.04167 8.75ZM10 8.75C9.4247 8.75 8.95833 9.21637 8.95833 9.79167C8.95833 10.367 9.4247 10.8333 10 10.8333C10.5753 10.8333 11.0417 10.367 11.0417 9.79167C11.0417 9.21637 10.5753 8.75 10 8.75ZM13.9583 8.75C13.383 8.75 12.9167 9.21637 12.9167 9.79167C12.9167 10.367 13.383 10.8333 13.9583 10.8333C14.5336 10.8333 15 10.367 15 9.79167C15 9.21637 14.5336 8.75 13.9583 8.75ZM14.7917 2.5C16.2874 2.5 17.5 3.71256 17.5 5.20833V5.83333H2.5V5.20833C2.5 3.71256 3.71256 2.5 5.20833 2.5H14.7917Z" fill="#F99E2C"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.5 5.20833C2.5 3.71256 3.71256 2.5 5.20833 2.5H14.7917C16.2874 2.5 17.5 3.71256 17.5 5.20833V14.7917C17.5 16.2874 16.2874 17.5 14.7917 17.5H5.20833C3.71256 17.5 2.5 16.2874 2.5 14.7917V5.20833ZM5.20833 3.75C4.40292 3.75 3.75 4.40292 3.75 5.20833V14.7917C3.75 15.5971 4.40292 16.25 5.20833 16.25H7.5V3.75H5.20833ZM8.75 3.75V11.6667H16.25V5.20833C16.25 4.40292 15.5971 3.75 14.7917 3.75H8.75ZM16.25 12.9167H8.75V16.25H14.7917C15.5971 16.25 16.25 15.5971 16.25 14.7917V12.9167Z" fill="#A1A2AB"/>
</svg>

After

Width:  |  Height:  |  Size: 647 B

@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.5 5.20833C2.5 3.71256 3.71256 2.5 5.20833 2.5H7.5V17.5H5.20833C3.71256 17.5 2.5 16.2874 2.5 14.7917V5.20833Z" fill="#F99E2C"/>
<path d="M8.75 17.5H14.7917C16.2874 17.5 17.5 16.2874 17.5 14.7917V12.9167H8.75V17.5Z" fill="#F99E2C"/>
<path d="M17.5 11.6667V5.20833C17.5 3.71256 16.2874 2.5 14.7917 2.5H8.75V11.6667H17.5Z" fill="#F99E2C"/>
</svg>

After

Width:  |  Height:  |  Size: 451 B

@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.33366 11.6658L10.8337 11.6667C11.7118 11.6667 12.4321 12.3462 12.4958 13.2089L12.5003 13.3333V14.5833C12.4995 17.5 9.40366 18.3333 7.08366 18.3333C4.81521 18.3333 1.80424 17.5366 1.67154 14.7747L1.66699 14.5833V13.3325C1.66699 12.4543 2.34732 11.7341 3.20933 11.6704L3.33366 11.6658ZM12.6837 11.6667H16.667C17.5452 11.6667 18.2654 12.347 18.3291 13.209L18.3337 13.3333V14.1667C18.3328 16.7183 15.952 17.5 14.167 17.5C13.6003 17.5 12.9745 17.42 12.3837 17.2317C12.6637 16.91 12.8895 16.5425 13.052 16.1258C13.5045 16.23 13.9295 16.25 14.167 16.25L14.3891 16.245C15.2102 16.2091 16.961 15.9422 17.0775 14.3375L17.0837 14.1667V13.3333C17.0837 13.1289 16.9355 12.9587 16.7416 12.9234L16.667 12.9167H13.2912C13.2212 12.4989 13.0465 12.1193 12.7957 11.7998L12.6837 11.6667H16.667H12.6837ZM3.33366 12.9158L3.24978 12.9242C3.14613 12.9452 3.07533 13.0015 3.03866 13.0375C3.00266 13.0742 2.94639 13.1444 2.92533 13.2483L2.91699 13.3325V14.5833C2.91699 15.4242 3.29199 16.0183 4.09783 16.4517C4.78629 16.8224 5.76658 17.0469 6.81914 17.0793L7.08366 17.0833L7.34816 17.0793C8.40062 17.0469 9.38026 16.8224 10.0695 16.4517C10.8242 16.0454 11.2017 15.4978 11.2459 14.7374L11.2503 14.5825V13.3333C11.2503 13.1289 11.1022 12.9587 10.9083 12.9234L10.8337 12.9167L3.33366 12.9158ZM7.08366 2.5C9.15449 2.5 10.8337 4.17917 10.8337 6.25C10.8337 8.32083 9.15449 10 7.08366 10C5.01283 10 3.33366 8.32083 3.33366 6.25C3.33366 4.17917 5.01283 2.5 7.08366 2.5ZM14.5837 4.16667C16.1945 4.16667 17.5003 5.4725 17.5003 7.08333C17.5003 8.69417 16.1945 10 14.5837 10C12.9728 10 11.667 8.69417 11.667 7.08333C11.667 5.4725 12.9728 4.16667 14.5837 4.16667ZM7.08366 3.75C5.70533 3.75 4.58366 4.87167 4.58366 6.25C4.58366 7.62833 5.70533 8.75 7.08366 8.75C8.46199 8.75 9.58366 7.62833 9.58366 6.25C9.58366 4.87167 8.46199 3.75 7.08366 3.75ZM14.5837 5.41667C13.6645 5.41667 12.917 6.16417 12.917 7.08333C12.917 8.0025 13.6645 8.75 14.5837 8.75C15.5028 8.75 16.2503 8.0025 16.2503 7.08333C16.2503 6.16417 15.5028 5.41667 14.5837 5.41667Z" fill="#A1A2AB"/>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.91699 11.6667L11.2503 11.6675C11.8997 11.6675 12.434 12.1636 12.4946 12.7972L12.5003 12.9175V14.5833C12.4995 17.5 9.40366 18.3333 7.08366 18.3333C4.81521 18.3333 1.80424 17.5366 1.67154 14.7747L1.66699 14.5833V12.9167C1.66699 12.2673 2.16305 11.733 2.79666 11.6724L2.91699 11.6667ZM12.907 11.6667H17.0837C17.7331 11.6667 18.2673 12.162 18.3279 12.7962L18.3337 12.9167V14.1667C18.3328 16.7183 15.952 17.5 14.167 17.5C13.6003 17.5 12.9745 17.42 12.3837 17.2317C12.9276 16.6064 13.2805 15.8123 13.3281 14.8167L13.3337 14.5833V12.9167C13.3337 12.5047 13.2092 12.124 13.0012 11.8013L12.907 11.6667ZM7.08366 2.5C9.15449 2.5 10.8337 4.17917 10.8337 6.25C10.8337 8.32083 9.15449 10 7.08366 10C5.01283 10 3.33366 8.32083 3.33366 6.25C3.33366 4.17917 5.01283 2.5 7.08366 2.5ZM14.5837 4.16667C16.1945 4.16667 17.5003 5.4725 17.5003 7.08333C17.5003 8.69417 16.1945 10 14.5837 10C12.9728 10 11.667 8.69417 11.667 7.08333C11.667 5.4725 12.9728 4.16667 14.5837 4.16667Z" fill="#F99E2C"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Loading…
Cancel
Save