feat(cloud): fix upgrade/downgrade and migrate webhook handler
This commit is contained in:
@@ -87,6 +87,8 @@ export default withApiLogging(
|
|||||||
const { event, license_key, license_status, tier, prev_license_key } =
|
const { event, license_key, license_status, tier, prev_license_key } =
|
||||||
payload;
|
payload;
|
||||||
|
|
||||||
|
log.info({ headers: req.headers, payload }, "partner webhook received");
|
||||||
|
|
||||||
const { db } = await createNextApiContext(req);
|
const { db } = await createNextApiContext(req);
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
@@ -141,7 +143,7 @@ export default withApiLogging(
|
|||||||
const cfg = tierConfig(tier);
|
const cfg = tierConfig(tier);
|
||||||
await subscriptionRepo.upsertByPartnerLicenseKey(db, license_key, {
|
await subscriptionRepo.upsertByPartnerLicenseKey(db, license_key, {
|
||||||
plan: cfg.plan,
|
plan: cfg.plan,
|
||||||
status: license_status,
|
status: "active",
|
||||||
partnerTier: tier,
|
partnerTier: tier,
|
||||||
seats: cfg.seats,
|
seats: cfg.seats,
|
||||||
unlimitedSeats: cfg.unlimitedSeats,
|
unlimitedSeats: cfg.unlimitedSeats,
|
||||||
@@ -163,7 +165,7 @@ export default withApiLogging(
|
|||||||
const cfg = tierConfig(tier);
|
const cfg = tierConfig(tier);
|
||||||
await subscriptionRepo.upsertByPartnerLicenseKey(db, license_key, {
|
await subscriptionRepo.upsertByPartnerLicenseKey(db, license_key, {
|
||||||
plan: cfg.plan,
|
plan: cfg.plan,
|
||||||
status: sub.status,
|
status: "active",
|
||||||
partnerTier: tier,
|
partnerTier: tier,
|
||||||
seats: cfg.seats,
|
seats: cfg.seats,
|
||||||
unlimitedSeats: cfg.unlimitedSeats,
|
unlimitedSeats: cfg.unlimitedSeats,
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ import { useWorkspace } from "~/providers/workspace";
|
|||||||
import { api } from "~/utils/api";
|
import { api } from "~/utils/api";
|
||||||
import { getAvatarUrl } from "~/utils/helpers";
|
import { getAvatarUrl } from "~/utils/helpers";
|
||||||
import { DeleteMemberConfirmation } from "./components/DeleteMemberConfirmation";
|
import { DeleteMemberConfirmation } from "./components/DeleteMemberConfirmation";
|
||||||
import { InviteMemberForm } from "./components/InviteMemberForm";
|
|
||||||
import { EditMemberPermissionsModal } from "./components/EditMemberPermissionsModal";
|
import { EditMemberPermissionsModal } from "./components/EditMemberPermissionsModal";
|
||||||
|
import { InviteMemberForm } from "./components/InviteMemberForm";
|
||||||
|
|
||||||
export default function MembersPage() {
|
export default function MembersPage() {
|
||||||
const { modalContentType, openModal, isOpen } = useModal();
|
const { modalContentType, openModal, isOpen } = useModal();
|
||||||
@@ -76,6 +76,13 @@ export default function MembersPage() {
|
|||||||
|
|
||||||
const unlimitedSeats = hasUnlimitedSeats(subscriptions);
|
const unlimitedSeats = hasUnlimitedSeats(subscriptions);
|
||||||
|
|
||||||
|
const isProPlan =
|
||||||
|
!!proSubscription ||
|
||||||
|
workspace.plan === "pro" ||
|
||||||
|
workspace.plan === "enterprise";
|
||||||
|
const isTeamPlan = !!teamSubscription || workspace.plan === "team";
|
||||||
|
const isPaidPlan = isProPlan || isTeamPlan;
|
||||||
|
|
||||||
const TableRow = ({
|
const TableRow = ({
|
||||||
memberPublicId,
|
memberPublicId,
|
||||||
memberId,
|
memberId,
|
||||||
@@ -144,8 +151,8 @@ export default function MembersPage() {
|
|||||||
{memberName}
|
{memberName}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{((workspace.role === "admin" ||
|
{(workspace.role === "admin" ||
|
||||||
data?.showEmailsToMembers === true) ||
|
data?.showEmailsToMembers === true ||
|
||||||
showSkeleton) && (
|
showSkeleton) && (
|
||||||
<p
|
<p
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
@@ -180,8 +187,7 @@ export default function MembersPage() {
|
|||||||
<div className="relative inline-flex items-center">
|
<div className="relative inline-flex items-center">
|
||||||
<span className="inline-flex items-center gap-1 rounded-md bg-emerald-500/10 px-1.5 py-0.5 text-[10px] font-medium text-emerald-400 ring-1 ring-inset ring-emerald-500/20 sm:text-[11px]">
|
<span className="inline-flex items-center gap-1 rounded-md bg-emerald-500/10 px-1.5 py-0.5 text-[10px] font-medium text-emerald-400 ring-1 ring-inset ring-emerald-500/20 sm:text-[11px]">
|
||||||
{memberRole &&
|
{memberRole &&
|
||||||
memberRole.charAt(0).toUpperCase() +
|
memberRole.charAt(0).toUpperCase() + memberRole.slice(1)}
|
||||||
memberRole.slice(1)}
|
|
||||||
{canEditMember && session?.user.id !== memberId && (
|
{canEditMember && session?.user.id !== memberId && (
|
||||||
<HiChevronDown className="h-3 w-3" />
|
<HiChevronDown className="h-3 w-3" />
|
||||||
)}
|
)}
|
||||||
@@ -266,32 +272,30 @@ export default function MembersPage() {
|
|||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
{env("NEXT_PUBLIC_KAN_ENV") === "cloud" && (
|
{env("NEXT_PUBLIC_KAN_ENV") === "cloud" && (
|
||||||
<>
|
<>
|
||||||
{!proSubscription && !teamSubscription && (
|
{!isPaidPlan && (
|
||||||
<Link
|
<Link
|
||||||
href="/settings/workspace?upgrade=pro"
|
href="/settings/workspace?upgrade=pro"
|
||||||
className="hidden items-center rounded-full border border-emerald-300 bg-emerald-50 px-3 py-1 text-center text-xs text-emerald-400 dark:border-emerald-700 dark:bg-emerald-950 dark:text-emerald-400 lg:flex"
|
className="hidden items-center rounded-full border border-emerald-300 bg-emerald-50 px-3 py-1 text-center text-xs text-emerald-400 dark:border-emerald-700 dark:bg-emerald-950 dark:text-emerald-400 lg:flex"
|
||||||
>
|
>
|
||||||
<HiBolt />
|
<HiBolt />
|
||||||
<span className="ml-1 font-medium">
|
<span className="ml-1 font-medium">{t`Upgrade`}</span>
|
||||||
{t`Launch offer: Get unlimited members with Pro`}
|
|
||||||
</span>
|
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
"flex items-center rounded-full border px-3 py-1 text-center text-xs",
|
"flex items-center rounded-full border px-3 py-1 text-center text-xs",
|
||||||
teamSubscription || proSubscription
|
isPaidPlan
|
||||||
? "border-emerald-300 bg-emerald-50 text-emerald-400 dark:border-emerald-700 dark:bg-emerald-950 dark:text-emerald-400"
|
? "border-emerald-300 bg-emerald-50 text-emerald-400 dark:border-emerald-700 dark:bg-emerald-950 dark:text-emerald-400"
|
||||||
: "border-light-300 bg-light-50 text-light-1000 dark:border-dark-300 dark:bg-dark-50 dark:text-dark-900",
|
: "border-light-300 bg-light-50 text-light-1000 dark:border-dark-300 dark:bg-dark-50 dark:text-dark-900",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<span className="font-medium">
|
<span className="font-medium">
|
||||||
{proSubscription
|
{isProPlan
|
||||||
? t`Pro Plan`
|
? t`Pro Plan`
|
||||||
: teamSubscription
|
: isTeamPlan
|
||||||
? t`Team Plan`
|
? t`Team Plan`
|
||||||
: t`Free Plan`}
|
: t`Free Plan`}
|
||||||
{proSubscription && unlimitedSeats && (
|
{isProPlan && unlimitedSeats && (
|
||||||
<span className="ml-1 text-xs">∞</span>
|
<span className="ml-1 text-xs">∞</span>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user