Remove unnecessary rank tracking details cards
This commit is contained in:
parent
383531c5cd
commit
fbef08fe8e
@ -12,7 +12,6 @@ import {
|
|||||||
import type { TooltipContentProps } from "recharts";
|
import type { TooltipContentProps } from "recharts";
|
||||||
import { getRankConfigTrend } from "@/serverFunctions/rank-tracking";
|
import { getRankConfigTrend } from "@/serverFunctions/rank-tracking";
|
||||||
import type { RankTrackingRow } from "@/types/schemas/rank-tracking";
|
import type { RankTrackingRow } from "@/types/schemas/rank-tracking";
|
||||||
import { computeScorecards } from "./rankTrackingScorecards";
|
|
||||||
import {
|
import {
|
||||||
formatDateTick,
|
formatDateTick,
|
||||||
TrendRangeToggle,
|
TrendRangeToggle,
|
||||||
@ -45,11 +44,6 @@ export function RankTrackingOverview({
|
|||||||
}) {
|
}) {
|
||||||
const [sinceDays, setSinceDays] = useState(730);
|
const [sinceDays, setSinceDays] = useState(730);
|
||||||
|
|
||||||
const scorecards = useMemo(
|
|
||||||
() => computeScorecards(rows, device),
|
|
||||||
[rows, device],
|
|
||||||
);
|
|
||||||
|
|
||||||
const { data: trend, isLoading: trendLoading } = useQuery({
|
const { data: trend, isLoading: trendLoading } = useQuery({
|
||||||
queryKey: ["rankConfigTrend", projectId, configId, device, sinceDays],
|
queryKey: ["rankConfigTrend", projectId, configId, device, sinceDays],
|
||||||
queryFn: () =>
|
queryFn: () =>
|
||||||
@ -74,45 +68,6 @@ export function RankTrackingOverview({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="px-4 pt-4 pb-4">
|
<div className="px-4 pt-4 pb-4">
|
||||||
<div className="grid items-start gap-3 lg:grid-cols-2">
|
|
||||||
{/* All metrics in one card */}
|
|
||||||
<div className="rounded-lg border border-base-300 bg-base-100 p-4">
|
|
||||||
<div className="grid grid-cols-2 gap-x-4 gap-y-4 sm:grid-cols-3">
|
|
||||||
<Scorecard
|
|
||||||
label="Visibility"
|
|
||||||
value={
|
|
||||||
scorecards.visibility === null
|
|
||||||
? "-"
|
|
||||||
: `${Math.round(scorecards.visibility)}%`
|
|
||||||
}
|
|
||||||
delta={scorecards.visibilityDelta}
|
|
||||||
hint="of click potential"
|
|
||||||
/>
|
|
||||||
<Scorecard
|
|
||||||
label="Ranking"
|
|
||||||
value={String(scorecards.ranking)}
|
|
||||||
delta={scorecards.rankingDelta}
|
|
||||||
hint={`of ${rows.length} tracked`}
|
|
||||||
/>
|
|
||||||
<Scorecard
|
|
||||||
label="In Top 3"
|
|
||||||
value={String(scorecards.top3)}
|
|
||||||
hint="of ranked keywords"
|
|
||||||
/>
|
|
||||||
<Scorecard
|
|
||||||
label="In Top 10"
|
|
||||||
value={String(scorecards.top10)}
|
|
||||||
hint="includes Top 3"
|
|
||||||
/>
|
|
||||||
<Scorecard
|
|
||||||
label="Improved / Declined"
|
|
||||||
value={`${scorecards.improved} / ${scorecards.declined}`}
|
|
||||||
hint="vs comparison period"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Position distribution */}
|
|
||||||
<div className="rounded-lg border border-base-300 p-3 space-y-2">
|
<div className="rounded-lg border border-base-300 p-3 space-y-2">
|
||||||
<div className="flex items-center justify-between gap-2">
|
<div className="flex items-center justify-between gap-2">
|
||||||
<span className="text-sm font-medium">Position distribution</span>
|
<span className="text-sm font-medium">Position distribution</span>
|
||||||
@ -148,12 +103,12 @@ export function RankTrackingOverview({
|
|||||||
<div
|
<div
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
className="w-full min-w-0"
|
className="w-full min-w-0"
|
||||||
style={{ height: 180 }}
|
style={{ height: 220 }}
|
||||||
>
|
>
|
||||||
{width > 0 ? (
|
{width > 0 ? (
|
||||||
<AreaChart
|
<AreaChart
|
||||||
width={width}
|
width={width}
|
||||||
height={180}
|
height={220}
|
||||||
data={chartData}
|
data={chartData}
|
||||||
margin={{ top: 8, right: 8, bottom: 0, left: 0 }}
|
margin={{ top: 8, right: 8, bottom: 0, left: 0 }}
|
||||||
>
|
>
|
||||||
@ -197,9 +152,7 @@ export function RankTrackingOverview({
|
|||||||
typeof p.value === "number" ? p.value : 0,
|
typeof p.value === "number" ? p.value : 0,
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
return (
|
return <DistributionTooltip label={label} byKey={byKey} />;
|
||||||
<DistributionTooltip label={label} byKey={byKey} />
|
|
||||||
);
|
|
||||||
}}
|
}}
|
||||||
cursor={{ stroke: "rgba(150,150,150,0.3)" }}
|
cursor={{ stroke: "rgba(150,150,150,0.3)" }}
|
||||||
/>
|
/>
|
||||||
@ -222,7 +175,6 @@ export function RankTrackingOverview({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,37 +209,3 @@ function DistributionTooltip({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Scorecard({
|
|
||||||
label,
|
|
||||||
value,
|
|
||||||
delta,
|
|
||||||
hint,
|
|
||||||
}: {
|
|
||||||
label: string;
|
|
||||||
value: string;
|
|
||||||
delta?: number | null;
|
|
||||||
hint?: string;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<div className="min-w-0">
|
|
||||||
<p className="text-xs text-base-content/55">{label}</p>
|
|
||||||
<div className="flex items-baseline gap-1.5">
|
|
||||||
<span className="text-xl font-semibold tabular-nums">{value}</span>
|
|
||||||
{delta != null && delta !== 0 && (
|
|
||||||
<span
|
|
||||||
className={`text-xs font-medium ${
|
|
||||||
delta > 0 ? "text-success" : "text-warning"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{delta > 0 ? "▲" : "▼"}{" "}
|
|
||||||
{Number.isInteger(delta)
|
|
||||||
? Math.abs(delta)
|
|
||||||
: Math.abs(delta).toFixed(1)}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{hint && <p className="text-[11px] text-base-content/45">{hint}</p>}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user