[object Object]

← back to Homesonspec

Add live national map to homepage hero (loads on page load) + fix stale demo copy

13c6b8379290767aa7bc282e095b87387b8dee43 · 2026-07-22 16:57:40 -0700 · Steve Abrams

Files touched

Diff

commit 13c6b8379290767aa7bc282e095b87387b8dee43
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Jul 22 16:57:40 2026 -0700

    Add live national map to homepage hero (loads on page load) + fix stale demo copy
---
 apps/web/src/app/HeroMap.tsx | 24 ++++++++++++++++++++++++
 apps/web/src/app/page.tsx    | 44 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/apps/web/src/app/HeroMap.tsx b/apps/web/src/app/HeroMap.tsx
new file mode 100644
index 0000000..efcafb7
--- /dev/null
+++ b/apps/web/src/app/HeroMap.tsx
@@ -0,0 +1,24 @@
+"use client";
+
+import dynamic from "next/dynamic";
+import type { MapMarker } from "@spechomes/shared-ui/src/MapView";
+
+// Leaflet needs window — client-only load, direct file import (not the barrel),
+// matching the search page. Renders on mount, so the hero map is live on page load.
+const MapView = dynamic(() => import("@spechomes/shared-ui/src/MapView").then((m) => m.MapView), {
+  ssr: false,
+  loading: () => (
+    <div className="flex h-full w-full items-center justify-center bg-teal-950/40 text-sm text-teal-100">
+      Loading map…
+    </div>
+  ),
+});
+
+/**
+ * Hero map — plots every community with live inventory across the country.
+ * Auto-fits to the full marker set (MapView.FitMarkers), so it opens showing
+ * the whole national footprint the moment the page loads.
+ */
+export default function HeroMap({ markers }: { markers: MapMarker[] }) {
+  return <MapView markers={markers} center={[39.5, -98.35]} zoom={4} />;
+}
diff --git a/apps/web/src/app/page.tsx b/apps/web/src/app/page.tsx
index 8ec1fa5..87e80e8 100644
--- a/apps/web/src/app/page.tsx
+++ b/apps/web/src/app/page.tsx
@@ -1,5 +1,6 @@
 import Link from "next/link";
 import { prisma } from "@spechomes/database";
+import HeroMap from "./HeroMap";
 
 export const dynamic = "force-dynamic";
 
@@ -12,6 +13,36 @@ export default async function HomePage() {
   const homeCount = await prisma.inventoryHome.count({ where: { status: "PUBLISHED", isDemo: false } });
   const builderCount = await prisma.builder.count({ where: { isDemo: false } });
 
+  // Community markers for the hero map — one point per community with live
+  // inventory (capped for a fast first paint). Convert Decimal lat/lon to plain
+  // numbers before crossing the server→client boundary.
+  const mapCommunities = await prisma.community.findMany({
+    where: {
+      isDemo: false,
+      lat: { not: null },
+      lon: { not: null },
+      homes: { some: { status: "PUBLISHED", isDemo: false } },
+    },
+    select: {
+      id: true,
+      name: true,
+      slug: true,
+      lat: true,
+      lon: true,
+      _count: { select: { homes: { where: { status: "PUBLISHED", isDemo: false } } } },
+    },
+    orderBy: { homes: { _count: "desc" } },
+    take: 800,
+  });
+  const heroMarkers = mapCommunities.map((c) => ({
+    id: c.id,
+    lat: Number(c.lat),
+    lon: Number(c.lon),
+    label: c.name,
+    sublabel: `${c._count.homes} home${c._count.homes === 1 ? "" : "s"}`,
+    href: `/communities/${c.slug}`,
+  }));
+
   return (
     <div>
       <section className="bg-gradient-to-b from-teal-900 to-teal-700 px-4 py-20 text-white">
@@ -43,7 +74,18 @@ export default async function HomePage() {
             </button>
           </form>
           <p className="mt-4 text-sm text-teal-200">
-            {homeCount} verified demonstration homes · {builderCount} builders · {markets.length} metros
+            {homeCount.toLocaleString()} verified homes · {builderCount} builders · {markets.length} metros
+          </p>
+        </div>
+
+        {/* Live national map — loads on page load, one marker per community with
+            available inventory; click a marker to open that community. */}
+        <div className="mx-auto mt-10 max-w-6xl">
+          <div className="h-[420px] w-full overflow-hidden rounded-2xl border border-teal-600/40 shadow-2xl" data-testid="hero-map">
+            <HeroMap markers={heroMarkers} />
+          </div>
+          <p className="mt-2 text-center text-xs text-teal-200/80">
+            Every marker is a community with live, verified inventory. Explore the map or search above.
           </p>
         </div>
       </section>

← ab1a330 auto-save: 2026-07-22T14:44:58 (1 files) — cert-homesonspec.  ·  back to Homesonspec  ·  Add robust map explorer (/map): 12k canvas markers, per-fiel bbbcbc6 →