Spaces:
Running
Running
Download apps/web/src/components/UpgradePrompt.tsx from Benaah/MicProtocol: direct link, hf CLI and curl.
- Browser
- Download file 3.11 kB
-
https://huggingface.co/spaces/Benaah/MicProtocol/resolve/main/apps/web/src/components/UpgradePrompt.tsx
- Command line
-
hf download hf://spaces/Benaah/MicProtocol/apps/web/src/components/UpgradePrompt.tsx
-
curl -L -o UpgradePrompt.tsx https://huggingface.co/spaces/Benaah/MicProtocol/resolve/main/apps/web/src/components/UpgradePrompt.tsx
3.11 kB
| "use client"; | |
| import React from "react"; | |
| import { useRouter } from "next/navigation"; | |
| import { Sparkles, X } from "lucide-react"; | |
| interface UpgradePromptProps { | |
| /** Which plan the user needs to unlock the feature */ | |
| requiredPlan?: "Creator" | "Studio"; | |
| /** Short description of the feature the user tried to access */ | |
| feature?: string; | |
| /** Optional; if set the prompt shows inline, otherwise it auto-hides after 8 s */ | |
| variant?: "banner" | "toast"; | |
| /** Called when the user dismisses the prompt */ | |
| onDismiss?: () => void; | |
| } | |
| /** | |
| * A small upgrade prompt shown when a user tries to use a feature | |
| * that requires an upgrade. | |
| */ | |
| export default function UpgradePrompt({ | |
| requiredPlan = "Creator", | |
| feature = "this feature", | |
| variant = "banner", | |
| onDismiss, | |
| }: UpgradePromptProps) { | |
| const router = useRouter(); | |
| const [visible, setVisible] = React.useState(true); | |
| // Auto-dismiss after 8 seconds for the toast variant | |
| React.useEffect(() => { | |
| if (variant !== "toast") return; | |
| const id = setTimeout(() => { | |
| setVisible(false); | |
| onDismiss?.(); | |
| }, 8000); | |
| return () => clearTimeout(id); | |
| }, [variant, onDismiss]); | |
| if (!visible) return null; | |
| return ( | |
| <div | |
| className="upgrade-prompt" | |
| style={{ | |
| display: "flex", | |
| alignItems: "center", | |
| gap: "var(--space-3)", | |
| padding: "var(--space-3) var(--space-4)", | |
| borderRadius: "var(--radius-md)", | |
| background: "linear-gradient(135deg, rgba(108, 92, 231, 0.12), rgba(245, 158, 11, 0.08))", | |
| border: "1px solid rgba(108, 92, 231, 0.2)", | |
| fontSize: "var(--text-sm)", | |
| position: variant === "toast" ? "fixed" : "relative", | |
| bottom: variant === "toast" ? "var(--space-6)" : undefined, | |
| right: variant === "toast" ? "var(--space-6)" : undefined, | |
| zIndex: variant === "toast" ? 1000 : undefined, | |
| maxWidth: variant === "toast" ? 400 : undefined, | |
| boxShadow: variant === "toast" ? "var(--shadow-lg)" : undefined, | |
| }} | |
| role="status" | |
| aria-live="polite" | |
| > | |
| <Sparkles size={18} color="var(--color-primary)" style={{ flexShrink: 0 }} /> | |
| <div style={{ flex: 1 }}> | |
| <strong>{feature}</strong> requires the <strong>{requiredPlan}</strong> plan. | |
| {" "} | |
| <button | |
| onClick={() => router.push("/settings/billing")} | |
| className="btn btn-primary" | |
| style={{ | |
| fontSize: "var(--text-xs)", | |
| padding: "2px 12px", | |
| height: "auto", | |
| display: "inline-flex", | |
| marginLeft: "var(--space-2)", | |
| }} | |
| > | |
| Upgrade | |
| </button> | |
| </div> | |
| {onDismiss && ( | |
| <button | |
| onClick={() => { | |
| setVisible(false); | |
| onDismiss(); | |
| }} | |
| style={{ | |
| background: "none", | |
| border: "none", | |
| cursor: "pointer", | |
| color: "var(--text-tertiary)", | |
| padding: 2, | |
| }} | |
| aria-label="Dismiss" | |
| > | |
| <X size={14} /> | |
| </button> | |
| )} | |
| </div> | |
| ); | |
| } | |