← back to Govarbitrage
src/app/b/[slug]/page.tsx
84 lines
import { notFound } from "next/navigation";
import { prisma } from "@/lib/db";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { OfferForm } from "@/components/offer-form";
import { formatMoney, countdown } from "@/lib/utils";
export const dynamic = "force-dynamic";
// Public, compliant buyer-interest page. Contingent only — never represents
// ownership of an item that has not yet been won at auction.
export default async function BuyerPage({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const page = await prisma.buyerInterestPage.findUnique({
where: { slug },
include: { listing: { include: { research: true } } },
});
if (!page || !page.published) notFound();
const l = page.listing;
// Sub-headline is the research summary ONLY — never fall back to
// l.description, which already renders in the Card below (avoids a
// double-description render when no summary exists).
const subHeadline = l.research?.summary ?? null;
return (
<main className="mx-auto max-w-2xl space-y-4 p-5">
{/* 1. Headline leads — legal badge moved down to where it's actionable */}
<h1 className="text-3xl font-semibold tracking-tight">{page.headline}</h1>
{/* 4. Urgency line — only when the listing's closingAt is set */}
{l.closingAt && (
<p className="text-sm font-medium text-warning">
Auction closes{" "}
{new Date(l.closingAt).toLocaleDateString(undefined, {
month: "short",
day: "numeric",
year: "numeric",
})}{" "}
({countdown(l.closingAt)})
</p>
)}
{/* 3. Sub-headline from research summary or listing description */}
{subHeadline && (
<p className="text-sm text-muted-foreground">{subHeadline}</p>
)}
{l.imageUrls[0] && (
// eslint-disable-next-line @next/next/no-img-element
<img src={l.imageUrls[0]} alt={l.title} className="h-64 w-full rounded-lg border object-cover" />
)}
<Card>
<CardHeader>
<CardTitle className="text-foreground">{l.title}</CardTitle>
</CardHeader>
<CardContent className="space-y-2 text-sm">
<p className="text-muted-foreground">{l.description}</p>
{page.estDelivered && (
<p>
Estimated delivered price:{" "}
<span className="font-semibold">{formatMoney(Number(page.estDelivered))}</span>
</p>
)}
<p className="rounded-md bg-muted p-3 text-xs text-muted-foreground">{page.disclaimer}</p>
</CardContent>
</Card>
{/* 2. Contingent badge relocated here — immediately above the form where it's actionable */}
<Badge variant="warning">Contingent interest — not yet owned</Badge>
<Card>
<CardHeader>
<CardTitle className="text-foreground">Register interest (contingent & non-binding)</CardTitle>
</CardHeader>
<CardContent>
<OfferForm listingId={l.id} />
</CardContent>
</Card>
</main>
);
}