Files
goodgo-platform/apps/web/components/listings/price-history-chart.tsx
Ho Ngoc Hai 865a28009f refactor(web): dedup tỷ/triệu compact formatters (GOO-206)
- Add `formatCompact` as an exported alias for `formatPrice` in lib/currency.ts
- Replace 5 inline copies of the tỷ/triệu compact formatter:
  - components/map/listing-map.tsx (local `formatPrice` fn)
  - components/agents/agent-profile-client.tsx (local `fmtVND` fn)
  - app/(dashboard)/dashboard/saved-searches/page.tsx (local `formatPrice` fn)
  - app/(public)/page.tsx (local `formatVnd` fn + `vndFmt` Intl instance)
  - components/listings/price-history-chart.tsx (local `formatMillions` + `priceToMillions`)

All call sites now import from the canonical lib/currency module.
PriceHistoryChart now stores raw VND in chart data (was: millions) so
formatCompact emits correct tỷ/triệu labels using canonical thresholds.

Pre-existing test failures in inquiry/lead/AVM specs are unrelated to this change.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-24 12:37:43 +07:00

66 lines
1.8 KiB
TypeScript

'use client';
import {
LineChart,
Line,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
ResponsiveContainer,
} from 'recharts';
import type { PriceHistoryItem } from '@/lib/listings-api';
import { formatCompact } from '@/lib/currency';
interface PriceHistoryChartProps {
data: PriceHistoryItem[];
height?: number;
}
export function PriceHistoryChart({ data, height = 280 }: PriceHistoryChartProps) {
if (data.length === 0) return null;
const chartData = [...data]
.sort((a, b) => new Date(a.changedAt).getTime() - new Date(b.changedAt).getTime())
.map((item) => ({
date: new Date(item.changedAt).toLocaleDateString('vi-VN', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
}),
price: Number(item.newPrice),
}));
return (
<ResponsiveContainer width="100%" height={height}>
<LineChart data={chartData} margin={{ top: 5, right: 20, left: 0, bottom: 5 }}>
<CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
<XAxis dataKey="date" tick={{ fontSize: 11 }} className="fill-muted-foreground" />
<YAxis
tick={{ fontSize: 11 }}
className="fill-muted-foreground"
tickFormatter={(v: number) => formatCompact(v)}
/>
<Tooltip
contentStyle={{
backgroundColor: 'hsl(var(--card))',
border: '1px solid hsl(var(--border))',
borderRadius: '0.5rem',
fontSize: '0.875rem',
}}
formatter={(value) => [formatCompact(Number(value)), 'Giá']}
/>
<Line
type="monotone"
dataKey="price"
stroke="hsl(var(--primary))"
strokeWidth={2}
dot={{ r: 4 }}
activeDot={{ r: 6 }}
/>
</LineChart>
</ResponsiveContainer>
);
}