diff --git a/apps/web/app/[locale]/(public)/listings/[id]/page.tsx b/apps/web/app/[locale]/(public)/listings/[id]/page.tsx index 129e31b..759a8dd 100644 --- a/apps/web/app/[locale]/(public)/listings/[id]/page.tsx +++ b/apps/web/app/[locale]/(public)/listings/[id]/page.tsx @@ -1,349 +1,128 @@ -'use client'; +import type { Metadata } from 'next'; +import { notFound } from 'next/navigation'; +import { ListingDetailClient } from '@/components/listings/listing-detail-client'; +import { + JsonLd, + generateBreadcrumbJsonLd, + generateListingJsonLd, +} from '@/components/seo/json-ld'; +import { fetchListingById } from '@/lib/listings-server'; +import { PROPERTY_TYPES, TRANSACTION_TYPES } from '@/lib/validations/listings'; -import dynamic from 'next/dynamic'; -import Link from 'next/link'; -import { useParams } from 'next/navigation'; -import * as React from 'react'; -import { ImageGallery } from '@/components/listings/image-gallery'; -import { Badge } from '@/components/ui/badge'; -import { Button } from '@/components/ui/button'; -import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; -import { AiEstimateButton } from '@/components/valuation/ai-estimate-button'; -import { listingsApi, type ListingDetail } from '@/lib/listings-api'; -import { PROPERTY_TYPES, DIRECTIONS, TRANSACTION_TYPES } from '@/lib/validations/listings'; +// --------------------------------------------------------------------------- +// Constants +// --------------------------------------------------------------------------- -const ListingMap = dynamic( - () => import('@/components/map/listing-map').then((mod) => mod.ListingMap), - { - ssr: false, - loading: () => ( -
Đang tải bản đồ...
-{error || 'Không tìm thấy tin đăng'}
- - - -- - {property.address}, {property.ward}, {property.district}, {property.city} -
-{formatPrice(listing.priceVND)} VND
- {listing.pricePerM2 != null && ( -- ~{listing.pricePerM2.toLocaleString('vi-VN')} VND/m² -
- )} - {listing.rentPriceMonthly && ( -- Thuê: {formatPrice(listing.rentPriceMonthly)}/tháng -
- )} -{property.description}
-{seller.fullName}
-{seller.phone}
-Môi giới
- {agent.agency &&{agent.agency}
} - {listing.commissionPct != null && ( -Hoa hồng: {listing.commissionPct}%
- )} -{listing.viewCount}
-Lượt xem
-{listing.saveCount}
-Lượt lưu
-{listing.inquiryCount}
-Liên hệ
-- Đăng ngày {new Date(listing.publishedAt).toLocaleDateString('vi-VN')} -
- )} -{label}
-{value}
-{label}
-{value}
-{'\u0110ang t\u1ea3i b\u1ea3n \u0111\u1ed3...'}
++ + {property.address}, {property.ward}, {property.district}, {property.city} +
+{formatPrice(listing.priceVND)} VND
+ {listing.pricePerM2 != null && ( ++ ~{listing.pricePerM2.toLocaleString('vi-VN')} VND/m² +
+ )} + {listing.rentPriceMonthly && ( ++ Thu\u00ea: {formatPrice(listing.rentPriceMonthly)}/th\u00e1ng +
+ )} +{property.description}
+{seller.fullName}
+{seller.phone}
+Môi giới
+ {agent.agency &&{agent.agency}
} + {listing.commissionPct != null && ( +Hoa hồng: {listing.commissionPct}%
+ )} +{listing.viewCount}
+Lượt xem
+{listing.saveCount}
+Lượt lưu
+{listing.inquiryCount}
+Liên hệ
++ Đăng ngày {new Date(listing.publishedAt).toLocaleDateString('vi-VN')} +
+ )} +{label}
+{value}
+{label}
+{value}
+