/** * Server-side listing data fetching for Next.js Server Components. * * This module uses `fetch` directly (no browser-only helpers) so it can run * inside `generateMetadata`, `generateStaticParams`, `sitemap()`, etc. */ import type { ListingDetail, PaginatedResult } from './listings-api'; const API_BASE_URL = process.env['NEXT_PUBLIC_API_URL'] || 'http://localhost:3001/api/v1'; /** * Fetch a single listing by ID — server-only. * Returns `null` when the listing is not found (404) so callers can `notFound()`. */ export async function fetchListingById(id: string): Promise { try { const res = await fetch(`${API_BASE_URL}/listings/${id}`, { // Listing detail includes mutable status, price, legal and moderation data. // Avoid serving stale details after admin/user actions. cache: 'no-store', }); if (!res.ok) return null; return (await res.json()) as ListingDetail; } catch { return null; } } /** * Fetch active listings — server-only, used by the dynamic sitemap. */ export async function fetchActiveListings(params: { page?: number; limit?: number; }): Promise> { const query = new URLSearchParams({ status: 'ACTIVE', page: String(params.page ?? 1), limit: String(params.limit ?? 100), }); const res = await fetch(`${API_BASE_URL}/listings?${query}`, { next: { revalidate: 3600 }, // re-validate every hour for sitemap }); if (!res.ok) { return { data: [], total: 0, page: 1, limit: 100, totalPages: 0 }; } return (await res.json()) as PaginatedResult; }