feat(analysis): show raw values ( → ) below each variation
This commit is contained in:
@@ -4,12 +4,18 @@ import { useInflation, useMonthlyLast } from "@/lib/queries";
|
||||
|
||||
type MonthKey = string;
|
||||
|
||||
type CurrencyValues = {
|
||||
variation: number | null;
|
||||
prev: number | null;
|
||||
current: number | null;
|
||||
};
|
||||
|
||||
type MonthRow = {
|
||||
month: MonthKey;
|
||||
label: string;
|
||||
BELO: number | null;
|
||||
BLUE: number | null;
|
||||
BNA: number | null;
|
||||
BELO: CurrencyValues;
|
||||
BLUE: CurrencyValues;
|
||||
BNA: CurrencyValues;
|
||||
inflation: number | null;
|
||||
};
|
||||
|
||||
@@ -38,12 +44,25 @@ function formatPct(value: number): string {
|
||||
return `${sign}${value.toFixed(1)}%`;
|
||||
}
|
||||
|
||||
const priceFormatter = new Intl.NumberFormat("es-AR", {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 0,
|
||||
});
|
||||
|
||||
function formatPrice(value: number): string {
|
||||
return `$${priceFormatter.format(value)}`;
|
||||
}
|
||||
|
||||
function VariationIndicator({
|
||||
variation,
|
||||
inflation,
|
||||
prev,
|
||||
current,
|
||||
}: {
|
||||
variation: number | null;
|
||||
inflation: number | null;
|
||||
prev: number | null;
|
||||
current: number | null;
|
||||
}) {
|
||||
if (variation === null) {
|
||||
return (
|
||||
@@ -54,32 +73,19 @@ function VariationIndicator({
|
||||
);
|
||||
}
|
||||
|
||||
if (inflation === null) {
|
||||
const isPositive = variation >= 0;
|
||||
return (
|
||||
<span
|
||||
className={`text-xs font-medium inline-flex items-center gap-1 tabular-nums ${isPositive ? "text-emerald-500" : "text-red-500"}`}
|
||||
>
|
||||
{isPositive ? (
|
||||
<ArrowUp className="size-3" />
|
||||
) : (
|
||||
<ArrowDown className="size-3" />
|
||||
)}
|
||||
{formatPct(variation)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
const beatsInflation = variation > inflation;
|
||||
return (
|
||||
const indicator = (
|
||||
<span
|
||||
className={`text-xs font-medium inline-flex items-center gap-1 tabular-nums px-1.5 py-0.5 rounded ${
|
||||
beatsInflation
|
||||
? "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400"
|
||||
: "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400"
|
||||
className={`text-xs font-medium inline-flex items-center gap-1 tabular-nums ${
|
||||
inflation !== null
|
||||
? variation > inflation
|
||||
? "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400 px-1.5 py-0.5 rounded"
|
||||
: "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400 px-1.5 py-0.5 rounded"
|
||||
: variation >= 0
|
||||
? "text-emerald-500"
|
||||
: "text-red-500"
|
||||
}`}
|
||||
>
|
||||
{beatsInflation ? (
|
||||
{variation >= 0 ? (
|
||||
<ArrowUp className="size-3" />
|
||||
) : (
|
||||
<ArrowDown className="size-3" />
|
||||
@@ -87,6 +93,19 @@ function VariationIndicator({
|
||||
{formatPct(variation)}
|
||||
</span>
|
||||
);
|
||||
|
||||
if (prev !== null && current !== null) {
|
||||
return (
|
||||
<div className="flex flex-col items-end gap-0.5">
|
||||
{indicator}
|
||||
<span className="text-[10px] text-muted-foreground tabular-nums">
|
||||
{formatPrice(prev)} → {formatPrice(current)}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return indicator;
|
||||
}
|
||||
|
||||
export function MonthlyVariationTable() {
|
||||
@@ -156,9 +175,21 @@ export function MonthlyVariationTable() {
|
||||
return {
|
||||
month,
|
||||
label: formatMonth(month),
|
||||
BELO: beloVar,
|
||||
BLUE: blueVar,
|
||||
BNA: bnaVar,
|
||||
BELO: {
|
||||
variation: beloVar,
|
||||
prev: prevData?.BELO ?? null,
|
||||
current: current?.BELO ?? null,
|
||||
},
|
||||
BLUE: {
|
||||
variation: blueVar,
|
||||
prev: prevData?.BLUE ?? null,
|
||||
current: current?.BLUE ?? null,
|
||||
},
|
||||
BNA: {
|
||||
variation: bnaVar,
|
||||
prev: prevData?.BNA ?? null,
|
||||
current: current?.BNA ?? null,
|
||||
},
|
||||
inflation,
|
||||
};
|
||||
})
|
||||
@@ -208,15 +239,19 @@ export function MonthlyVariationTable() {
|
||||
<div>
|
||||
<p className="text-[10px] text-muted-foreground mb-0.5">BELO</p>
|
||||
<VariationIndicator
|
||||
variation={row.BELO}
|
||||
variation={row.BELO.variation}
|
||||
inflation={row.inflation}
|
||||
prev={row.BELO.prev}
|
||||
current={row.BELO.current}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-[10px] text-muted-foreground mb-0.5">Blue</p>
|
||||
<VariationIndicator
|
||||
variation={row.BLUE}
|
||||
variation={row.BLUE.variation}
|
||||
inflation={row.inflation}
|
||||
prev={row.BLUE.prev}
|
||||
current={row.BLUE.current}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
@@ -224,8 +259,10 @@ export function MonthlyVariationTable() {
|
||||
Oficial
|
||||
</p>
|
||||
<VariationIndicator
|
||||
variation={row.BNA}
|
||||
variation={row.BNA.variation}
|
||||
inflation={row.inflation}
|
||||
prev={row.BNA.prev}
|
||||
current={row.BNA.current}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -263,20 +300,26 @@ export function MonthlyVariationTable() {
|
||||
<td className="px-3 py-2.5 font-medium">{row.label}</td>
|
||||
<td className="px-3 py-2.5 text-right">
|
||||
<VariationIndicator
|
||||
variation={row.BELO}
|
||||
variation={row.BELO.variation}
|
||||
inflation={row.inflation}
|
||||
prev={row.BELO.prev}
|
||||
current={row.BELO.current}
|
||||
/>
|
||||
</td>
|
||||
<td className="px-3 py-2.5 text-right">
|
||||
<VariationIndicator
|
||||
variation={row.BLUE}
|
||||
variation={row.BLUE.variation}
|
||||
inflation={row.inflation}
|
||||
prev={row.BLUE.prev}
|
||||
current={row.BLUE.current}
|
||||
/>
|
||||
</td>
|
||||
<td className="px-3 py-2.5 text-right">
|
||||
<VariationIndicator
|
||||
variation={row.BNA}
|
||||
variation={row.BNA.variation}
|
||||
inflation={row.inflation}
|
||||
prev={row.BNA.prev}
|
||||
current={row.BNA.current}
|
||||
/>
|
||||
</td>
|
||||
<td className="px-3 py-2.5 text-right">
|
||||
|
||||
Reference in New Issue
Block a user