Files
dataroom/components/billing/add-seat-modal.tsx
zooqueen 5476669298 billing: hand payment to the hosted pages
The dataroom carried its own plan catalog, feature grid and Stripe
price-id mapper with no payment SDK behind them, so nothing there could
take money. Plans and pricing now open pay.hanzo.ai, invoices and
payment method open billing.hanzo.ai, both named once in
lib/billing/hosted.ts.

UpgradePlanModal keeps its name, props and children API across all 45
call sites; clickedPlan rides the analytics event and highlightItem no
longer has an effect, since the hosted page owns the catalog.
2026-08-14 20:50:04 -07:00

53 lines
1.3 KiB
TypeScript

import { useEffect, useRef } from "react";
import React from "react";
import { useTeam } from "@/context/team-context";
import { BILLING_URL, visit } from "@/lib/billing/hosted";
import { useAnalytics } from "@/lib/analytics";
import { usePlan } from "@/lib/swr/use-billing";
/**
* Opens the hosted billing page in a new tab, where seats are added to the
* subscription. Either wrap a trigger element as `children`, or drive it by
* flipping `open` to true.
*/
export function AddSeatModal({
open,
setOpen,
children,
}: {
open: boolean;
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
children?: React.ReactNode;
}) {
const teamId = useTeam()?.currentTeam?.id;
const { plan } = usePlan();
const analytics = useAnalytics();
const sent = useRef(false);
const addSeat = () => {
analytics.capture("Add Seat Clicked", { teamId, plan });
visit(BILLING_URL);
};
useEffect(() => {
if (!open) {
sent.current = false;
return;
}
if (sent.current) return;
sent.current = true;
addSeat();
setOpen(false);
}, [open]);
return React.isValidElement<{
onClick?: React.MouseEventHandler<HTMLButtonElement>;
}>(children) ? (
React.cloneElement(children, { onClick: addSeat })
) : (
<>{children}</>
);
}