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.
This commit is contained in:
Ryan Salazar
2026-05-08 15:03:16 +00:00
parent f1e1d5ea76
commit 7c9d2c8c79
2 changed files with 79 additions and 67 deletions

View File

@@ -1,22 +1,12 @@
import React from "react";
import AppImage from "@/components/ui/AppImage";
import AdSlot from "@/components/AdSlot";
// DO NOT OVERRIDE — Leaderboard ad placeholder layout
export default function LeaderboardAd() {
return (
<div className="bg-ice-blue border-b border-border py-3">
<div className="max-w-container mx-auto px-4 flex justify-center">
{/* Leaderboard ad unit — 728x90 — stub links to advertise page */}
<a href="/advertise" aria-label="Advertisement — click to learn about advertising on BroadcastBeat" className="block">
<AppImage
src="https://img.rocket.new/generatedImages/rocket_gen_img_1bebfd3c7-1765090260606.png"
alt="BroadcastBeat sponsor advertisement banner 728x90"
width={728}
height={90}
className="max-w-full h-auto" />
</a>
<AdSlot zone="homepage-top" size="728x90" />
</div>
</div>);
</div>
);
}

View File

@@ -48,6 +48,7 @@ export default function Header() {
const [searchFocused, setSearchFocused] = useState(false);
const [currentUserId, setCurrentUserId] = useState<string | null>(null);
const [currentUserEmail, setCurrentUserEmail] = useState<string | null>(null);
const [isAdmin, setIsAdmin] = useState(false);
const [subEmail, setSubEmail] = useState("");
const [subStatus, setSubStatus] = useState<"idle" | "loading" | "success" | "error">("idle");
const [subMessage, setSubMessage] = useState("");
@@ -65,14 +66,29 @@ export default function Header() {
useEffect(() => {
const supabase = createClient();
const ADMIN_ROLES = new Set([
"administrator", "admin", "super_admin", "editor", "support",
]);
const refreshAdmin = async (userId: string | null) => {
if (!userId) { setIsAdmin(false); return; }
const { data } = await supabase
.from("user_profiles")
.select("role")
.eq("id", userId)
.maybeSingle();
setIsAdmin(!!data?.role && ADMIN_ROLES.has(data.role));
};
supabase.auth.getUser().then(({ data: { user } }) => {
setCurrentUserId(user?.id || null);
setCurrentUserEmail(user?.email || null);
refreshAdmin(user?.id || null);
});
const supabase2 = createClient();
const { data: { subscription } } = supabase2.auth.onAuthStateChange((_event, session) => {
const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, session) => {
setCurrentUserId(session?.user?.id || null);
setCurrentUserEmail(session?.user?.email || null);
refreshAdmin(session?.user?.id || null);
});
return () => subscription.unsubscribe();
}, []);
@@ -237,48 +253,52 @@ export default function Header() {
My Profile
</Link>
)}
<Link href="/admin/import" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
WP Import
</Link>
<Link href="/admin/articles" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Articles
</Link>
<Link href="/dashboard/editorial" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Editorial
</Link>
<Link href="/admin/users" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Users
</Link>
<Link href="/admin/analytics" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Analytics
</Link>
<Link href="/admin/audit-log" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Audit Log
</Link>
<Link href="/admin/notifications" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Notifications
</Link>
<Link href="/admin/newsletter" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Newsletter
</Link>
<Link href="/admin/forum-seed" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Forum Seed
</Link>
<Link href="/admin/company-tracker" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Company Tracker
</Link>
<Link href="/dashboard/show-calendar" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Show Calendar
</Link>
<Link href="/dashboard/ai-console" className="text-[#3b82f6] hover:text-blue-300 focus:text-blue-300 focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
AI Console
</Link>
<Link href="/admin/banned-terms" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Banned Terms
</Link>
<Link href="/admin" className="text-[#3b82f6] hover:text-blue-300 focus:text-blue-300 focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Dashboard
</Link>
{isAdmin && (
<>
<Link href="/admin/import" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
WP Import
</Link>
<Link href="/admin/articles" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Articles
</Link>
<Link href="/dashboard/editorial" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Editorial
</Link>
<Link href="/admin/users" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Users
</Link>
<Link href="/admin/analytics" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Analytics
</Link>
<Link href="/admin/audit-log" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Audit Log
</Link>
<Link href="/admin/notifications" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Notifications
</Link>
<Link href="/admin/newsletter" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Newsletter
</Link>
<Link href="/admin/forum-seed" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Forum Seed
</Link>
<Link href="/admin/company-tracker" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Company Tracker
</Link>
<Link href="/dashboard/show-calendar" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Show Calendar
</Link>
<Link href="/dashboard/ai-console" className="text-[#3b82f6] hover:text-blue-300 focus:text-blue-300 focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
AI Console
</Link>
<Link href="/admin/banned-terms" className="text-[#999] hover:text-[#3b82f6] focus:text-[#3b82f6] focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Banned Terms
</Link>
<Link href="/admin" className="text-[#3b82f6] hover:text-blue-300 focus:text-blue-300 focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors text-xs font-body font-bold uppercase tracking-wider">
Dashboard
</Link>
</>
)}
{/* Inline Email Subscription Form */}
{subStatus === "success" ? (
<span className="text-[#3b82f6] text-xs font-body font-bold whitespace-nowrap">{subMessage}</span>
@@ -448,15 +468,17 @@ export default function Header() {
Account
</Link>
{/* WP Import mobile link */}
<Link
href="/admin/import"
className="px-2 py-2.5 text-sm font-body font-bold uppercase tracking-wide text-[#cccccc] hover:text-[#3b82f6] hover:bg-[#1a1a1a] border-b border-[#222] transition-colors focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-[#3b82f6] flex items-center gap-2"
onClick={() => setMobileOpen(false)}>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /><polyline points="7 10 12 15 17 10" /><line x1="12" y1="15" x2="12" y2="3" />
</svg>
WP Import
</Link>
{isAdmin && (
<Link
href="/admin/import"
className="px-2 py-2.5 text-sm font-body font-bold uppercase tracking-wide text-[#cccccc] hover:text-[#3b82f6] hover:bg-[#1a1a1a] border-b border-[#222] transition-colors focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-[#3b82f6] flex items-center gap-2"
onClick={() => setMobileOpen(false)}>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /><polyline points="7 10 12 15 17 10" /><line x1="12" y1="15" x2="12" y2="3" />
</svg>
WP Import
</Link>
)}
</div>
<div className="flex flex-col gap-0 border-t border-[#252525] mt-1">
{categoryLinks?.map((link) => (