Files
dataroom/components/ui/upgrade-button.tsx
zeekay 9dff9e667e rip: enterprise dirs + paywalls — full AGPL, no commercial-license code
Drop the dual-licensed `ee/` tree entirely. All features previously
locked behind the Hanzo Dataroom Commercial License are now part of the
AGPL-3.0 core and freely available — custom domains, branded viewing,
advanced analytics, watermarks, access controls, Q&A, AI vector stores,
workflows, SAML SSO, dataroom invitations, conversations, templates.

Layout changes:
* `ee/features/{ai,conversations,workflows,permissions,storage,templates,
  dataroom-invitations,access-notifications,security,conversions}/` →
  `features/<name>/` (AGPL).
* `ee/limits/` → `lib/billing/limits/` with every plan resolving to an
  unlimited profile (no users/links/documents/domains/datarooms cap,
  conversations and watermarks always on).
* `ee/stripe/` → `lib/billing/legacy/` (already a compat shim over
  `@hanzoai/commerce`; renewal-reminder webhook is now a no-op).
* `ee/features/billing/cancellation/` deleted. Pause/unpause/cancel/
  retention routes now compile against `lib/billing/cancellation.ts`
  stubs that return 410 Gone; `isTeamPaused`/`isTeamPausedById` in
  `lib/billing/paused.ts` always report active. `CancellationModal` is
  a no-op shim in `components/billing/`.
* `app/(ee)/api/*` route group folded into `app/api/*` (SAML auth,
  SCIM, AI chat, workflows, FAQ, link-upload).

Build: `npm run build` green.
2026-06-07 11:46:48 -07:00

100 lines
2.1 KiB
TypeScript

import React, { ButtonHTMLAttributes, useState } from "react";
import { PlanEnum } from "@/lib/billing/legacy/constants";
import { CrownIcon } from "lucide-react";
import { cn } from "@/lib/utils";
import { UpgradePlanModal } from "@/components/billing/upgrade-plan-modal";
import { Button } from "@/components/ui/button";
interface UpgradeButtonProps {
text: string;
clickedPlan: PlanEnum;
trigger: string;
variant?: "default" | "outline" | "ghost";
size?: "default" | "sm" | "lg" | "icon";
className?: string;
highlightItem?: string[];
onClick?: () => void;
useModal?: boolean;
customText?: string;
type?: ButtonHTMLAttributes<HTMLButtonElement>["type"];
disabled?: boolean;
}
export function UpgradeButton({
text,
clickedPlan,
trigger,
variant = "default",
size = "default",
className,
highlightItem,
onClick,
useModal = true,
customText,
type = "button",
disabled,
}: UpgradeButtonProps) {
const [open, setOpen] = useState(false);
const buttonContent = (
<Button
disabled={disabled}
type={type}
variant={variant}
size={size}
className={cn("gap-1.5", className)}
onClick={onClick ? onClick : useModal ? () => setOpen(true) : undefined}
>
{customText ? (
<>
<CrownIcon className="h-4 w-4" /> {customText}
</>
) : (
<>
<CrownIcon className="h-4 w-4" />
Upgrade to {text}
</>
)}
</Button>
);
if (!useModal || onClick || disabled) {
return buttonContent;
}
return (
<>
{buttonContent}
<UpgradePlanModal
clickedPlan={clickedPlan}
trigger={trigger}
open={open}
setOpen={setOpen}
highlightItem={highlightItem}
/>
</>
);
}
export function createUpgradeButton(
text: string,
clickedPlan: PlanEnum,
trigger: string,
options?: Partial<UpgradeButtonProps>,
) {
return function UpgradeButtonComponent(props?: Partial<UpgradeButtonProps>) {
return (
<UpgradeButton
text={text}
clickedPlan={clickedPlan}
trigger={trigger}
{...options}
{...props}
/>
);
};
}