feat: per-tier feature toggles for recipe variations/pairings (v0.50.0)
Admins can now disable specific AI features per tier from Admin > Tier Limits — new feature_flags table (feature x tier -> enabled, defaulting to true so adding a new gated feature never needs a backfill). Covers recipe variations, drink pairing, and meal pairing to start. When disabled for a user's tier, the button stays visible (with a small lock badge) but opens an upgrade dialog instead of running; the API route rejects the call server-side either way (requireFeatureEnabled, re-reads tier from the DB rather than trusting the session's cache, same rationale as checkAndIncrementTierLimit). The upgrade dialog is informational only — no Stripe checkout exists yet (STRIPE_PLAN.md is still just a plan) — its CTA links to /support prefilled as an upgrade-interest suggestion. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { Sparkles } from "lucide-react";
|
||||
import { buttonVariants } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
} from "@/components/ui/dialog";
|
||||
|
||||
export function UpgradeDialog({
|
||||
open,
|
||||
onOpenChange,
|
||||
featureKey,
|
||||
featureLabel,
|
||||
}: {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
featureKey: string;
|
||||
featureLabel: string;
|
||||
}) {
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-sm">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="flex items-center gap-2">
|
||||
<Sparkles className="h-5 w-5 text-primary" />
|
||||
A Pro feature
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
{featureLabel} is available on the Pro plan (€4.99/mo). Free accounts don't include it.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<DialogFooter className="sm:justify-start">
|
||||
<Link
|
||||
href={`/support?upgrade=${encodeURIComponent(featureKey)}`}
|
||||
className={cn(buttonVariants({ variant: "default" }))}
|
||||
>
|
||||
I'm interested — let us know
|
||||
</Link>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user