Skip to content

Commit 7e03e05

Browse files
Sbussisoclaude
andcommitted
Show PRO badge on Admin nav link for free tier users
Instead of hiding the Admin link entirely, show it with a small blue "PRO" badge so free users know the feature exists but requires an upgrade. Clicking it still shows the full upgrade prompt. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 30c1660 commit 7e03e05

2 files changed

Lines changed: 48 additions & 4 deletions

File tree

frontend/src/components/Layout.jsx

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,33 @@
11
import { Outlet, Link, useLocation } from "react-router-dom"
2-
import { SignedIn, SignedOut, UserButton, OrganizationSwitcher, useOrganization } from "@clerk/clerk-react"
2+
import { SignedIn, SignedOut, UserButton, OrganizationSwitcher, useOrganization, useAuth } from "@clerk/clerk-react"
3+
import { useState, useEffect } from "react"
4+
import { getPlanInfo } from "../services/api"
35
import ToastContainer from "./ToastContainer.jsx"
46

57
function Layout() {
68
const { organization, isLoaded: orgLoaded, membership } = useOrganization()
9+
const { getToken } = useAuth()
710
const location = useLocation()
11+
const [planFeatures, setPlanFeatures] = useState([])
812

913
const isAdmin = orgLoaded && membership?.role === "org:admin"
14+
const hasAdminFeature = planFeatures.includes("admin")
15+
16+
useEffect(() => {
17+
if (organization && isAdmin) {
18+
loadPlanFeatures()
19+
}
20+
}, [organization])
21+
22+
const loadPlanFeatures = async () => {
23+
try {
24+
const token = await getToken()
25+
const data = await getPlanInfo(() => Promise.resolve(token))
26+
setPlanFeatures(data.features || [])
27+
} catch (err) {
28+
// Silently fail — nav still works, just hides admin link
29+
}
30+
}
1031

1132
const isActive = (path) => location.pathname === path ? "nav-link active" : "nav-link"
1233

@@ -42,9 +63,16 @@ function Layout() {
4263
<Link to="/settings" className={isActive("/settings")}>
4364
Settings
4465
</Link>
45-
<Link to="/admin" className={isActive("/admin")}>
46-
Admin
47-
</Link>
66+
{hasAdminFeature ? (
67+
<Link to="/admin" className={isActive("/admin")}>
68+
Admin
69+
</Link>
70+
) : (
71+
<Link to="/admin" className={`${isActive("/admin")} nav-link-locked`}>
72+
Admin
73+
<span className="nav-pro-badge">PRO</span>
74+
</Link>
75+
)}
4876
</>
4977
)}
5078
<Link to="/pricing" className={isActive("/pricing")}>

frontend/src/index.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,22 @@ body {
11401140
color: var(--accent-green);
11411141
}
11421142

1143+
.nav-link-locked {
1144+
opacity: 0.7;
1145+
gap: 4px;
1146+
}
1147+
1148+
.nav-pro-badge {
1149+
font-size: 0.55rem;
1150+
font-weight: 700;
1151+
letter-spacing: 0.05em;
1152+
padding: 1px 4px;
1153+
border-radius: 3px;
1154+
background: rgba(59, 130, 246, 0.2);
1155+
color: #60a5fa;
1156+
line-height: 1;
1157+
}
1158+
11431159
/* Dev Mode Badge */
11441160
.dev-mode-badge {
11451161
display: flex;

0 commit comments

Comments
 (0)