Compare commits
2 Commits
55098a7b95
...
7c864053bb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c864053bb | ||
|
|
9ce5511ad8 |
@@ -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 <p className="text-sm text-muted-foreground">Sin datos</p>;
|
||||
const isPositive = value >= 0;
|
||||
const color = isPositive ? "text-emerald-500" : "text-red-500";
|
||||
const sign = isPositive ? "+" : "";
|
||||
return (
|
||||
<p className={`text-lg font-bold tabular-nums ${color}`}>
|
||||
{sign}${priceFormatter.format(Math.abs(value))}{" "}
|
||||
<span className="text-sm font-normal">
|
||||
({sign}
|
||||
{pct.toFixed(2)}%)
|
||||
</span>
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-center justify-between">
|
||||
@@ -101,7 +158,7 @@ export function BeloAnalysisPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-4 md:grid-cols-2">
|
||||
<div className="grid gap-4 md:grid-cols-4">
|
||||
<div className="rounded-lg border p-4">
|
||||
<p className="text-sm text-muted-foreground mb-2">
|
||||
Mínimo histórico (compra)
|
||||
@@ -140,6 +197,16 @@ export function BeloAnalysisPage() {
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="rounded-lg border p-4">
|
||||
<p className="text-sm text-muted-foreground mb-2">Vs. día anterior</p>
|
||||
<VariationValue value={prevDayDiff} pct={prevDayPct} />
|
||||
</div>
|
||||
<div className="rounded-lg border p-4">
|
||||
<p className="text-sm text-muted-foreground mb-2">
|
||||
Vs. primer día del mes
|
||||
</p>
|
||||
<VariationValue value={monthDiff} pct={monthPct} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border p-4">
|
||||
|
||||
@@ -127,6 +127,7 @@ export function DashboardPage() {
|
||||
|
||||
const belo = quotes?.find((q) => q.type === "BELO");
|
||||
const blue = quotes?.find((q) => q.type === "BLUE");
|
||||
const bna = quotes?.find((q) => q.type === "BNA");
|
||||
|
||||
const now = new Date();
|
||||
const { data: monthlyExpenses } = useMonthlyPayedTotal(
|
||||
@@ -156,7 +157,7 @@ export function DashboardPage() {
|
||||
Actualizar
|
||||
</button>
|
||||
</div>
|
||||
<div className="grid gap-4 md:grid-cols-4">
|
||||
<div className="grid gap-4 md:grid-cols-4 lg:grid-cols-5">
|
||||
<div className="rounded-lg border p-4">
|
||||
<p className="text-sm text-muted-foreground">Pagos pendientes</p>
|
||||
<p className="text-2xl font-bold">
|
||||
@@ -176,6 +177,7 @@ export function DashboardPage() {
|
||||
variant="minimal"
|
||||
/>
|
||||
<QuoteCard quote={blue} title="BLUE" variant="minimal" />
|
||||
<QuoteCard quote={bna} title="Dolar Oficial" variant="minimal" />
|
||||
</div>
|
||||
<DashboardExpensesTable />
|
||||
</div>
|
||||
|
||||
@@ -141,11 +141,7 @@ export function ExpensesTable({
|
||||
if (expense.status === "PAYED") return null;
|
||||
return (
|
||||
<div className="flex justify-end gap-1">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
onClick={() => onEdit(expense)}
|
||||
>
|
||||
<Button variant="ghost" size="xs" onClick={() => onEdit(expense)}>
|
||||
<Pencil className="size-3.5" />
|
||||
Editar
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user