import { useGetAnalyticsSummary, useGetTopTools, useGetAnalyticsByCategory, useGetRatingDistribution, GetTopToolsMetric } from "@workspace/api-client-react"; import { useTranslation } from "react-i18next"; import { Layout } from "@/components/layout"; import { GuideHelp } from "@/components/guide-help"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; import { Skeleton } from "@/components/ui/skeleton"; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip as RechartsTooltip, ResponsiveContainer, RadarChart, PolarGrid, PolarAngleAxis, PolarRadiusAxis, Radar, Legend, LineChart, Line } from "recharts"; import { BarChart3, TrendingUp, Layers, Activity } from "lucide-react"; export default function Analytics() { const { t } = useTranslation(); const { data: summary, isLoading: loadingSummary } = useGetAnalyticsSummary(); const { data: topTools, isLoading: loadingTopTools } = useGetTopTools({ limit: 8, metric: GetTopToolsMetric.combined }); const { data: categoryStats, isLoading: loadingCategories } = useGetAnalyticsByCategory(); const { data: distribution, isLoading: loadingDistribution } = useGetRatingDistribution(); const topToolsChartData = topTools?.map(t => ({ name: t.tool.name, score: Number((t.score).toFixed(2)), ratings: t.ratingCount })) || []; const categoryChartData = categoryStats?.map(c => ({ category: c.category, tools: c.toolCount, avgScore: (c.avgUsefulness != null && c.avgUsability != null) ? Number(((c.avgUsefulness + c.avgUsability) / 2).toFixed(2)) : 0 })) || []; const usefulnessData = distribution?.usefulness.map(b => ({ score: `${b.score} Star`, count: b.count })) || []; const usabilityData = distribution?.usability.map(b => ({ score: `${b.score} Star`, count: b.count })) || []; return (

{t("analytics.title")}

{t("analytics.subtitle")}

{/* Top KPI Cards */}
{t("analytics.totalToolsIndexed")}
{loadingSummary ? : (
{summary?.totalTools || 0}
)}
{t("analytics.totalRatingsCast")}
{loadingSummary ? : (
{summary?.totalRatings || 0}
)}
{t("analytics.activeCategories")}
{loadingSummary ? : (
{summary?.categoriesCount || 0}
)}
{t("analytics.avgGlobalScore")}
{loadingSummary ? : (
{summary?.avgCombined?.toFixed(2) || "0.00"}
)}
{/* Top Tools Chart */} {t("analytics.top8Tools")} {t("analytics.top8ToolsSub")} {loadingTopTools ? ( ) : (
`${v}`} tick={{ fill: 'hsl(var(--foreground))', fontSize: 12 }} />
)}
{/* Category Breakdown */} {t("analytics.toolsByCategory")} {t("analytics.toolsByCategorySub")} {loadingCategories ? ( ) : (
)}
{/* Rating Distributions */} {t("analytics.globalRatingDistribution")} {t("analytics.globalRatingDistributionSub")} {loadingDistribution ? ( ) : (
{t("detail.usefulness")}
{t("detail.usability")}
)}
); }