Rapport-Mobileapp/src/components/DashboardPerformanceStats/PerformanceStatsContainer.jsx

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;