cross-link: forum auto-link, NAB hub, sponsor strip, recent stories

Feature 3 — forum auto-linking
  Thread + reply bodies in /forum/thread/[id] now wrap company-name
  mentions with /manufacturers/<slug> links via a new client-side
  LinkifyPlainText component. Loads the directory list once per page
  (module-level promise cache), regex-scans each body, preserves
  whitespace, caps at 10 links per body to avoid clutter.
  CompanyMentionsHover mounted on the page so the same preview card
  pops on hover.
  Adds /api/public/companies/list — minimal { name, slug } directory
  feed, cached 10min.

Feature 4 — /nab-2026 live coverage hub
  New page aggregating every directory company with exhibits_nab=true.
  Three sections:
    - Coverage Partners — active advertisers exhibiting at NAB, larger
      tiles with emerald Sponsor border
    - Latest from the show floor — last 60 days of articles with NAB
      in the title, cinematic grid
    - All NAB 2026 exhibitors — alphabetical, capped at 200 with link
      to full /manufacturers directory
  Every company tile carries data-company-slug for hover previews.

Feature 5b — Sponsor logo strip on homepage
  New SponsorLogoStrip server component renders just above the footer
  on the homepage, showing logos of every current banner advertiser
  with a directory entry + logo. Each links to the manufacturer
  profile with the hover-card slug attribute.

Feature 5c — Recent coverage on manufacturer profiles
  /manufacturers/[slug] now includes a grid of the 6 most recent
  articles matching the company name in the title, with thumbnails.
  Renames the existing manufacturer_id-linked block to "Press
  releases" since it's a separate data source.
This commit is contained in:
Ryan Salazar
2026-05-27 12:55:25 +00:00
parent a59846a524
commit 2e78726291
7 changed files with 552 additions and 4 deletions

View File

@@ -8,6 +8,8 @@ import AdImage from '@/components/AdImage';
import { ADS_300X250, rotateAll } from '@/lib/ads';
import { createClient } from '@/lib/supabase/client';
import SidebarAdStack from "@/components/SidebarAdStack";
import LinkifyPlainText from "@/components/LinkifyPlainText";
import CompanyMentionsHover from "@/components/CompanyMentionsHover";
// Inline ad slot inserted between forum replies every N posts.
function InThreadAd({ adIndex }: { adIndex: number }) {
@@ -368,7 +370,9 @@ export default function ForumThreadPage() {
<span className="text-[#555] font-body text-xs">·</span>
<span className="text-[#555] font-body text-xs">{thread.view_count} views</span>
</div>
<p className="text-[#d0d0d0] font-body text-sm leading-relaxed whitespace-pre-wrap">{thread.body}</p>
<p className="text-[#d0d0d0] font-body text-sm leading-relaxed">
<LinkifyPlainText body={thread.body} />
</p>
<VoteButtons
targetType="thread"
targetId={thread.id}
@@ -408,7 +412,9 @@ export default function ForumThreadPage() {
<span className="text-[#555] font-body text-xs">·</span>
<span className="text-[#555] font-body text-xs">{timeAgo(reply.created_at)}</span>
</div>
<p className="text-[#d0d0d0] font-body text-sm leading-relaxed whitespace-pre-wrap">{reply.body}</p>
<p className="text-[#d0d0d0] font-body text-sm leading-relaxed">
<LinkifyPlainText body={reply.body} />
</p>
<VoteButtons
targetType="reply"
targetId={reply.id}
@@ -537,6 +543,7 @@ export default function ForumThreadPage() {
</div>
</main>
<Footer />
<CompanyMentionsHover />
</>
);
}