feat: self-serve signup Phase 2 (frontend cutover) (#162)
Co-authored-by: Michael Chihlas <michael@resolutionflow.com> Co-committed-by: Michael Chihlas <michael@resolutionflow.com>
This commit was merged in pull request #162.
This commit is contained in:
111
frontend/src/components/common/UpgradePrompt.tsx
Normal file
111
frontend/src/components/common/UpgradePrompt.tsx
Normal file
@@ -0,0 +1,111 @@
|
||||
import { Lock, Sparkles } from 'lucide-react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
interface UpgradePromptProps {
|
||||
feature: string
|
||||
className?: string
|
||||
}
|
||||
|
||||
interface FeatureMeta {
|
||||
/** Display name shown in the prompt heading. */
|
||||
displayName: string
|
||||
/** Plan that unlocks this feature. */
|
||||
requiredPlan: string
|
||||
/** Optional one-line value pitch. */
|
||||
description?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Mapping from feature flag key to display metadata.
|
||||
*
|
||||
* v1: small inline table maintained here. If this grows, lift to
|
||||
* `frontend/src/lib/featureCatalog.ts` and source from a backend endpoint.
|
||||
*
|
||||
* Keys must match `feature_flags.flag_key` on the backend.
|
||||
*/
|
||||
const FEATURE_CATALOG: Record<string, FeatureMeta> = {
|
||||
psa_integration: {
|
||||
displayName: 'PSA Integration',
|
||||
requiredPlan: 'Pro',
|
||||
description: 'Sync tickets and assets with your PSA in real time.',
|
||||
},
|
||||
kb_accelerator: {
|
||||
displayName: 'Knowledge Base Accelerator',
|
||||
requiredPlan: 'Pro',
|
||||
description: 'Auto-generate troubleshooting flows from your existing KB.',
|
||||
},
|
||||
ai_builder: {
|
||||
displayName: 'AI Builder',
|
||||
requiredPlan: 'Pro',
|
||||
description: 'Generate decision trees from natural-language prompts.',
|
||||
},
|
||||
branching_logic: {
|
||||
displayName: 'Branching Logic',
|
||||
requiredPlan: 'Pro',
|
||||
},
|
||||
custom_branding: {
|
||||
displayName: 'Custom Branding',
|
||||
requiredPlan: 'Pro',
|
||||
},
|
||||
api_access: {
|
||||
displayName: 'API Access',
|
||||
requiredPlan: 'Pro',
|
||||
},
|
||||
sso: {
|
||||
displayName: 'Single Sign-On',
|
||||
requiredPlan: 'Enterprise',
|
||||
},
|
||||
}
|
||||
|
||||
/** Humanize an unknown feature key for the fallback display name. */
|
||||
function humanizeFeatureKey(key: string): string {
|
||||
return key
|
||||
.split('_')
|
||||
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
||||
.join(' ')
|
||||
}
|
||||
|
||||
/**
|
||||
* Standardized "this feature is on Pro" affordance.
|
||||
*
|
||||
* Renders a locked panel with a CTA that routes to the plan-selection page.
|
||||
* The actual gating is enforced server-side via `require_feature` — this is UX.
|
||||
*/
|
||||
export function UpgradePrompt({ feature, className }: UpgradePromptProps) {
|
||||
const meta = FEATURE_CATALOG[feature]
|
||||
const displayName = meta?.displayName ?? humanizeFeatureKey(feature)
|
||||
const requiredPlan = meta?.requiredPlan ?? 'Pro'
|
||||
const description = meta?.description
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'flex flex-col items-center justify-center gap-3 rounded-lg border border-default bg-white/[0.04] px-6 py-10 text-center',
|
||||
className,
|
||||
)}
|
||||
data-testid="upgrade-prompt"
|
||||
>
|
||||
<div className="flex h-10 w-10 items-center justify-center rounded-full border border-default bg-elevated text-muted-foreground">
|
||||
<Lock className="h-4 w-4" aria-hidden="true" />
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<h3 className="text-base font-semibold text-heading">
|
||||
{displayName} is available on {requiredPlan}
|
||||
</h3>
|
||||
{description && (
|
||||
<p className="max-w-md text-sm text-muted-foreground">{description}</p>
|
||||
)}
|
||||
</div>
|
||||
<Link
|
||||
to="/account/billing/select-plan"
|
||||
className="inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90"
|
||||
>
|
||||
<Sparkles className="h-4 w-4" aria-hidden="true" />
|
||||
Upgrade to {requiredPlan}
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default UpgradePrompt
|
||||
Reference in New Issue
Block a user