33import type { SubscriptionConfigData } from "@/lib/cms"
44import { formatEuroCurrency } from "@/lib/formatters"
55import type { AppLocale } from "@/lib/i18n"
6+ import { calculateSubscriptionPrice , clampToRange , formatDiscountBadge , getPaymentPeriodDiscount , getPaymentPeriodSuffix , type PaymentPeriod , type UsageRange } from "@/lib/subscriptionCalculator"
67import { useDesktopPinnedPosition } from "@/hooks/useDesktopPinnedPosition"
78import { cn } from "@/lib/utils"
89import { BuyMenu } from "@/components/BuyMenu"
@@ -17,7 +18,6 @@ import { Card } from "./ui/Card"
1718
1819type DeploymentMode = "self-hosted" | "cloud"
1920type CustomerType = "b2b" | "b2c"
20- type PaymentPeriod = "monthly" | "quarterly" | "yearly"
2121type OptionAccent = "aqua" | "yellow" | "pink" | "blue" | "brand"
2222type SubscriptionSelection = {
2323 deployment : DeploymentMode
@@ -26,12 +26,6 @@ type SubscriptionSelection = {
2626 workflowExecutions : number
2727 aiTokens : number
2828}
29- type UsageRange = {
30- min : number
31- max : number
32- step : number
33- }
34-
3529export interface SubscriptionIcons {
3630 featureOverview : ReactNode [ ]
3731 deployment : {
@@ -182,29 +176,6 @@ function AdditionalFeatureCard({ title, description, active, onClick, icon, form
182176 )
183177}
184178
185- function clampToRange ( value : number , range : UsageRange ) {
186- return Math . min ( Math . max ( value , range . min ) , range . max )
187- }
188-
189- function formatDiscountBadge ( discount : number , locale : AppLocale ) {
190- return new Intl . NumberFormat ( locale === "de" ? "de-DE" : "en-US" , {
191- style : "percent" ,
192- maximumFractionDigits : 0 ,
193- } ) . format ( discount )
194- }
195-
196- function getPaymentPeriodDiscount ( period : PaymentPeriod , paymentPeriod : SubscriptionConfigData [ "paymentPeriod" ] ) {
197- if ( period === "quarterly" ) return paymentPeriod . quarterlyDiscount
198- if ( period === "yearly" ) return paymentPeriod . yearlyDiscount
199- return 0
200- }
201-
202- function getPaymentPeriodSuffix ( period : PaymentPeriod , paymentPeriod : SubscriptionConfigData [ "paymentPeriod" ] ) {
203- if ( period === "quarterly" ) return paymentPeriod . quarterlyPeriodSuffix
204- if ( period === "yearly" ) return paymentPeriod . yearlyPeriodSuffix
205- return paymentPeriod . monthlyPeriodSuffix
206- }
207-
208179export function SubscriptionConfigurator ( { locale, content, icons } : { locale : AppLocale ; content : SubscriptionConfigData ; icons : SubscriptionIcons } ) {
209180 const workflowExecutions = content . workflowExecutions
210181 const aiTokens = content . aiTokens
@@ -226,13 +197,17 @@ export function SubscriptionConfigurator({ locale, content, icons }: { locale: A
226197 const [ selectedFeatures , setSelectedFeatures ] = useState < Set < number > > ( new Set ( ) )
227198 const { wrapperRef : desktopWrapperRef , containerRef : desktopContainerRef } = useDesktopPinnedPosition < HTMLDivElement , HTMLDivElement > ( 96 )
228199
229- const workflowExecutionPrice = content . workflowExecutionPriceFactor * selection . workflowExecutions
230- const aiTokenPrice = content . aiTokenPriceFactor * selection . aiTokens
231200 const additionalFeaturesPrice = Array . from ( selectedFeatures ) . reduce ( ( acc , idx ) => acc + ( content . additionalFeatures ?. [ idx ] ?. price ?? 0 ) , 0 )
232201 const paymentPeriodDiscount = getPaymentPeriodDiscount ( selection . paymentPeriod , content . paymentPeriod )
233202 const paymentPeriodSuffix = getPaymentPeriodSuffix ( selection . paymentPeriod , content . paymentPeriod )
234- const totalBeforeDiscount = workflowExecutionPrice + aiTokenPrice + additionalFeaturesPrice
235- const totalPrice = totalBeforeDiscount * ( 1 - paymentPeriodDiscount )
203+ const { totalPrice } = calculateSubscriptionPrice ( {
204+ additionalFeaturesPrice,
205+ aiTokenPriceFactor : content . aiTokenPriceFactor ,
206+ aiTokens : selection . aiTokens ,
207+ discount : paymentPeriodDiscount ,
208+ workflowExecutionPriceFactor : content . workflowExecutionPriceFactor ,
209+ workflowExecutions : selection . workflowExecutions ,
210+ } )
236211 const paymentPeriodSwitchOptions : SwitchOption < PaymentPeriod > [ ] = paymentPeriodOptions . map ( ( option ) => {
237212 const discount = getPaymentPeriodDiscount ( option . value , content . paymentPeriod )
238213
0 commit comments