← back to Homesonspec

apps/web/src/app/communities/[slug]/page.tsx

105 lines

import Link from "next/link";
import { notFound } from "next/navigation";
import { prisma } from "@homesonspec/database";
import { fmtPrice, VerificationBadge } from "@homesonspec/shared-ui";

export const dynamic = "force-dynamic";

export default async function CommunityPage({ params }: { params: Promise<{ slug: string }> }) {
  const { slug } = await params;
  const community = await prisma.community.findUnique({
    where: { slug },
    include: {
      builder: true,
      floorPlans: true,
      salesOffices: true,
      incentives: true,
      homes: { where: { status: "PUBLISHED", isDemo: false }, orderBy: { publishedAt: "desc" } },
    },
  });
  if (!community || community.isDemo) notFound();

  return (
    <div className="mx-auto max-w-6xl px-4 py-8">
      <h1 className="text-3xl font-bold">{community.name}</h1>
      <p className="mt-1 text-neutral-600">
        {community.city}, {community.state} {community.zip} · {community.metro} ·{" "}
        <Link href={`/builders/${community.builder.slug}`} className="text-teal-700 hover:underline">
          {community.builder.name}
        </Link>
      </p>
      <div className="mt-2 flex flex-wrap gap-4 text-sm text-neutral-600">
        {community.priceMin && community.priceMax && (
          <span>From {fmtPrice(Number(community.priceMin))} to {fmtPrice(Number(community.priceMax))}</span>
        )}
        {community.schoolDistrict && <span>School district: {community.schoolDistrict}</span>}
        <span>
          HOA:{" "}
          {community.hoaFeeMonthly ? `$${Number(community.hoaFeeMonthly)}/mo` : community.hoaRequired === false ? "None" : "Not published"}
        </span>
        {community.ageRestricted && <span className="font-medium text-violet-700">Age-restricted community</span>}
      </div>

      {community.incentives.length > 0 && (
        <section className="mt-6">
          <h2 className="text-xl font-semibold">Current offers</h2>
          <ul className="mt-2 grid gap-3 sm:grid-cols-2">
            {community.incentives.map((incentive) => (
              <li key={incentive.id} className="rounded-lg border border-amber-200 bg-amber-50 p-3 text-sm">
                <div className="font-semibold">{incentive.title}</div>
                <div className="mt-1 text-xs text-neutral-500">
                  {incentive.expiresAt ? `Expires ${incentive.expiresAt.toLocaleDateString()}` : incentive.evergreenLabel}
                </div>
              </li>
            ))}
          </ul>
        </section>
      )}

      <section className="mt-8">
        <h2 className="text-xl font-semibold">Available homes ({community.homes.length})</h2>
        <div className="mt-3 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
          {community.homes.map((home) => (
            <Link key={home.id} href={`/homes/${home.id}`}
              className="rounded-xl border border-neutral-200 p-4 shadow-sm hover:border-teal-400">
              <div className="font-semibold">{fmtPrice(home.price === null ? null : Number(home.price))}</div>
              <div className="mt-0.5 text-sm text-neutral-600">{home.street}</div>
              <div className="text-sm text-neutral-500">
                {home.beds ?? "—"} bd · {home.bathsTotal?.toString() ?? "—"} ba · {home.sqft?.toLocaleString() ?? "—"} sqft
              </div>
              <div className="mt-2"><VerificationBadge label={home.verificationLabel} /></div>
            </Link>
          ))}
        </div>
      </section>

      <section className="mt-8">
        <h2 className="text-xl font-semibold">Floor plans</h2>
        <div className="mt-3 grid gap-4 sm:grid-cols-3">
          {community.floorPlans.map((plan) => (
            <Link key={plan.id} href={`/plans/${plan.id}`}
              className="rounded-lg border border-neutral-200 p-3 text-sm hover:border-teal-400">
              <div className="font-semibold">{plan.name}</div>
              <div className="text-neutral-500">
                {plan.beds}–{plan.bedsMax ?? plan.beds} bd · {plan.sqft?.toLocaleString()} sqft · from{" "}
                {fmtPrice(plan.basePrice === null ? null : Number(plan.basePrice))}
              </div>
            </Link>
          ))}
        </div>
      </section>

      {community.salesOffices.length > 0 && (
        <section className="mt-8 text-sm text-neutral-600">
          <h2 className="text-xl font-semibold text-neutral-900">Sales office</h2>
          {community.salesOffices.map((office) => (
            <p key={office.id} className="mt-2">
              {office.street}, {office.city}, {office.state} {office.zip} · {office.phone}
            </p>
          ))}
        </section>
      )}
    </div>
  );
}