first commit
This commit is contained in:
621
app/(panel)/reports/page.tsx
Normal file
621
app/(panel)/reports/page.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user