Files
Magent/frontend/app/ui/FeatureGate.tsx
T
Assclaw ec0a866ef3
Magent CI/CD / verify (push) Canceled after 1m19s
Magent CI/CD / deploy-prod (push) Canceled after 0s
Magent CI/CD / deploy-beta (push) Canceled after 0s
Add user feature permissions and unified account management
2026-09-11 12:31:25 +12:00

38 lines
1.7 KiB
TypeScript

'use client'
import { usePathname } from 'next/navigation'
import { useEffect, useState, type ReactNode } from 'react'
import { authFetch, getApiBase, getToken } from '../lib/auth'
import { canAccess, featureForPath, type FeatureAccess } from '../lib/features'
export function useFeatureUser() {
const pathname = usePathname()
const [state, setState] = useState<{ path: string; user: { role?: string; features?: FeatureAccess; invite_management_enabled?: boolean } | null }>({ path: '', user: null })
useEffect(() => {
let active = true
const load = async () => {
if (!getToken()) { if (active) setState({ path: pathname, user: null }); return }
try {
const response = await authFetch(`${getApiBase()}/auth/me`)
const user = response.ok ? await response.json() : null
if (active) setState({ path: pathname, user })
} catch { if (active) setState({ path: pathname, user: null }) }
}
void load()
window.addEventListener('focus', load)
return () => { active = false; window.removeEventListener('focus', load) }
}, [pathname])
return { user: state.user, ready: state.path === pathname }
}
export default function FeatureGate({ children }: { children: ReactNode }) {
const pathname = usePathname()
const { user, ready } = useFeatureUser()
const feature = featureForPath(pathname)
if (!feature) return children
if (!ready) return <main className="card">Loading account access...</main>
if (!getToken()) return children
if (!canAccess(user, feature)) return <main className="card"><h1>Feature unavailable</h1><p>Your account does not have access to this feature. Ask an administrator if you need it enabled.</p><a href="/profile">Go to my profile</a></main>
return children
}