feat(analysis): add comparison chart of buy price for the 3 quotes

This commit is contained in:
Jose Selesan
2026-08-20 14:33:39 -03:00
parent 31dae446af
commit 48c4c892cd

View File

@@ -67,6 +67,22 @@ export function AnalysisPage({ currency }: { currency: string }) {
endDateStr,
);
const { data: beloDaily, isLoading: beloLoading } = useDailyQuotes(
"BELO",
startDateStr,
endDateStr,
);
const { data: blueDaily, isLoading: blueLoading } = useDailyQuotes(
"BLUE",
startDateStr,
endDateStr,
);
const { data: bnaDaily, isLoading: bnaLoading } = useDailyQuotes(
"BNA",
startDateStr,
endDateStr,
);
const yesterday = subDays(today, 1);
const yesterdayStr = formatDate(yesterday);
const firstOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
@@ -91,6 +107,29 @@ export function AnalysisPage({ currency }: { currency: string }) {
}));
}, [daily]);
const comparisonData = useMemo(() => {
const map = new Map<
string,
{ date: string; BELO?: number; BLUE?: number; BNA?: number }
>();
const add = (
rows: { date: string; buy: number }[] | undefined,
key: "BELO" | "BLUE" | "BNA",
) => {
rows?.forEach((d) => {
const entry = map.get(d.date) ?? { date: d.date };
entry[key] = d.buy;
map.set(d.date, entry);
});
};
add(beloDaily, "BELO");
add(blueDaily, "BLUE");
add(bnaDaily, "BNA");
return [...map.values()]
.sort((a, b) => a.date.localeCompare(b.date))
.map(({ date, ...rest }) => ({ date: formatShortDate(date), ...rest }));
}, [beloDaily, blueDaily, bnaDaily]);
const { yDomain, minBuyValue, maxBuyValue, avgBuyValue } = useMemo(() => {
if (chartData.length === 0)
return {
@@ -178,7 +217,10 @@ export function AnalysisPage({ currency }: { currency: string }) {
key={c}
type="button"
onClick={() =>
navigate({ to: "/quotes/analysis/$currency", params: { currency: c } })
navigate({
to: "/quotes/analysis/$currency",
params: { currency: c },
})
}
className={`px-3 py-1 text-xs rounded-md transition-colors cursor-pointer ${
currency === c
@@ -402,6 +444,119 @@ export function AnalysisPage({ currency }: { currency: string }) {
</>
)}
</div>
<div className="rounded-lg border p-4">
<h2 className="text-sm font-medium mb-4">
Precio de compra por cotización
</h2>
{beloLoading || blueLoading || bnaLoading ? (
<div className="flex items-center justify-center h-64 text-muted-foreground">
Cargando...
</div>
) : comparisonData.length === 0 ? (
<div className="flex items-center justify-center h-64 text-muted-foreground">
Sin datos para este período
</div>
) : (
<>
<div className="h-64">
<ResponsiveContainer width="100%" height="100%">
<LineChart data={comparisonData}>
<CartesianGrid
strokeDasharray="3 3"
className="stroke-border"
/>
<XAxis
dataKey="date"
tick={{ fontSize: 11 }}
className="text-muted-foreground"
interval="preserveStartEnd"
/>
<YAxis
tick={{ fontSize: 11 }}
className="text-muted-foreground"
tickFormatter={(v: number) =>
`$${priceFormatter.format(v)}`
}
width={80}
/>
<Tooltip
formatter={(value: unknown, name: unknown) => [
`$${priceFormatter.format(Number(value))}`,
CURRENCY_LABELS[String(name)] ?? String(name),
]}
labelFormatter={(label: unknown) => `Fecha: ${label}`}
contentStyle={{
backgroundColor: "var(--card)",
border: "1px solid var(--border)",
borderRadius: "var(--radius)",
fontSize: 13,
}}
/>
<Line
type="linear"
dataKey="BELO"
name="BELO"
stroke="var(--chart-1)"
strokeWidth={2}
dot={false}
activeDot={{ r: 4 }}
isAnimationActive={false}
/>
<Line
type="linear"
dataKey="BLUE"
name="BLUE"
stroke="var(--chart-2)"
strokeWidth={2}
dot={false}
activeDot={{ r: 4 }}
isAnimationActive={false}
/>
<Line
type="linear"
dataKey="BNA"
name="BNA"
stroke="var(--chart-4)"
strokeWidth={2}
dot={false}
activeDot={{ r: 4 }}
isAnimationActive={false}
/>
</LineChart>
</ResponsiveContainer>
</div>
<div className="flex items-center justify-center gap-4 mt-3">
<div className="flex items-center gap-1.5">
<span
className="size-2.5 rounded-full"
style={{ backgroundColor: "var(--chart-1)" }}
/>
<span className="text-xs text-muted-foreground">BELO</span>
</div>
<div className="flex items-center gap-1.5">
<span
className="size-2.5 rounded-full"
style={{ backgroundColor: "var(--chart-2)" }}
/>
<span className="text-xs text-muted-foreground">
Dólar Blue
</span>
</div>
<div className="flex items-center gap-1.5">
<span
className="size-2.5 rounded-full"
style={{ backgroundColor: "var(--chart-4)" }}
/>
<span className="text-xs text-muted-foreground">
Dólar Oficial
</span>
</div>
</div>
</>
)}
</div>
</div>
);
}