182 lines
5.5 KiB
JavaScript
Executable File
182 lines
5.5 KiB
JavaScript
Executable File
import { useState } from "react";
|
|
import { useNavigate } from "react-router-dom";
|
|
import { Container, Card, Button } from "react-bootstrap";
|
|
import CustomIcon from "../CustomIcon/CustomIcon";
|
|
import PlaceholderCard from "../PlaceholderCard/PlaceholderCard";
|
|
import StatsCard from "../StatsCard/StatsCard";
|
|
|
|
//React Query
|
|
import { useQuery } from "@tanstack/react-query";
|
|
|
|
//Services
|
|
import dashboardService from "../../services/Dashboard";
|
|
|
|
function parseMetricViewIdFromReportUrl(reportViewUrl) {
|
|
if (!reportViewUrl || typeof reportViewUrl !== "string") return null;
|
|
try {
|
|
const u = new URL(
|
|
reportViewUrl.startsWith("http")
|
|
? reportViewUrl
|
|
: `https://placeholder.local${reportViewUrl.startsWith("/") ? "" : "/"}${reportViewUrl}`
|
|
);
|
|
return u.searchParams.get("id");
|
|
} catch {
|
|
const m = String(reportViewUrl).match(/[?&]id=([^&]+)/);
|
|
return m ? decodeURIComponent(m[1]) : null;
|
|
}
|
|
}
|
|
|
|
function PerformanceStatsContainer() {
|
|
const navigate = useNavigate();
|
|
const [isRefresh, setIsRefresh] = useState(false);
|
|
|
|
/** get all actions */
|
|
const fetchDashboardUserStats = async ({ queryKey }) => {
|
|
const [key, serviceInput] = queryKey;
|
|
// console.log("serviceInput - ", serviceInput);
|
|
try {
|
|
const statsRes = await dashboardService.getDashboardUserStats(
|
|
serviceInput
|
|
);
|
|
if (statsRes.data.status === "success") {
|
|
console.log("## Dashboard User Stats Res --", statsRes);
|
|
const stats = statsRes.data?.data?.stats;
|
|
return stats;
|
|
}
|
|
return null;
|
|
} catch (error) {
|
|
throw new Error("Error fetching quick actions");
|
|
}
|
|
};
|
|
|
|
const {
|
|
isFetching,
|
|
isPending,
|
|
isError,
|
|
data: userStats,
|
|
error,
|
|
refetch,
|
|
} = useQuery({
|
|
queryKey: ["dashboardUserStatsQuery", { isRefresh: isRefresh }],
|
|
queryFn: fetchDashboardUserStats,
|
|
});
|
|
|
|
async function handleReloadStats() {
|
|
setIsRefresh(true); // triggers refetch with a new queryKey
|
|
// refetch({ isRefresh: isRefresh });
|
|
}
|
|
|
|
const handleStatsCardClick = (item) => {
|
|
const metricViewId =
|
|
item?.id ??
|
|
item?.metric_view_id ??
|
|
parseMetricViewIdFromReportUrl(item?.report_view_url);
|
|
if (!metricViewId) {
|
|
console.warn("Performance stat has no metric view id in report_view_url");
|
|
return;
|
|
}
|
|
const title = item?.value_title || item?.title || "Metric report";
|
|
const aggType = String(item?.agg_type || "").toLowerCase();
|
|
const defaultTab =
|
|
aggType === "team" ? "Detail" : aggType === "individual" ? "Trend" : "Detail";
|
|
navigate("/metric-reports", {
|
|
state: {
|
|
metricViewId,
|
|
reportTitle: title,
|
|
pageTitle: title,
|
|
defaultTab,
|
|
},
|
|
});
|
|
};
|
|
|
|
if (isPending) {
|
|
return (
|
|
<Container className="pt-1 pb-1 py-sm-3">
|
|
<div className="d-flex flex-nowrap justify-content-betwee overflow-auto py-3">
|
|
{[0, 1].map((_, index) => (
|
|
<PlaceholderCard
|
|
key={index}
|
|
type="simple-stats"
|
|
className="card-theme overflow-hidden card-width-40 me-3"
|
|
/>
|
|
))}
|
|
</div>
|
|
</Container>
|
|
);
|
|
}
|
|
|
|
if (isError) {
|
|
return (
|
|
<Container className="mb-4">
|
|
<Card className="card-theme border-0 shadow-sm p-3 rounded-3 font-14">
|
|
No more stats
|
|
</Card>
|
|
</Container>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<>
|
|
{isFetching && userStats?.length === 0 ? (
|
|
<>
|
|
<Container className="pt-1 pb-1 py-sm-3">
|
|
<div className="d-flex flex-nowrap justify-content-betwee overflow-auto py-3">
|
|
{[0, 1].map((_, index) => (
|
|
<PlaceholderCard
|
|
key={index}
|
|
type="simple-stats"
|
|
className="card-theme overflow-hidden card-width-40 me-3"
|
|
/>
|
|
))}
|
|
</div>
|
|
</Container>
|
|
</>
|
|
) : (
|
|
<>
|
|
{userStats?.length > 0 && (
|
|
<Container className="pt-1 pb-1 py-sm-3">
|
|
<div className="d-flex align-items-center justify-content-between">
|
|
<h4 className="section-title mb-0">Performance stats</h4>
|
|
<Button
|
|
variant="link"
|
|
size="sm"
|
|
className="btn-theme font-12 fw-sb pe-0 d-none"
|
|
>
|
|
View all
|
|
</Button>
|
|
</div>
|
|
<div className="d-flex no-scrollbar flex-nowrap justify-content-betwee overflow-auto py-3 ">
|
|
{userStats.map((item, index) => (
|
|
<StatsCard
|
|
key={`${item?.value_title}-${index}`}
|
|
item={item}
|
|
className="card-width-40 shadow-sm dashboard-stats-card"
|
|
handleStatsCardClick={handleStatsCardClick}
|
|
/>
|
|
))}
|
|
</div>
|
|
<div className="text-center pt-2 pb-1">
|
|
<Button
|
|
variant="secondary"
|
|
size="sm"
|
|
className="btn-theme btn-secondary rounded- font-14"
|
|
onClick={handleReloadStats}
|
|
disabled={isFetching}
|
|
>
|
|
<CustomIcon
|
|
tag="reload3"
|
|
className={`${isFetching ? "rotate-anime" : ""}`}
|
|
/>{" "}
|
|
Reload Stats
|
|
</Button>
|
|
</div>
|
|
</Container>
|
|
)}
|
|
</>
|
|
)}
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default PerformanceStatsContainer;
|