diff --git a/apps/frontend/src/features/analysis/AnalysisPage.tsx b/apps/frontend/src/features/analysis/AnalysisPage.tsx index 1c28fe0..e36d3a3 100644 --- a/apps/frontend/src/features/analysis/AnalysisPage.tsx +++ b/apps/frontend/src/features/analysis/AnalysisPage.tsx @@ -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 }) { )} + +
+

+ Precio de compra por cotización +

+ + {beloLoading || blueLoading || bnaLoading ? ( +
+ Cargando... +
+ ) : comparisonData.length === 0 ? ( +
+ Sin datos para este período +
+ ) : ( + <> +
+ + + + + + `$${priceFormatter.format(v)}` + } + width={80} + /> + [ + `$${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, + }} + /> + + + + + +
+
+
+ + BELO +
+
+ + + Dólar Blue + +
+
+ + + Dólar Oficial + +
+
+ + )} +
); }