"use client"; import { useEffect, useState, type ReactNode } from "react"; import { checkFeatureAccess } from "../adapters"; import { UpgradePrompt } from "./UpgradePrompt"; /** * Feature gate — entitlement API only when featureKey is provided. * Never uses local capability allowlists. Never hides silently. */ export function FeatureLock({ locked: lockedProp, reason: reasonProp, featureKey, tenantId, requiredPlan: requiredPlanProp, requiredCapability: requiredCapabilityProp, requiredBundle: requiredBundleProp, children, fallback, }: { locked?: boolean; reason?: string | null; featureKey?: string; tenantId?: string; requiredPlan?: string | null; requiredCapability?: string | null; requiredBundle?: string | null; children: ReactNode; fallback?: ReactNode; }) { const [prompt, setPrompt] = useState(false); const [entitlementLocked, setEntitlementLocked] = useState(featureKey ? true : Boolean(lockedProp)); const [reason, setReason] = useState(reasonProp); const [requiredPlan, setRequiredPlan] = useState(requiredPlanProp); const [requiredCapability, setRequiredCapability] = useState(requiredCapabilityProp); const [requiredBundle, setRequiredBundle] = useState(requiredBundleProp); useEffect(() => { if (!featureKey || !tenantId) { setEntitlementLocked(Boolean(lockedProp)); setReason(reasonProp); setRequiredPlan(requiredPlanProp); setRequiredCapability(requiredCapabilityProp); setRequiredBundle(requiredBundleProp); return; } let cancelled = false; void checkFeatureAccess(tenantId, featureKey).then((r) => { if (cancelled) return; setEntitlementLocked(!r.has_access); setReason(r.reason || reasonProp); setRequiredPlan(r.required_plan || requiredPlanProp); setRequiredCapability(r.required_capability || requiredCapabilityProp); setRequiredBundle(r.required_bundle || requiredBundleProp); }); return () => { cancelled = true; }; }, [ featureKey, tenantId, lockedProp, reasonProp, requiredPlanProp, requiredCapabilityProp, requiredBundleProp, ]); const locked = featureKey ? entitlementLocked : Boolean(lockedProp); if (!locked) return <>{children}; const promptEl = ( setPrompt(false)} /> ); if (fallback) { return ( <>
setPrompt(true)} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") setPrompt(true); }} > {fallback}
{promptEl} ); } return ( <>
{children}
{promptEl} ); }