← 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 &amp; non-binding)</CardTitle>
        </CardHeader>
        <CardContent>
          <OfferForm listingId={l.id} />
        </CardContent>
      </Card>
    </main>
  );
}