From 819cf506ff95d9c869919ae96e488449fbc59cf4 Mon Sep 17 00:00:00 2001 From: bender Date: Tue, 3 Mar 2026 04:54:58 +0000 Subject: [PATCH] Switch to version 3: modified src/components/sections/pricing/PricingCardEight.tsx --- .../sections/pricing/PricingCardEight.tsx | 338 +++++++++++++----- 1 file changed, 243 insertions(+), 95 deletions(-) diff --git a/src/components/sections/pricing/PricingCardEight.tsx b/src/components/sections/pricing/PricingCardEight.tsx index 9a1381a..5c00d72 100644 --- a/src/components/sections/pricing/PricingCardEight.tsx +++ b/src/components/sections/pricing/PricingCardEight.tsx @@ -1,100 +1,248 @@ -import React from "react"; -import { cn } from "@/lib/utils"; +"use client"; -export interface PricingPlan { - id: string; - badge: string; - price: string; - subtitle: string; - buttons: Array<{ text: string; onClick?: () => void; href?: string }>; - features: string[]; -} +import { memo } from "react"; +import CardStack from "@/components/cardStack/CardStack"; +import Button from "@/components/button/Button"; +import PricingBadge from "@/components/shared/PricingBadge"; +import PricingFeatureList from "@/components/shared/PricingFeatureList"; +import { getButtonProps } from "@/lib/buttonUtils"; +import { cls, shouldUseInvertedText } from "@/lib/utils"; +import { useTheme } from "@/providers/themeProvider/ThemeProvider"; +import type { LucideIcon } from "lucide-react"; +import type { ButtonConfig, CardAnimationType, TitleSegment, ButtonAnimationType } from "@/components/cardStack/types"; +import type { TextboxLayout, InvertedBackground } from "@/providers/themeProvider/config/constants"; -export interface PricingCardEightProps { - plans: PricingPlan[]; - title: string; - description: string; - animationType?: "none" | "opacity" | "slide-up" | "scale-rotate" | "blur-reveal"; - textboxLayout?: "default" | "split" | "split-actions" | "split-description" | "inline-image"; - useInvertedBackground?: boolean; - className?: string; - containerClassName?: string; - cardClassName?: string; - badgeClassName?: string; - priceClassName?: string; - subtitleClassName?: string; - planButtonContainerClassName?: string; - planButtonClassName?: string; - featuresClassName?: string; - featureItemClassName?: string; - gridClassName?: string; - textBoxClassName?: string; -} - -export const PricingCardEight: React.FC = ({ - plans, - title, - description, - animationType = "slide-up", textboxLayout = "default", useInvertedBackground = false, - className, - containerClassName, - cardClassName, - badgeClassName, - priceClassName, - subtitleClassName, - planButtonContainerClassName, - planButtonClassName, - featuresClassName, - featureItemClassName, - gridClassName, - textBoxClassName -}) => { - return ( -
-
-
-

{title}

-

{description}

-
- -
- {plans.map((plan) => ( -
-
- {plan.badge} - -

{plan.price}

-

{plan.subtitle}

-
- -
- {plan.buttons.map((button, idx) => ( - - ))} -
- -
- {plan.features.map((feature, idx) => ( -
- - {feature} -
- ))} -
-
- ))} -
-
-
- ); +type PricingPlan = { + id: string; + badge: string; + badgeIcon?: LucideIcon; + price: string; + subtitle: string; + buttons: ButtonConfig[]; + features: string[]; }; +interface PricingCardEightProps { + plans: PricingPlan[]; + carouselMode?: "auto" | "buttons"; + uniformGridCustomHeightClasses?: string; + animationType: CardAnimationType; + title: string; + titleSegments?: TitleSegment[]; + description: string; + tag?: string; + tagIcon?: LucideIcon; + tagAnimation?: ButtonAnimationType; + buttons?: ButtonConfig[]; + buttonAnimation?: ButtonAnimationType; + textboxLayout: TextboxLayout; + useInvertedBackground: InvertedBackground; + ariaLabel?: string; + className?: string; + containerClassName?: string; + cardClassName?: string; + textBoxTitleClassName?: string; + textBoxTitleImageWrapperClassName?: string; + textBoxTitleImageClassName?: string; + textBoxDescriptionClassName?: string; + badgeClassName?: string; + priceClassName?: string; + subtitleClassName?: string; + planButtonContainerClassName?: string; + planButtonClassName?: string; + featuresClassName?: string; + featureItemClassName?: string; + gridClassName?: string; + carouselClassName?: string; + controlsClassName?: string; + textBoxClassName?: string; + textBoxTagClassName?: string; + textBoxButtonContainerClassName?: string; + textBoxButtonClassName?: string; + textBoxButtonTextClassName?: string; +} + +interface PricingCardItemProps { + plan: PricingPlan; + shouldUseLightText: boolean; + cardClassName?: string; + badgeClassName?: string; + priceClassName?: string; + subtitleClassName?: string; + planButtonContainerClassName?: string; + planButtonClassName?: string; + featuresClassName?: string; + featureItemClassName?: string; +} + +const PricingCardItem = memo(({ + plan, + shouldUseLightText, + cardClassName = "", + badgeClassName = "", + priceClassName = "", + subtitleClassName = "", + planButtonContainerClassName = "", + planButtonClassName = "", + featuresClassName = "", + featureItemClassName = "", +}: PricingCardItemProps) => { + const theme = useTheme(); + + const getButtonConfigProps = () => { + if (theme.defaultButtonVariant === "hover-bubble") { + return { bgClassName: "w-full" }; + } + if (theme.defaultButtonVariant === "icon-arrow") { + return { className: "justify-between" }; + } + return {}; + }; + + return ( +
+
+ + +
+
+ {plan.price} +
+ +

+ {plan.subtitle} +

+
+ + {plan.buttons && plan.buttons.length > 0 && ( +
+ {plan.buttons.slice(0, 2).map((button, index) => ( +
+ )} +
+ +
+ +
+
+ ); +}); + +PricingCardItem.displayName = "PricingCardItem"; + +const PricingCardEight = ({ + plans, + carouselMode = "buttons", + uniformGridCustomHeightClasses, + animationType, + title, + titleSegments, + description, + tag, + tagIcon, + tagAnimation, + buttons, + buttonAnimation, + textboxLayout, + useInvertedBackground, + ariaLabel = "Pricing section", + className = "", + containerClassName = "", + cardClassName = "", + textBoxTitleClassName = "", + textBoxTitleImageWrapperClassName = "", + textBoxTitleImageClassName = "", + textBoxDescriptionClassName = "", + badgeClassName = "", + priceClassName = "", + subtitleClassName = "", + planButtonContainerClassName = "", + planButtonClassName = "", + featuresClassName = "", + featureItemClassName = "", + gridClassName = "", + carouselClassName = "", + controlsClassName = "", + textBoxClassName = "", + textBoxTagClassName = "", + textBoxButtonContainerClassName = "", + textBoxButtonClassName = "", + textBoxButtonTextClassName = "", +}: PricingCardEightProps) => { + const theme = useTheme(); + const shouldUseLightText = shouldUseInvertedText(useInvertedBackground, theme.cardStyle); + + return ( + + {plans.map((plan, index) => ( + + ))} + + ); +}; + +PricingCardEight.displayName = "PricingCardEight"; + export default PricingCardEight;