feat(web): centralise Vietnamese price formatting across all pages
Create a single `currency.ts` utility with `formatPrice`, `formatVND`, `formatPricePerM2`, and `parseVND` to replace 9+ duplicated inline formatters. This fixes inconsistent decimal handling (1.5M was truncated to "1 triệu") and standardises price/m² display. Integrated across property cards, listing detail, dashboard, analytics, payments, pricing, and admin moderation pages with 19 new unit tests. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
||||
CardTitle,
|
||||
} from '@/components/ui/card';
|
||||
import { Link } from '@/i18n/navigation';
|
||||
import { formatVND } from '@/lib/currency';
|
||||
import { usePlans } from '@/lib/hooks/use-subscription';
|
||||
import type { PlanDto } from '@/lib/subscription-api';
|
||||
import { cn } from '@/lib/utils';
|
||||
@@ -134,16 +135,6 @@ const FALLBACK_PLANS: PlanDto[] = [
|
||||
// Helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function formatVND(amount: string | number): string {
|
||||
const num = typeof amount === 'string' ? Number(amount) : amount;
|
||||
if (num === 0) return 'Miễn phí';
|
||||
if (num >= 1_000_000) {
|
||||
const millions = num / 1_000_000;
|
||||
return `${millions % 1 === 0 ? millions.toFixed(0) : millions.toFixed(1)} triệu đ`;
|
||||
}
|
||||
return num.toLocaleString('vi-VN') + ' đ';
|
||||
}
|
||||
|
||||
// Feature labels mapped for the comparison table
|
||||
const FEATURE_LABELS: Record<string, string> = {
|
||||
maxListings: 'Tin đăng',
|
||||
|
||||
Reference in New Issue
Block a user