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 MonthKey = string;
|
||||||
|
|
||||||
|
type CurrencyValues = {
|
||||||
|
variation: number | null;
|
||||||
|
prev: number | null;
|
||||||
|
current: number | null;
|
||||||
|
};
|
||||||
|
|
||||||
type MonthRow = {
|
type MonthRow = {
|
||||||
month: MonthKey;
|
month: MonthKey;
|
||||||
label: string;
|
label: string;
|
||||||
BELO: number | null;
|
BELO: CurrencyValues;
|
||||||
BLUE: number | null;
|
BLUE: CurrencyValues;
|
||||||
BNA: number | null;
|
BNA: CurrencyValues;
|
||||||
inflation: number | null;
|
inflation: number | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -38,12 +44,25 @@ function formatPct(value: number): string {
|
|||||||
return `${sign}${value.toFixed(1)}%`;
|
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({
|
function VariationIndicator({
|
||||||
variation,
|
variation,
|
||||||
inflation,
|
inflation,
|
||||||
|
prev,
|
||||||
|
current,
|
||||||
}: {
|
}: {
|
||||||
variation: number | null;
|
variation: number | null;
|
||||||
inflation: number | null;
|
inflation: number | null;
|
||||||
|
prev: number | null;
|
||||||
|
current: number | null;
|
||||||
}) {
|
}) {
|
||||||
if (variation === null) {
|
if (variation === null) {
|
||||||
return (
|
return (
|
||||||
@@ -54,32 +73,19 @@ function VariationIndicator({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inflation === null) {
|
const indicator = (
|
||||||
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 (
|
|
||||||
<span
|
<span
|
||||||
className={`text-xs font-medium inline-flex items-center gap-1 tabular-nums px-1.5 py-0.5 rounded ${
|
className={`text-xs font-medium inline-flex items-center gap-1 tabular-nums ${
|
||||||
beatsInflation
|
inflation !== null
|
||||||
? "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400"
|
? variation > inflation
|
||||||
: "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400"
|
? "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" />
|
<ArrowUp className="size-3" />
|
||||||
) : (
|
) : (
|
||||||
<ArrowDown className="size-3" />
|
<ArrowDown className="size-3" />
|
||||||
@@ -87,6 +93,19 @@ function VariationIndicator({
|
|||||||
{formatPct(variation)}
|
{formatPct(variation)}
|
||||||
</span>
|
</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() {
|
export function MonthlyVariationTable() {
|
||||||
@@ -156,9 +175,21 @@ export function MonthlyVariationTable() {
|
|||||||
return {
|
return {
|
||||||
month,
|
month,
|
||||||
label: formatMonth(month),
|
label: formatMonth(month),
|
||||||
BELO: beloVar,
|
BELO: {
|
||||||
BLUE: blueVar,
|
variation: beloVar,
|
||||||
BNA: bnaVar,
|
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,
|
inflation,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
@@ -208,15 +239,19 @@ export function MonthlyVariationTable() {
|
|||||||
<div>
|
<div>
|
||||||
<p className="text-[10px] text-muted-foreground mb-0.5">BELO</p>
|
<p className="text-[10px] text-muted-foreground mb-0.5">BELO</p>
|
||||||
<VariationIndicator
|
<VariationIndicator
|
||||||
variation={row.BELO}
|
variation={row.BELO.variation}
|
||||||
inflation={row.inflation}
|
inflation={row.inflation}
|
||||||
|
prev={row.BELO.prev}
|
||||||
|
current={row.BELO.current}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-[10px] text-muted-foreground mb-0.5">Blue</p>
|
<p className="text-[10px] text-muted-foreground mb-0.5">Blue</p>
|
||||||
<VariationIndicator
|
<VariationIndicator
|
||||||
variation={row.BLUE}
|
variation={row.BLUE.variation}
|
||||||
inflation={row.inflation}
|
inflation={row.inflation}
|
||||||
|
prev={row.BLUE.prev}
|
||||||
|
current={row.BLUE.current}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -224,8 +259,10 @@ export function MonthlyVariationTable() {
|
|||||||
Oficial
|
Oficial
|
||||||
</p>
|
</p>
|
||||||
<VariationIndicator
|
<VariationIndicator
|
||||||
variation={row.BNA}
|
variation={row.BNA.variation}
|
||||||
inflation={row.inflation}
|
inflation={row.inflation}
|
||||||
|
prev={row.BNA.prev}
|
||||||
|
current={row.BNA.current}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</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 font-medium">{row.label}</td>
|
||||||
<td className="px-3 py-2.5 text-right">
|
<td className="px-3 py-2.5 text-right">
|
||||||
<VariationIndicator
|
<VariationIndicator
|
||||||
variation={row.BELO}
|
variation={row.BELO.variation}
|
||||||
inflation={row.inflation}
|
inflation={row.inflation}
|
||||||
|
prev={row.BELO.prev}
|
||||||
|
current={row.BELO.current}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-3 py-2.5 text-right">
|
<td className="px-3 py-2.5 text-right">
|
||||||
<VariationIndicator
|
<VariationIndicator
|
||||||
variation={row.BLUE}
|
variation={row.BLUE.variation}
|
||||||
inflation={row.inflation}
|
inflation={row.inflation}
|
||||||
|
prev={row.BLUE.prev}
|
||||||
|
current={row.BLUE.current}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-3 py-2.5 text-right">
|
<td className="px-3 py-2.5 text-right">
|
||||||
<VariationIndicator
|
<VariationIndicator
|
||||||
variation={row.BNA}
|
variation={row.BNA.variation}
|
||||||
inflation={row.inflation}
|
inflation={row.inflation}
|
||||||
|
prev={row.BNA.prev}
|
||||||
|
current={row.BNA.current}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-3 py-2.5 text-right">
|
<td className="px-3 py-2.5 text-right">
|
||||||
|
|||||||
Reference in New Issue
Block a user