From c0c8bf09458413552fb52b4e427ddc4f6c292985 Mon Sep 17 00:00:00 2001 From: Jose Selesan Date: Fri, 12 Jun 2026 16:44:20 -0300 Subject: [PATCH] feat(analysis): make analysis page work for all currencies (BELO, BLUE, BNA) - Replace hardcoded BELO analysis with generic AnalysisPage - Add /quotes/analysis/ route with currency path param - Add currency selector tabs on analysis page - Dashboard QuoteCards now navigate to analysis for all currencies - Old /quotes/belo/analysis redirects to /quotes/analysis/BELO --- .../AnalysisPage.tsx} | 50 +++++++++++++++---- apps/frontend/src/features/belo/BeloPage.tsx | 3 +- .../src/features/dashboard/DashboardPage.tsx | 16 ++++-- .../quotes.analysis.$currency.tsx | 20 ++++++++ .../_authenticated/quotes.belo.analysis.tsx | 7 +-- 5 files changed, 79 insertions(+), 17 deletions(-) rename apps/frontend/src/features/{belo/BeloAnalysisPage.tsx => analysis/AnalysisPage.tsx} (89%) create mode 100644 apps/frontend/src/routes/_authenticated/quotes.analysis.$currency.tsx diff --git a/apps/frontend/src/features/belo/BeloAnalysisPage.tsx b/apps/frontend/src/features/analysis/AnalysisPage.tsx similarity index 89% rename from apps/frontend/src/features/belo/BeloAnalysisPage.tsx rename to apps/frontend/src/features/analysis/AnalysisPage.tsx index 0522ed8..1c28fe0 100644 --- a/apps/frontend/src/features/belo/BeloAnalysisPage.tsx +++ b/apps/frontend/src/features/analysis/AnalysisPage.tsx @@ -1,4 +1,4 @@ -import { Link } from "@tanstack/react-router"; +import { Link, useNavigate } from "@tanstack/react-router"; import { subDays } from "date-fns"; import { ArrowLeft } from "lucide-react"; import { useMemo, useState } from "react"; @@ -15,6 +15,14 @@ import { import { DatePicker } from "@/components/ui/date-picker"; import { useDailyQuotes, useHistoricalMinMax, useQuotes } from "@/lib/queries"; +const CURRENCIES = ["BELO", "BLUE", "BNA"] as const; + +const CURRENCY_LABELS: Record = { + BELO: "BELO", + BLUE: "Dólar Blue", + BNA: "Dólar Oficial", +}; + const priceFormatter = new Intl.NumberFormat("es-AR", { minimumFractionDigits: 2, maximumFractionDigits: 2, @@ -39,7 +47,8 @@ function formatShortDate(iso: string): string { return dateFormatter.format(new Date(y, m - 1, d)); } -export function BeloAnalysisPage() { +export function AnalysisPage({ currency }: { currency: string }) { + const navigate = useNavigate(); const today = new Date(); const defaultStart = subDays(today, 30); @@ -50,10 +59,10 @@ export function BeloAnalysisPage() { const endDateStr = formatDate(endDate); const { data: historical, isLoading: historicalLoading } = - useHistoricalMinMax("BELO"); + useHistoricalMinMax(currency); const { data: quotes } = useQuotes(); const { data: daily, isLoading: dailyLoading } = useDailyQuotes( - "BELO", + currency, startDateStr, endDateStr, ); @@ -64,12 +73,12 @@ export function BeloAnalysisPage() { const firstOfMonthStr = formatDate(firstOfMonth); const { data: yesterdayQuote } = useDailyQuotes( - "BELO", + currency, yesterdayStr, yesterdayStr, ); const { data: firstDayQuote } = useDailyQuotes( - "BELO", + currency, firstOfMonthStr, firstOfMonthStr, ); @@ -107,8 +116,8 @@ export function BeloAnalysisPage() { }; }, [chartData]); - const beloQuote = quotes?.find((q) => q.type === "BELO"); - const currentBuy = beloQuote ? Number(beloQuote.buy) : 0; + const currentQuote = quotes?.find((q) => q.type === currency); + const currentBuy = currentQuote ? Number(currentQuote.buy) : 0; const yesterdayBuy = yesterdayQuote?.[0]?.buy ?? null; const prevDayDiff = yesterdayBuy !== null ? currentBuy - yesterdayBuy : null; @@ -124,6 +133,9 @@ export function BeloAnalysisPage() { ? (monthDiff / firstMonthBuy) * 100 : null; + const backTo = currency === "BELO" ? "/quotes/belo" : "/quotes"; + const backLabel = currency === "BELO" ? "BELO" : "Cotizaciones"; + function VariationValue({ value, pct, @@ -152,14 +164,32 @@ export function BeloAnalysisPage() {
- BELO + {backLabel}

Análisis

+
+ {CURRENCIES.map((c) => ( + + ))} +
diff --git a/apps/frontend/src/features/belo/BeloPage.tsx b/apps/frontend/src/features/belo/BeloPage.tsx index 424e8d1..591e2e9 100644 --- a/apps/frontend/src/features/belo/BeloPage.tsx +++ b/apps/frontend/src/features/belo/BeloPage.tsx @@ -232,7 +232,8 @@ export function BeloPage() { )} diff --git a/apps/frontend/src/features/dashboard/DashboardPage.tsx b/apps/frontend/src/features/dashboard/DashboardPage.tsx index 6b6d58b..b0c47df 100644 --- a/apps/frontend/src/features/dashboard/DashboardPage.tsx +++ b/apps/frontend/src/features/dashboard/DashboardPage.tsx @@ -173,11 +173,21 @@ export function DashboardPage() { + + - -
diff --git a/apps/frontend/src/routes/_authenticated/quotes.analysis.$currency.tsx b/apps/frontend/src/routes/_authenticated/quotes.analysis.$currency.tsx new file mode 100644 index 0000000..7683965 --- /dev/null +++ b/apps/frontend/src/routes/_authenticated/quotes.analysis.$currency.tsx @@ -0,0 +1,20 @@ +import { createFileRoute, redirect } from "@tanstack/react-router"; +import { AnalysisPage } from "@/features/analysis/AnalysisPage"; + +const VALID_CURRENCIES = ["BELO", "BLUE", "BNA"]; + +export const Route = createFileRoute( + "/_authenticated/quotes/analysis/$currency", +)({ + component: RouteComponent, + loader: ({ params }) => { + if (!VALID_CURRENCIES.includes(params.currency)) { + throw redirect({ to: "/quotes" }); + } + }, +}); + +function RouteComponent() { + const { currency } = Route.useParams(); + return ; +} diff --git a/apps/frontend/src/routes/_authenticated/quotes.belo.analysis.tsx b/apps/frontend/src/routes/_authenticated/quotes.belo.analysis.tsx index faf8bda..4e881b1 100644 --- a/apps/frontend/src/routes/_authenticated/quotes.belo.analysis.tsx +++ b/apps/frontend/src/routes/_authenticated/quotes.belo.analysis.tsx @@ -1,6 +1,7 @@ -import { createFileRoute } from "@tanstack/react-router"; -import { BeloAnalysisPage } from "@/features/belo/BeloAnalysisPage"; +import { createFileRoute, redirect } from "@tanstack/react-router"; export const Route = createFileRoute("/_authenticated/quotes/belo/analysis")({ - component: BeloAnalysisPage, + loader: () => { + throw redirect({ to: "/quotes/analysis/$currency", params: { currency: "BELO" } }); + }, });