Commit Graph

22 Commits

Author SHA1 Message Date
Ryan Salazar
418027b469 search: real autocomplete previews + clearer placeholder
PLACEHOLDER: "Search broadcast news…" → "Search articles, gear,
vendors". Drops the weird ellipsis and the "we're a broadcast site
so 'broadcast news' is redundant" feel.

API (/api/search/suggest):
- Match expanded from {title, author_name} to
  {title, excerpt, content, author_name} — surfaces hits when the
  phrase lives deep in the article body.
- Returns a snippet object {text, matchStart, matchEnd} sliced
  from the first hit (HTML-stripped), with ~80 chars of context on
  either side and "…" markers when truncated.
- Returns matched_in: 'title' | 'excerpt' | 'content' | 'author' so
  the UI can show "match in article body" / "match in byline".
- Returns date + author_name on each result.

UI dropdown (Header.tsx):
- Each suggestion now renders three rows:
  1) Title (bold) + category chip
  2) Snippet with the matched substring wrapped in <mark>
  3) Author byline + date + (if match wasn't in title) a tag
     showing where the match occurred
- Vertical stacking with a colored left-border on hover so the
  active suggestion is visible.

CSS:
- Stack item layout, snippet with -webkit-line-clamp:2 so long
  matches don't overflow.
- <mark> background uses the accent blue at 28% so the highlight
  reads against the dark card.
2026-05-20 16:22:04 +00:00
Ryan Salazar
cb00f7f343 search: return all matches (not just 100) + add typeahead autocomplete
- searchLegacyArticles() default limit: 50 → 5000. /search page
    explicitly passes 5000 too. ilike on title/excerpt/author is fast
    enough on the 29k-row archive that returning everything is fine.

  - New API route /api/search/suggest?q=...&limit=8 returns the top
    matching article titles + category + slug, with a 30-second CDN
    cache + 60-second stale-while-revalidate.

  - The search input in the Browse bar now debounces (150ms) and
    fires that API per keystroke once 2+ chars are typed. Matches
    appear in a styled dropdown below the input — click to navigate
    directly to /news/<slug>, or press Enter to fall through to the
    full /search page. "See all results for …" link in the dropdown
    footer.

  - Keyboard: Escape closes the dropdown; aria-autocomplete + role
    listbox/option for accessibility.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 06:00:10 +00:00
Ryan Salazar
c5d4c1d075 header/footer chrome polish: logo in footer, search in NAV bar, NAV bar restyle
- Footer bottom: replace the plain "Broadcast Beat" text wordmark
    with the same logo image used in the top-left header (so footer
    matches header brand mark).

  - Move the site-wide search input out of the top sticky row and
    into the Browse bar that sits below the 728x90 leaderboard. Top
    row is now just logo / reading-list / notification bell.

  - Browse bar redesign for personality + alignment:
      * 48px tall, dark navy gradient with a 2px accent-blue bottom
        border and a horizontal sheen across the top edge
      * Search input (pill shape, focus-glow ring) sits flush left
      * Menu items (Events ▾, Newsletter, Forum, About ▾) are now
        right-aligned via flex justify-between
      * Each menu item is uppercase + tracked, hover lights an
        accent-blue underline that scales in from the left
      * EventsDropdown and AboutDropdown buttons now use the same
        .bb-browse-item class — fixes the vertical alignment issue
        where they were rendering at the old 60px nav-link-bb height
        while the new bar is 48px.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 05:40:04 +00:00
Ryan Salazar
8e7e152422 header: move primary nav to a Browse bar below the 728x90 leaderboard
The main sticky top row now holds only the logo, Reading List icon,
notification bell, and search box. The Events dropdown, navLinks
(Newsletter, Forum), and About dropdown were lifted out of the top
row and re-rendered in a new "Browse bar" that sits directly below
the header leaderboard banner.

Visual result:
  [ top utility bar (account / admin) ]
  [ logo                          📑 🔔 🔍 ]
  [ 728x90 leaderboard ]
  [ Events ▾  Newsletter  Forum  About ▾ ]   ← new Browse bar
  [ LIVE WIRE ····                       ]
  [ RECENT FORUM POSTS ····              ]

The mobile hamburger drawer is unchanged — it already keeps all the
nav items consolidated for small screens.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 23:08:05 +00:00
broadcastbeat-rename
0db3ea34e3 Replace 'BroadcastBeat' with 'Broadcast Beat' in all user-visible text (133 occurrences across 40+ files) 2026-05-16 00:32:13 +00:00
959e3980ae Revert "slice 4: accent palette refinement — blue → teal"
This reverts commit 52fe7bceb6.
2026-05-15 23:49:36 +00:00
52fe7bceb6 slice 4: accent palette refinement — blue → teal
Replace the four accent-family hex codes site-wide with the teal palette
(keeps the dark theme; only swaps the accent family, not the dark base):

  #3b82f6 (accent primary CTA)   → #5B7C8D  (teal)        [839×]
  #2563eb (accent-dark / hover)  → #4A6473  (darker teal) [44×]
  #60a5fa (info link, lighter)   → #8FB0C3  (mid teal)    [68×]
  #1e3a5f (accent-muted bg)      → #2F4F5F  (navy)        [44×]

tailwind.config.js tokens updated to match (accent/accent-dark/accent-muted).
Sweep also covers tailwind.css. 108 files touched. The dark base (#0d0d0d,
#111, #161616, #1a1a1a etc.) is intentionally untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:33:04 +00:00
a240133ec7 slice 1+2: header social URLs, drop TwitterX/Press Kit, wrap About/Team/PressKit, add /newsletter + /rss
- Header.tsx: bare linkedin/instagram/facebook URLs → /broadcastbeat handles; remove TwitterXIcon from social bar + import (Footer retains TwitterXIcon per "DO NOT OVERRIDE" marker)
- AboutDropdown.tsx: drop "Press kit" item (the page itself stays at /about/press-kit, just delisted from menu)
- SystemStatusBar.tsx: remove "Index online" pulse-dot and "N wire sources" span (keep articles count + events count + build version)
- /about, /about/team, /about/press-kit: wrap in Header+Footer (previously rendered bare <main>)
- /newsletter/page.tsx (new): redirect to /newsletter/archive — Header was 404'ing on /newsletter
- /rss/route.ts (new): dynamic RSS feed reading from legacy-source news section; replaces 404 at /rss

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 21:49:34 +00:00
Claude (Phase B)
a785ef428e BB AI redesign: 4-item nav, Show coverage, About, status bar, wire ticker,
trends sidebar, Ask BB AI, neural-summary schema, 13-event seed.

Phases 1-10 (11 phases minus Phase 8 which is the pgvector marker).

DB:
  bb.events                — 13 industry events seeded (MPTS, ANGA COM,
                             BroadcastAsia, SET Expo, IBC, NAB NY,
                             NewTECHForum, SATIS, DPP EBS, SVVS,
                             Hamburg Open, CABSAT, NAB Show '27).
  bb.article_events        — composite PK (article_id, article_table, event_id)
                             links any article-table row to one or more events.
  bb.banner_creatives      — (no change tonight)
  bb.{native_articles,
      ai_rewritten_articles,
      wp_imported_posts,
      press_releases}.neural_summary jsonb — populated by Phase 7
                             analyzer (deferred).
  bb.{native_articles,
      ai_rewritten_articles}.featured boolean — featured carousel source.

Routes:
  /api/events/upcoming     — date-gated, enriched with is_live/days_until/
                             day_of_event/total_days.
  /api/ask-bb-ai           — Claude Opus 4.7 chat with prompt caching on
                             the system block, 30-msg/hr/IP rate limit.
                             Tool-use deferred — first cut is straight
                             LLM with archive-citation prompting.

Pages:
  /show-coverage           — index of all events, upcoming + past split.
  /show-coverage/[slug]    — hero + status (live/T-Nd/past) + schema.org
                             Event JSON-LD + tagged articles list.
  /about, /about/{team,contact,advertise,press-kit}.

Components:
  Header                   — 4-item nav: Show coverage (dropdown) /
                             Newsletter / Forum / About (dropdown).
                             Old NEWS/GEAR/TECHNOLOGY/ADVERTISE items
                             removed from nav (routes still exist).
  EventsDropdown           — 340px CSI panel with L-corner brackets,
                             pulsing dot, "BB AI" badge, live/T-Nd rows,
                             auto-updated stamp.
  AboutDropdown            — 5-item lighter treatment.
  SystemStatusBar          — Index online pulse, articles/sources/events
                             counts, build version. Above Header.
  LiveWireTicker           — replaces NewsTicker. [HH:MM] [SRC] prefix,
                             CSS marquee, doubled for seamless loop.
  TrendsSidebar            — BB AI detected trends, top 5 entities by
                             7d-vs-30d lift, vector-pass stamp.
                             Phase 6b: replace with pgvector.
  AskBBAI                  — floating bottom-right button + 420px right
                             drawer chat. No mention of Anthropic/Claude.

Styling:
  redesign-tokens.css      — --color-text-info, --color-background-*,
                             --font-serif/mono/body, bb-pulse/bb-ring
                             animations + bb-marquee.

Constraints honored:
  - LiveU 728x90 still between </nav> and ticker.
  - Blackmagic 300x600 still pinned top of sidebar.
  - /r/[slug] click tracking unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 02:22:23 +00:00
Claude Code
8a2ca37134 remove broken auth UI from header; PR firms now authenticate at distribute platform
- Header.tsx: remove "SIGN IN" and "REGISTER" buttons from the top
  utility bar and the mobile drawer. Auth for PR firms / writers lives
  at distribution.relevantmediaproperties.com now; the local /client-login
  and /register routes are no longer the right entry point.
- src/middleware.ts (new): 301-redirect /wp-login, /wp-login.php,
  /wp-admin, /wp-admin/*, /login, /client-login, and /register to
  https://distribution.relevantmediaproperties.com/login so existing
  bookmarks and old WP-era links land somewhere useful instead of 404.
- Newsletter signup form, social icons, country selector all retained.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 17:51:24 +00:00
Claude Code
8be2ccbff2 Deploy-1 fix + P0-6/7/8: Suspense wrap, carousel arrows, banner reposition, search-box removal
Deploy-1 build failed because NewsPageClient now calls useSearchParams.
- src/app/news/page.tsx: wrap NewsPageClient in <Suspense> so static
  generation can bail out to client rendering cleanly.

P0-6 (Featured carousel arrows):
- FeaturedBento: brighten arrow buttons (text-[#ccc] over bg-[#1a1a1a]
  with #3a3a3a border; previously near-invisible #666 over the same
  background), enlarge to w-8 h-8, hover fills to blue. Wrap the
  arrow group with role/aria + Left/Right keyboard nav.

P0-7 (728x90 reposition):
- Header: move the leaderboard block from above the main nav to AFTER
  the sticky nav, so it sits between the nav and The Beat ticker.

P0-8 (remove Latest search box):
- ArticleFeed: drop the in-section search input + clear button. The
  top-right header search is now the sole search UI. searchQuery state
  remains since the active-filter chip code still references it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 16:39:24 +00:00
Claude Code
70e2aebb83 P0-3/4/5: route error boundary, null guards, slug fallback, search
P0-3 (category page crash):
- Add src/app/error.tsx and src/app/global-error.tsx so any future render
  error shows a real ref id instead of the bare client-exception toast.
- NewsPageClient: null-guard every field accessed during search/category/
  sort filtering and article render (title, excerpt, author, tags,
  category, date, image, alt). The user-visible link
  /news?category=live-production now also hydrates filter state from
  ?category= and ?search= search-params, so the dropdown actually filters.

P0-4 (/articles/[slug] 404s):
- /articles/[slug] and /news/[slug]: on slug miss, redirect("/news")
  instead of notFound(). Dead links from the hardcoded NewsTicker /
  FeaturedBento / ArticleFeed arrays now land on the news index instead
  of dead-ending on 404.
- legacy-source: add searchLegacyArticles() (title/excerpt/author ilike).

P0-5 (header search):
- Header: wire Enter on the desktop and mobile search inputs and make
  both search icons clickable buttons. Submits to /search?q=<query>.
- New /search route: server component that runs searchLegacyArticles
  and renders results in the same card style as /news.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 16:35:24 +00:00
Claude Code
146b7259d4 wip-banner-system: real ads, logo fix, remove duplicate banner, clean footer
- Remove duplicate 728x90 LeaderboardAd below news ticker (per Ryan)
- Footer: remove NAB Official Media Partner badge
- Header: replace AdSlot stub with real AdImage rotation (3 verified 728x90s)
- Header: fix logo path from dead WP URL to local /assets/images/logo.png
- ads.ts: only include ads with verified real images (3x728x90, 2x300x250)
- ads.ts: remove 22 unrecovered ads — see PENDING_ads.md for upload list
- SidebarAdStack: handle null FIXED_300X600 gracefully (Blackmagic not recovered)
- public/legacy/ads/: 5 real ad images committed (Tower, Sony, LiveU 728x90; LiveU PAYG, Telycam 300x250)
- public/assets/images/logo.png: recovered from Wayback Machine

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 12:23:22 +00:00
Ryan Salazar
aec6d0c43d Header: also rename mobile drawer 'My Account' to 'My Profile' (parity with desktop) 2026-05-10 14:48:48 +00:00
Ryan Salazar
1ca5ca108a Header: consolidate My Account/Profile into one link; group 9 admin tools into TOOLS dropdown
Top-bar nav changes:
- Authenticated user previously saw two separate links 'My Account' (-> /account)
  and 'My Profile' (-> /profile/{userId}). Replaced with a single 'My Profile'
  link -> /account.
- Admin block previously rendered 14 inline links (WP Import, Articles, Editorial,
  Users, Analytics, Audit Log, Notifications, Newsletter, Forum Seed, Company
  Tracker, Show Calendar, AI Console, Banned Terms, Dashboard) which sprawled
  horizontally past the available width. 9 of those are now grouped under a
  single TOOLS hover dropdown matching the existing NEWS/GEAR/SHOW
  COVERAGE/TECHNOLOGY pattern (Tailwind group-hover + group-focus-within for
  keyboard accessibility, role=menu / menuitem, aria-haspopup=true).
- Inline admin links retained per spec: WP Import, Articles, Editorial,
  Newsletter.
- TOOLS submenu: Users, Analytics, Audit Log, Notifications, Forum Seed,
  Company Tracker, Show Calendar, AI Console, Banned Terms.

The whole admin tier (inline + dropdown) remains gated by the existing isAdmin
check, so anonymous and non-admin users see nothing.
2026-05-10 14:41:46 +00:00
Ryan Salazar
0674d0188b Header redesign: dropdowns + site-wide leaderboard, drop secondary nav
Reorganize the navigation:
- navLinks now carries an optional dropdown[] per section. NEWS / GEAR &
  REVIEWS / SHOW COVERAGE / TECHNOLOGY get sub-items pulled from the old
  flat categoryLinks list.
- Desktop main nav renders each top-level item as a hover-triggered
  dropdown (CSS-only via Tailwind group-hover + group-focus-within for
  keyboard accessibility). aria-haspopup advertises the popup; the panel
  is role=menu with menuitem children.
- Mobile drawer's category list now groups by parent section instead of
  showing a flat list.
- Removed the secondary category sub-nav row that previously sat below
  the main nav (its content is in the dropdowns now).
- Added a site-wide 728x90 ad slot between the top utility bar and the
  main nav (md+ only). Uses <AdSlot zone='homepage-top'> so the existing
  ad-rotation pool serves it.

Net: 566 → ~600 lines (markup heavier than what was removed because the
dropdown panels are inline).
2026-05-08 22:25:47 +00:00
Ryan Salazar
e544ddccd1 update homepage tagline to 'News & Intelligence for Broadcast, Post-Production & Streaming Technology' 2026-05-08 21:06:49 +00:00
Ryan Salazar
c642b4deb5 Header: split Sign In / My Account by auth state, route Sign In to /client-login
Desktop nav (and mobile drawer) now show different account-related
links depending on auth state:

- Anonymous: Sign In (-> /client-login) + Register
- Authenticated: My Account + My Profile
- Admin-tier (administrator/admin/super_admin/editor/support): plus the
  full admin block (already gated by isAdmin from earlier commit)

Previously a single 'Sign In / My Account' link pointed at /account
regardless of auth state, which forced anonymous users through a
server-side bounce to the login page. Now Sign In links straight to the
canonical /client-login.
2026-05-08 21:05:32 +00:00
Ryan Salazar
7c9d2c8c79 remove rocket.new leaderboard banner; re-add admin nav guard
- src/app/home-page/components/LeaderboardAd.tsx: drop the hardcoded
  img.rocket.new image (rocket_gen_img_1bebfd3c7) at the top of the
  homepage. Replaced with <AdSlot zone='homepage-top' size='728x90' />
  to keep the slot for the eventual ad-server wiring while removing the
  rocket.new dependency entirely.
- src/components/Header.tsx: re-add the isAdmin gate that was reverted
  in 0d51dad. Reads bb.user_profiles.role and only renders the desktop
  admin nav block (WP Import, Articles, Editorial, Users, Analytics,
  Audit Log, Notifications, Newsletter, Forum Seed, Company Tracker,
  Show Calendar, AI Console, Banned Terms, Dashboard) and the mobile WP
  Import link when role is in (administrator, admin, super_admin,
  editor, support). 'support' is admin-tier per the new RBAC matrix.
  Page-level auth checks on each /admin/* route remain authoritative;
  this only suppresses menu visibility for non-admin/anonymous.
2026-05-08 15:03:16 +00:00
Ryan Salazar
0d51dade6e Revert "hide admin nav links unless user has admin role"
This reverts commit 92a256bbe0.
2026-05-07 22:50:35 +00:00
Ryan Salazar
92a256bbe0 hide admin nav links unless user has admin role
Header was rendering all admin links unconditionally to every visitor
(including unauthenticated). Add an isAdmin state derived from
user_profiles.role (administrator|admin|super_admin) and wrap both the
desktop admin block and the mobile WP Import link in the guard.

Note: page-level auth checks on each /admin/* route remain authoritative;
this only suppresses menu visibility.
2026-05-07 22:25:33 +00:00
Ryan Salazar
70aa1ad46e initial commit: rocket.new export of broadcastbeat 2026-05-07 16:39:17 +00:00