Adds <AdSlot zone size /> server component that renders a labeled
placeholder for now (size + zone exposed as data attrs for the future
bb.ad_placements lookup).
Inserted on news/[slug] article template:
- 728×90 leaderboard above the <article>
- 300×600 half-page at top of sidebar
- 300×250 mid-rectangle in sidebar (replaces the old hand-rolled
placeholder div)
- 728×90 leaderboard below the </article>, before related-articles
Same scheme should be applied to articles/[slug]/page.tsx in a follow-up
once that template's body is finalized.
Drops the rendered date span from:
- ArticleFeed.tsx (homepage feed)
- news/page.tsx (news list — also drops the orphan separator)
- news/[slug]/NewsArticleDetailClient.tsx (article header + related-articles row, drops paired separators)
- AISuggestedArticles.tsx (sidebar — keeps readTime alone)
JSON-LD datePublished/publishedTime in news/[slug]/page.tsx and
articles/[slug]/page.tsx is unchanged so search engines still see the
publication date.
src/lib/legacy-image.ts exports rewriteLegacyImageUrl(url) and
rewriteLegacyImageUrlsInHtml(html) which translate WP origin URLs
(https://www.broadcastbeat.com/wp-content/uploads/...) to local paths
under /legacy/... served from the new persistent storage volume mounted
at /app/public/legacy/.
src/lib/legacy-image-map.json holds 3,856 URL→path entries built in
Phase 2: 3,839 featured images (mostly converted to webp, q=85) plus
27 ad creatives plus the site logo.
Use this helper at server-render time when emitting <img>/<Image> for
imported WP articles, so the 707 MB on-host cache replaces external
fetches to the origin.
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.