"use client";
import { Check, Cloud } from "lucide-react";
import { Badge } from "@/components/shadcn/badge/badge";
import { Button } from "@/components/shadcn/button/button";
import { Modal } from "@/components/shadcn/modal";
import { useAuth } from "@/hooks/use-auth";
import {
CLOUD_UPGRADE_CONTENT,
CLOUD_UPGRADE_FOOTER_NOTE,
CLOUD_UPGRADE_SECONDARY_CTA,
getCloudUpgradeCompareUrl,
getCloudUpgradePrimaryUrl,
getPaidPlanUpgradeBillingHref,
getPaidPlanUpgradeCompareUrl,
isCloudUpgradeFeature,
isPaidPlanUpgradeFeature,
PAID_PLAN_UPGRADE_ADMIN_NOTE,
PAID_PLAN_UPGRADE_BADGE,
PAID_PLAN_UPGRADE_CONTENT,
} from "@/lib/cloud-upgrade";
import { isCloud } from "@/lib/shared/env";
import { useCloudUpgradeStore } from "@/store";
import type {
CloudUpgradeFeature,
PaidPlanUpgradeFeature,
} from "@/types/cloud-upgrade";
const allowInitialAutoFocus = () => {};
const CTA_CLASS_NAME =
"h-auto min-h-9 w-full min-w-0 shrink whitespace-normal md:flex-1";
interface UpgradeModalCta {
label: string;
href: string;
opensInNewTab: boolean;
}
interface UpgradeModalVariantProps {
open: boolean;
onClose: () => void;
returnFocusElement: HTMLElement | null;
}
interface UpgradeModalLayoutProps extends UpgradeModalVariantProps {
title: string;
description: string;
badge: string;
benefits: readonly string[];
primaryCta?: UpgradeModalCta;
secondaryCta: UpgradeModalCta;
footerNote?: string;
}
interface UpgradeModalLinkProps {
cta: UpgradeModalCta;
isSecondary?: boolean;
}
const UpgradeModalLink = ({ cta, isSecondary }: UpgradeModalLinkProps) => (
);
const UpgradeModalLayout = ({
open,
onClose,
returnFocusElement,
title,
description,
badge,
benefits,
primaryCta,
secondaryCta,
footerNote,
}: UpgradeModalLayoutProps) => (
!nextOpen && onClose()}
onOpenAutoFocus={allowInitialAutoFocus}
onCloseAutoFocus={(event) => {
event.preventDefault();
returnFocusElement?.focus();
}}
title={title}
description={description}
size="2xl"
>
{benefits.map((benefit) => (
-
{benefit}
))}
{primaryCta && }
{footerNote && (
{footerNote}
)}
);
interface LocalServerUpgradeModalProps extends UpgradeModalVariantProps {
feature: CloudUpgradeFeature;
}
const LocalServerUpgradeModal = ({
feature,
...modalProps
}: LocalServerUpgradeModalProps) => {
const content = CLOUD_UPGRADE_CONTENT[feature];
return (
);
};
interface PaidPlanUpgradeModalProps extends UpgradeModalVariantProps {
feature: PaidPlanUpgradeFeature;
}
const PaidPlanUpgradeModal = ({
feature,
...modalProps
}: PaidPlanUpgradeModalProps) => {
const { permissions } = useAuth();
const content = PAID_PLAN_UPGRADE_CONTENT[feature];
// The /billing route redirects users without billing access to /profile.
const canManageBilling = permissions.manage_billing === true;
return (
);
};
export const CloudUpgradeModal = () => {
const activeFeature = useCloudUpgradeStore((state) => state.activeFeature);
const retainedFeature = useCloudUpgradeStore(
(state) => state.retainedFeature,
);
const closeCloudUpgrade = useCloudUpgradeStore(
(state) => state.closeCloudUpgrade,
);
const returnFocusElement = useCloudUpgradeStore(
(state) => state.returnFocusElement,
);
const feature = activeFeature ?? retainedFeature;
const modalProps = {
open: activeFeature !== null,
onClose: closeCloudUpgrade,
returnFocusElement,
};
// Cloud only upsells paid plans; Local Server only upsells Prowler Cloud.
if (isCloud()) {
return isPaidPlanUpgradeFeature(feature) ? (
) : null;
}
return isCloudUpgradeFeature(feature) ? (
) : null;
};