[WEB-4253] improvement: plan card enhancements (#7168)

* [WEB-4253] improvement: plan card enhancements

* improvement: pricing changes
This commit is contained in:
Prateek Shourya 2025-06-05 14:37:26 +05:30 committed by GitHub
parent 1113f9fc19
commit 986f29d1f2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 91 additions and 15 deletions

View file

@ -11,10 +11,12 @@ import { useTranslation } from "@plane/i18n";
import { TBillingFrequency } from "@plane/types";
import { getButtonStyling } from "@plane/ui";
import { cn, getSubscriptionName } from "@plane/utils";
// components
import { DiscountInfo } from "@/components/license/modal/card/discount-info";
// constants
import { getUpgradeButtonStyle } from "@/components/workspace/billing/subscription";
import { TPlanDetail } from "@/constants/plans";
// components
// local imports
import { PlanFrequencyToggle } from "./frequency-toggle";
type TPlanDetailProps = {
@ -64,11 +66,17 @@ export const PlanDetail: FC<TPlanDetailProps> = observer((props) => {
</div>
<div className="flex gap-x-2 items-start text-custom-text-300 pb-1 transition-all duration-300 animate-slide-up">
{isSubscriptionActive && displayPrice !== undefined && (
<span className="text-custom-text-100 text-2xl font-semibold transition-all duration-300">
{"$" + displayPrice}
</span>
<div className="flex items-center gap-1 text-2xl text-custom-text-100 font-semibold transition-all duration-300">
<DiscountInfo
currency="$"
frequency={billingFrequency ?? "month"}
price={displayPrice}
subscriptionType={subscriptionType}
className="mr-1.5"
/>
</div>
)}
<div className="pt-2">
<div className="pt-1">
{pricingDescription && <div className="transition-all duration-300">{pricingDescription}</div>}
{pricingSecondaryDescription && (
<div className="text-xs text-custom-text-400 transition-all duration-300">

View file

@ -6,8 +6,10 @@ import { EProductSubscriptionEnum } from "@plane/constants";
import { IPaymentProduct, TSubscriptionPrice } from "@plane/types";
import { getButtonStyling, Loader } from "@plane/ui";
import { cn } from "@plane/utils";
// helpers
// components
import { getUpgradeButtonStyle } from "@/components/workspace/billing/subscription";
// local imports
import { DiscountInfo } from "./discount-info";
export type TCheckoutParams = {
planVariant: EProductSubscriptionEnum;
@ -56,8 +58,13 @@ export const PlanCheckoutButton: FC<Props> = observer((props) => {
</Loader>
) : (
<span className="animate-fade-in">
{price.currency}
{price.price}
<DiscountInfo
currency={price.currency}
frequency={price.recurring}
price={price.price}
subscriptionType={planVariant}
className="mr-1.5"
/>
</span>
)}
</div>

View file

@ -0,0 +1,61 @@
import { useTheme } from "next-themes";
// plane imports
import { EProductSubscriptionEnum } from "@plane/constants";
import { TBillingFrequency } from "@plane/types";
import { cn } from "@plane/utils";
type TDiscountInfoProps = {
className?: string;
currency: string;
frequency: TBillingFrequency;
price: number;
subscriptionType: EProductSubscriptionEnum;
};
const PLANS_WITH_DISCOUNT = [EProductSubscriptionEnum.PRO];
const getActualPrice = (frequency: TBillingFrequency, subscriptionType: EProductSubscriptionEnum): number | null => {
switch (subscriptionType) {
case EProductSubscriptionEnum.PRO:
return frequency === "month" ? 10 : 8;
default:
return null;
}
};
export const DiscountInfo = ({ className, currency, frequency, price, subscriptionType }: TDiscountInfoProps) => {
const { resolvedTheme } = useTheme();
// derived values
const actualPrice = getActualPrice(frequency, subscriptionType);
if (!PLANS_WITH_DISCOUNT.includes(subscriptionType)) {
return (
<>
{currency}
{price}
</>
);
}
return (
<>
{actualPrice != price && (
<span className={cn("relative", className)}>
<img
src={
resolvedTheme === "dark"
? "https://images.plane.so/pricing/hero/scribble-white.svg"
: "https://images.plane.so/pricing/hero/scribble-black.svg"
}
alt="image"
className="absolute top-1/2 left-1/2 -translate-y-1/2 -translate-x-1/2 w-full scale-x-125"
/>
{currency}
{actualPrice}
</span>
)}
{currency}
{price}
</>
);
};