shellphone.app/app/settings/components/billing/plans.tsx

115 lines
3.3 KiB
TypeScript
Raw Normal View History

2021-09-30 22:18:03 +00:00
import * as Panelbear from "@panelbear/panelbear-js";
import clsx from "clsx";
import type { Subscription } from "db";
import { SubscriptionStatus } from "db";
2021-10-19 18:03:09 +00:00
import useSubscription from "app/core/hooks/use-subscription";
2021-09-30 22:18:03 +00:00
export default function Plans() {
const { hasActiveSubscription, subscription, subscribe, changePlan } = useSubscription();
2021-09-30 22:18:03 +00:00
return (
<div className="mt-6 flex flex-row flex-wrap gap-2">
2021-09-30 22:18:03 +00:00
{pricing.tiers.map((tier) => {
const isCurrentTier = subscription?.paddlePlanId === tier.planId;
const isActiveTier = hasActiveSubscription && isCurrentTier;
const cta = getCTA({ subscription, tier });
2021-09-30 22:18:03 +00:00
return (
<div
key={tier.title}
className={clsx(
"relative p-2 pt-4 bg-white border border-gray-200 rounded-xl shadow-sm flex flex-1 min-w-[250px] flex-col",
2021-09-30 22:18:03 +00:00
)}
>
<div className="flex-1 px-2">
2021-09-30 22:18:03 +00:00
<h3 className="text-xl font-mackinac font-semibold text-gray-900">{tier.title}</h3>
{tier.yearly ? (
<p className="absolute top-0 py-1.5 px-4 bg-primary-500 rounded-full text-xs font-semibold uppercase tracking-wide text-white transform -translate-y-1/2">
Get 2 months free!
</p>
) : null}
<p className="mt-4 flex items-baseline text-gray-900">
<span className="text-2xl font-extrabold tracking-tight">{tier.price}</span>
<span className="ml-1 text-lg font-semibold">{tier.frequency}</span>
</p>
{tier.yearly ? (
<p className="text-gray-500 text-sm">Billed yearly ({tier.price * 12})</p>
) : null}
<p className="mt-6 text-gray-500">{tier.description}</p>
</div>
<button
disabled={isActiveTier}
2021-09-30 22:18:03 +00:00
onClick={() => {
if (hasActiveSubscription) {
changePlan({ planId: tier.planId });
Panelbear.track(`Subscribe to ${tier.title}`);
} else {
subscribe({ planId: tier.planId, coupon: "groot429" });
Panelbear.track(`Subscribe to ${tier.title}`);
}
2021-09-30 22:18:03 +00:00
}}
className={clsx(
!isActiveTier
2021-09-30 22:18:03 +00:00
? "bg-primary-500 text-white hover:bg-primary-600"
: "bg-primary-50 text-primary-700 cursor-not-allowed",
"mt-8 block w-full py-3 px-6 border border-transparent rounded-md text-center font-medium",
)}
>
{cta}
</button>
</div>
);
})}
</div>
);
}
function getCTA({
subscription,
tier,
}: {
subscription?: Subscription;
tier: typeof pricing["tiers"][number];
}): string {
if (!subscription) {
return "Subscribe";
}
const isCancelling = subscription.status === SubscriptionStatus.deleted;
if (isCancelling) {
return "Resubscribe";
}
const isCurrentTier = subscription.paddlePlanId === tier.planId;
const hasActiveSubscription = subscription.status !== SubscriptionStatus.deleted;
const isActiveTier = hasActiveSubscription && isCurrentTier;
if (isActiveTier) {
return "Current plan";
}
return `Switch to ${tier.title}`;
}
2021-09-30 22:18:03 +00:00
const pricing = {
tiers: [
{
title: "Yearly",
planId: 727544,
price: 12.5,
frequency: "/month",
description: "Text and call anyone, anywhere in the world, all year long.",
yearly: true,
2021-09-30 22:18:03 +00:00
},
{
title: "Monthly",
planId: 727540,
2021-09-30 22:18:03 +00:00
price: 15,
frequency: "/month",
description: "Text and call anyone, anywhere in the world.",
yearly: false,
},
],
};