fix: standardize locked-vs-hidden treatment across all 9 per-tier gated features (v0.79.0)
Rule, applied consistently everywhere via a new isFeatureAvailableAnyTier() helper: if a feature is enabled on at least one tier, it stays visible for locked-out viewers with a small "Pro" badge and opens an upgrade prompt on click; if a feature is disabled on every tier, it hides entirely, since there's no upgrade path to point at. Covers: recipe variations, meal/drink pairings, nutrition estimation, Markdown export (5 call sites), weekly nutrition, import from URL, import from photo, and the Instacart grocery-delivery menu item. Previously inconsistent — some hid outright, one showed a lock icon overlapping its own icon. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,16 +7,23 @@ import { Camera, Loader2 } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { FakeProgressBar } from "@/components/ui/fake-progress-bar";
|
||||
import { UpgradeDialog } from "@/components/premium/upgrade-dialog";
|
||||
import { ProBadge } from "@/components/premium/pro-badge";
|
||||
|
||||
export function PhotoImportButton() {
|
||||
export function PhotoImportButton({ locked = false }: { locked?: boolean }) {
|
||||
const t = useTranslations("recipe");
|
||||
const router = useRouter();
|
||||
const fileRef = useRef<HTMLInputElement>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [stage, setStage] = useState<"recognizing" | "generating">("recognizing");
|
||||
const stageTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
const [upgradeOpen, setUpgradeOpen] = useState(false);
|
||||
|
||||
function handleClick() {
|
||||
if (locked) {
|
||||
setUpgradeOpen(true);
|
||||
return;
|
||||
}
|
||||
fileRef.current?.click();
|
||||
}
|
||||
|
||||
@@ -88,12 +95,19 @@ export function PhotoImportButton() {
|
||||
<Camera className="mr-2 h-4 w-4" />
|
||||
)}
|
||||
{t("importFromPhoto")}
|
||||
{locked && <ProBadge />}
|
||||
</Button>
|
||||
<FakeProgressBar
|
||||
active={loading}
|
||||
durationMs={12000}
|
||||
label={loading ? (stage === "recognizing" ? t("recognizingPhoto") : t("writingRecipe")) : undefined}
|
||||
/>
|
||||
<UpgradeDialog
|
||||
open={upgradeOpen}
|
||||
onOpenChange={setUpgradeOpen}
|
||||
featureKey="recipe_import_photo"
|
||||
featureLabel="Import from photo"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user