first commit

This commit is contained in:
2026-05-23 13:22:10 +03:30
parent 5f9ee72174
commit 6591a52f27
52 changed files with 3937 additions and 133 deletions

View File

@@ -0,0 +1,621 @@
"use client";
import { requestType, ticketStatuses } from "@/core/constant";
import {
exportToExcel,
formatDurationPersian,
handleAxiosError,
} from "@/core/utils";
import {
useMutateAgentEfficiency,
useMutateAgentPerformance,
useMutateAgingReport,
useMutateAvgResolutionTime,
useMutateClosureRate,
useMutateCriticalTickets,
useMutateDepartmentLoad,
useMutateDepartmentReport,
useMutateKpiReport,
useMutatePredictionReport,
useMutateSlaBreach,
useMutateStatsReport,
} from "@/services/hooks/report.hook";
import { DownloadOutlined } from "@mui/icons-material";
import {
Box,
Button,
Card,
CardContent,
Stack,
Typography,
} from "@mui/material";
import { UseMutateAsyncFunction } from "@tanstack/react-query";
import { toast } from "react-toastify";
export default function Page() {
// ۱. آمار کلی تیکت‌ها
const { mutateAsync: totalStatsAsync } = useMutateStatsReport();
// ۲. گزارش عملکرد دپارتمان‌ها
const { mutateAsync: deptReportAsync } = useMutateDepartmentReport();
// ۳. گزارش عملکرد کارشناسان
const { mutateAsync: agentPerfAsync } = useMutateAgentPerformance();
// ۴. میانگین زمان پاسخ‌گویی
const { mutateAsync: avgResTimeAsync } = useMutateAvgResolutionTime();
// ۵. تیکت‌های بحرانی
const { mutateAsync: criticalTicketsAsync } = useMutateCriticalTickets();
// ۶. روند ثبت تیکت‌ها (نیاز به params دارد)
// const { mutateAsync: ticketsTrend, isLoading: trendLoading } = useMutateTicketsTrend(dateParams);
// ۷. نرخ بستن تیکت‌ها
const { mutateAsync: closureRateAsync } = useMutateClosureRate();
// ۸. تیکت‌های خارج از SLA
const { mutateAsync: slaBreachAsync } = useMutateSlaBreach();
// ۹. گزارش قدمت تیکت‌ها
const { mutateAsync: agingReportAsync } = useMutateAgingReport();
// ۱۰. بهره‌وری کارشناسان
const { mutateAsync: agentEfficiencyAsync } = useMutateAgentEfficiency();
// ۱۱. بار کاری دپارتمان‌ها
const { mutateAsync: deptLoadAsync } = useMutateDepartmentLoad();
// ۱۲. شاخص‌های کلیدی عملکرد (KPI)
const { mutateAsync: kpiReportAsync } = useMutateKpiReport();
// ۱۳. پیش‌بینی وضعیت تیکت‌ها
const { mutateAsync: predictionReportAsync } = useMutatePredictionReport();
const handleGetStatsReport = async () => {
try {
const { data } = await totalStatsAsync();
const formattedData = [data]?.map((t: any) => ({
"كل تيكت ها": t.total,
"تيكت هاي باز": t.open,
"تيكت هاي در حال بررسي": t.inProgress,
"تيكت هاي حل شده": t.resolved,
"تيكت هاي بسته شده": t.closed,
}));
exportToExcel("excel", formattedData, "گزارش كلي تيكت ها");
} catch (error) {
console.log(error);
toast.error(handleAxiosError(error));
}
};
const handleDepReport = async () => {
try {
const { data } = await deptReportAsync();
const formattedData = data?.map((t: any) => ({
"بخش / واحد": t.department?.displayName,
"كل تيكت ها": t.totalTickets,
"تيكت هاي باز": t.openTickets,
"تيكت هاي حل شده": t.resolvedTickets,
}));
exportToExcel("excel", formattedData, "گزارش تيكت ها به تفكيك واحد");
} catch (error) {
console.log(error);
toast.error(handleAxiosError(error));
}
};
const handleAgentPerformanceReport = async () => {
try {
const { data } = await agentPerfAsync();
const formattedData = data?.map((t: any) => ({
"كارشناس مربوطه": t.assignee?.fullname,
"كل تيكت ها": t.totalAssigned,
"تيكت هاي باز": t.open,
"تيكت هاي حل شده": t.resolved,
}));
exportToExcel("excel", formattedData, "گزارش تيكت ها به تفكيك كارشناسان");
} catch (error) {
console.log(error);
toast.error(handleAxiosError(error));
}
};
const handleAvgPerformanceReport = async () => {
try {
const { data } = await avgResTimeAsync();
const formattedData = [data]?.map((t: any) => ({
"نرخ زمان پاسخگويي": formatDurationPersian(t.avgResolutionSeconds),
"نرخ دقيق بر حسب ثانيه": t.avgResolutionSeconds,
}));
exportToExcel("excel", formattedData, "گزارش نرخ پاسخگويي ");
} catch (error) {
console.log(error);
toast.error(handleAxiosError(error));
}
};
const handleCriticalTicketsReport = async () => {
try {
const { data } = await criticalTicketsAsync();
const formattedData = data?.map((t: any) => ({
"شماره تيكت": t.ticketNumber,
"واحد / بخش": t.department?.displayName,
"تلفن داخلي": t.internalPhone,
كاربر: t.createdBy,
"محل وقوع مشكل": t.location,
"نوع درخواست": requestType.find((p) => p.id === t.requestType)
?.displayName,
"كارشناس مربوطه": t.assignee?.fullname,
"دستگاه مربوطه": t.relatedSystem,
وضعيت: ticketStatuses.find((p) => p.id === t.status)?.displayName,
توضيحات: t.description,
"اقدامات كارشناس": t.helpdeskAction,
"يادداشت ها": t.finalNotes,
"تاريخ ثبت": new Date(t.createdAt).toLocaleDateString("fa-IR"),
}));
exportToExcel("excel", formattedData, "گزارش تيكت هاي بحراني");
} catch (error) {
console.log(error);
toast.error(handleAxiosError(error));
}
};
return (
<div>
<Box
sx={{
display: "grid",
// ریسپانسیو بودن: در موبایل ۱ ستون، در تبلت ۲، در دسکتاپ ۴ ستون
gridTemplateColumns: {
xs: "1fr",
sm: "1fr 1fr",
md: "repeat(6, 1fr)",
},
gap: 3,
}}
>
<Card
sx={{
aspectRatio: "1/1", // مربع کردن کارت
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
transition: "0.3s",
"&:hover": { boxShadow: 6, transform: "translateY(-5px)" },
}}
>
<CardContent>
<Typography variant="h6" align="center" gutterBottom>
آمار کلی تیکتها{" "}
</Typography>
</CardContent>
<Stack spacing={1} sx={{ p: 2 }}>
{/* <Button
variant="contained"
startIcon={<VisibilityIcon />}
fullWidth
>
مشاهده
</Button> */}
<Button
onClick={handleGetStatsReport}
variant="outlined"
startIcon={<DownloadOutlined />}
fullWidth
>
اکسل
</Button>
</Stack>
</Card>
<Card
sx={{
aspectRatio: "1/1", // مربع کردن کارت
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
transition: "0.3s",
"&:hover": { boxShadow: 6, transform: "translateY(-5px)" },
}}
>
<CardContent>
<Typography variant="h6" align="center" gutterBottom>
گزارش عملکرد دپارتمانها
</Typography>
</CardContent>
<Stack spacing={1} sx={{ p: 2 }}>
{/* <Button
variant="contained"
startIcon={<VisibilityIcon />}
fullWidth
>
مشاهده
</Button> */}
<Button
onClick={handleDepReport}
variant="outlined"
startIcon={<DownloadOutlined />}
fullWidth
>
اکسل
</Button>
</Stack>
</Card>
<Card
sx={{
aspectRatio: "1/1", // مربع کردن کارت
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
transition: "0.3s",
"&:hover": { boxShadow: 6, transform: "translateY(-5px)" },
}}
>
<CardContent>
<Typography variant="h6" align="center" gutterBottom>
گزارش عملکرد کارشناسان
</Typography>
</CardContent>
<Stack spacing={1} sx={{ p: 2 }}>
{/* <Button
variant="contained"
startIcon={<VisibilityIcon />}
fullWidth
>
مشاهده
</Button> */}
<Button
onClick={handleAgentPerformanceReport}
variant="outlined"
startIcon={<DownloadOutlined />}
fullWidth
>
اکسل
</Button>
</Stack>
</Card>
<Card
sx={{
aspectRatio: "1/1", // مربع کردن کارت
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
transition: "0.3s",
"&:hover": { boxShadow: 6, transform: "translateY(-5px)" },
}}
>
<CardContent>
<Typography variant="h6" align="center" gutterBottom>
میانگین زمان پاسخگویی
</Typography>
</CardContent>
<Stack spacing={1} sx={{ p: 2 }}>
{/* <Button
variant="contained"
startIcon={<VisibilityIcon />}
fullWidth
>
مشاهده
</Button> */}
<Button
onClick={handleAvgPerformanceReport}
variant="outlined"
startIcon={<DownloadOutlined />}
fullWidth
>
اکسل
</Button>
</Stack>
</Card>
<Card
sx={{
aspectRatio: "1/1", // مربع کردن کارت
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
transition: "0.3s",
"&:hover": { boxShadow: 6, transform: "translateY(-5px)" },
}}
>
<CardContent>
<Typography variant="h6" align="center" gutterBottom>
تیکتهای بحرانی
</Typography>
</CardContent>
<Stack spacing={1} sx={{ p: 2 }}>
{/* <Button
variant="contained"
startIcon={<VisibilityIcon />}
fullWidth
>
مشاهده
</Button> */}
<Button
onClick={handleCriticalTicketsReport}
variant="outlined"
startIcon={<DownloadOutlined />}
fullWidth
>
اکسل
</Button>
</Stack>
</Card>
<Card
sx={{
aspectRatio: "1/1", // مربع کردن کارت
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
transition: "0.3s",
"&:hover": { boxShadow: 6, transform: "translateY(-5px)" },
}}
>
<CardContent>
<Typography variant="h6" align="center" gutterBottom>
روند ثبت تیکتها{" "}
</Typography>
</CardContent>
<Stack spacing={1} sx={{ p: 2 }}>
{/* <Button
variant="contained"
startIcon={<VisibilityIcon />}
fullWidth
>
مشاهده
</Button> */}
<Button
variant="outlined"
startIcon={<DownloadOutlined />}
fullWidth
>
اکسل
</Button>
</Stack>
</Card>
<Card
sx={{
aspectRatio: "1/1", // مربع کردن کارت
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
transition: "0.3s",
"&:hover": { boxShadow: 6, transform: "translateY(-5px)" },
}}
>
<CardContent>
<Typography variant="h6" align="center" gutterBottom>
نرخ بستن تیکتها
</Typography>
</CardContent>
<Stack spacing={1} sx={{ p: 2 }}>
{/* <Button
variant="contained"
startIcon={<VisibilityIcon />}
fullWidth
>
مشاهده
</Button> */}
<Button
variant="outlined"
startIcon={<DownloadOutlined />}
fullWidth
>
اکسل
</Button>
</Stack>
</Card>
<Card
sx={{
aspectRatio: "1/1", // مربع کردن کارت
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
transition: "0.3s",
"&:hover": { boxShadow: 6, transform: "translateY(-5px)" },
}}
>
<CardContent>
<Typography variant="h6" align="center" gutterBottom>
تیکتهای خارج از SLA
</Typography>
</CardContent>
<Stack spacing={1} sx={{ p: 2 }}>
{/* <Button
variant="contained"
startIcon={<VisibilityIcon />}
fullWidth
>
مشاهده
</Button> */}
<Button
variant="outlined"
startIcon={<DownloadOutlined />}
fullWidth
>
اکسل
</Button>
</Stack>
</Card>
<Card
sx={{
aspectRatio: "1/1", // مربع کردن کارت
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
transition: "0.3s",
"&:hover": { boxShadow: 6, transform: "translateY(-5px)" },
}}
>
<CardContent>
<Typography variant="h6" align="center" gutterBottom>
گزارش قدمت تیکتها
</Typography>
</CardContent>
<Stack spacing={1} sx={{ p: 2 }}>
{/* <Button
variant="contained"
startIcon={<VisibilityIcon />}
fullWidth
>
مشاهده
</Button> */}
<Button
variant="outlined"
startIcon={<DownloadOutlined />}
fullWidth
>
اکسل
</Button>
</Stack>
</Card>
<Card
sx={{
aspectRatio: "1/1", // مربع کردن کارت
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
transition: "0.3s",
"&:hover": { boxShadow: 6, transform: "translateY(-5px)" },
}}
>
<CardContent>
<Typography variant="h6" align="center" gutterBottom>
بهرهوری کارشناسان
</Typography>
</CardContent>
<Stack spacing={1} sx={{ p: 2 }}>
{/* <Button
variant="contained"
startIcon={<VisibilityIcon />}
fullWidth
>
مشاهده
</Button> */}
<Button
variant="outlined"
startIcon={<DownloadOutlined />}
fullWidth
>
اکسل
</Button>
</Stack>
</Card>
<Card
sx={{
aspectRatio: "1/1", // مربع کردن کارت
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
transition: "0.3s",
"&:hover": { boxShadow: 6, transform: "translateY(-5px)" },
}}
>
<CardContent>
<Typography variant="h6" align="center" gutterBottom>
بار کاری دپارتمانها{" "}
</Typography>
</CardContent>
<Stack spacing={1} sx={{ p: 2 }}>
{/* <Button
variant="contained"
startIcon={<VisibilityIcon />}
fullWidth
>
مشاهده
</Button> */}
<Button
variant="outlined"
startIcon={<DownloadOutlined />}
fullWidth
>
اکسل
</Button>
</Stack>
</Card>
<Card
sx={{
aspectRatio: "1/1", // مربع کردن کارت
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
transition: "0.3s",
"&:hover": { boxShadow: 6, transform: "translateY(-5px)" },
}}
>
<CardContent>
<Typography variant="h6" align="center" gutterBottom>
شاخصهای کلیدی عملکرد (KPI){" "}
</Typography>
</CardContent>
<Stack spacing={1} sx={{ p: 2 }}>
{/* <Button
variant="contained"
startIcon={<VisibilityIcon />}
fullWidth
>
مشاهده
</Button> */}
<Button
variant="outlined"
startIcon={<DownloadOutlined />}
fullWidth
>
اکسل
</Button>
</Stack>
</Card>
<Card
sx={{
aspectRatio: "1/1", // مربع کردن کارت
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
transition: "0.3s",
"&:hover": { boxShadow: 6, transform: "translateY(-5px)" },
}}
>
<CardContent>
<Typography variant="h6" align="center" gutterBottom>
پیشبینی وضعیت تیکتها{" "}
</Typography>
</CardContent>
<Stack spacing={1} sx={{ p: 2 }}>
{/* <Button
variant="contained"
startIcon={<VisibilityIcon />}
fullWidth
>
مشاهده
</Button> */}
<Button
variant="outlined"
startIcon={<DownloadOutlined />}
fullWidth
>
اکسل
</Button>
</Stack>
</Card>
</Box>
</div>
);
}