From 7c864053bb9c2614af6d03b1d4d2ffb4792afb80 Mon Sep 17 00:00:00 2001 From: Jose Selesan Date: Thu, 4 Jun 2026 11:10:37 -0300 Subject: [PATCH] feat(belo): add daily and monthly variation quotes to analysis page --- .../src/features/belo/BeloAnalysisPage.tsx | 71 ++++++++++++++++++- .../expenses/components/ExpensesTable.tsx | 6 +- 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/apps/frontend/src/features/belo/BeloAnalysisPage.tsx b/apps/frontend/src/features/belo/BeloAnalysisPage.tsx index 3730c91..882bf62 100644 --- a/apps/frontend/src/features/belo/BeloAnalysisPage.tsx +++ b/apps/frontend/src/features/belo/BeloAnalysisPage.tsx @@ -13,7 +13,7 @@ import { YAxis, } from "recharts"; import { DatePicker } from "@/components/ui/date-picker"; -import { useDailyQuotes, useHistoricalMinMax } from "@/lib/queries"; +import { useDailyQuotes, useHistoricalMinMax, useQuotes } from "@/lib/queries"; const priceFormatter = new Intl.NumberFormat("es-AR", { minimumFractionDigits: 2, @@ -47,12 +47,29 @@ export function BeloAnalysisPage() { const { data: historical, isLoading: historicalLoading } = useHistoricalMinMax("BELO"); + const { data: quotes } = useQuotes(); const { data: daily, isLoading: dailyLoading } = useDailyQuotes( "BELO", startDateStr, endDateStr, ); + const yesterday = subDays(today, 1); + const yesterdayStr = formatDate(yesterday); + const firstOfMonth = new Date(today.getFullYear(), today.getMonth(), 1); + const firstOfMonthStr = formatDate(firstOfMonth); + + const { data: yesterdayQuote } = useDailyQuotes( + "BELO", + yesterdayStr, + yesterdayStr, + ); + const { data: firstDayQuote } = useDailyQuotes( + "BELO", + firstOfMonthStr, + firstOfMonthStr, + ); + const chartData = useMemo(() => { if (!daily) return []; return daily.map((d) => ({ @@ -86,6 +103,46 @@ export function BeloAnalysisPage() { }; }, [chartData]); + const beloQuote = quotes?.find((q) => q.type === "BELO"); + const currentBuy = beloQuote ? Number(beloQuote.buy) : 0; + + const yesterdayBuy = yesterdayQuote?.[0]?.buy ?? null; + const prevDayDiff = yesterdayBuy !== null ? currentBuy - yesterdayBuy : null; + const prevDayPct = + prevDayDiff !== null && yesterdayBuy !== null && yesterdayBuy !== 0 + ? (prevDayDiff / yesterdayBuy) * 100 + : null; + + const firstMonthBuy = firstDayQuote?.[0]?.buy ?? null; + const monthDiff = firstMonthBuy !== null ? currentBuy - firstMonthBuy : null; + const monthPct = + monthDiff !== null && firstMonthBuy !== null && firstMonthBuy !== 0 + ? (monthDiff / firstMonthBuy) * 100 + : null; + + function VariationValue({ + value, + pct, + }: { + value: number | null; + pct: number | null; + }) { + if (value === null || pct === null) + return

Sin datos

; + const isPositive = value >= 0; + const color = isPositive ? "text-emerald-500" : "text-red-500"; + const sign = isPositive ? "+" : ""; + return ( +

+ {sign}${priceFormatter.format(Math.abs(value))}{" "} + + ({sign} + {pct.toFixed(2)}%) + +

+ ); + } + return (
@@ -101,7 +158,7 @@ export function BeloAnalysisPage() {
-
+

Mínimo histórico (compra) @@ -140,6 +197,16 @@ export function BeloAnalysisPage() { )}

+
+

Vs. día anterior

+ +
+
+

+ Vs. primer día del mes +

+ +
diff --git a/apps/frontend/src/features/expenses/components/ExpensesTable.tsx b/apps/frontend/src/features/expenses/components/ExpensesTable.tsx index 912a376..0577e97 100644 --- a/apps/frontend/src/features/expenses/components/ExpensesTable.tsx +++ b/apps/frontend/src/features/expenses/components/ExpensesTable.tsx @@ -141,11 +141,7 @@ export function ExpensesTable({ if (expense.status === "PAYED") return null; return (
-