diff --git a/react/package.json b/react/package.json index bbc47507..ee1ab16a 100644 --- a/react/package.json +++ b/react/package.json @@ -34,6 +34,7 @@ "@stripe/stripe-js": "^4.3.0", "lodash.merge": "^4.6.2", "pako": "^2.1.0", + "pluralize": "^8.0.0", "styled-components": "^6.1.13" }, "devDependencies": { @@ -43,6 +44,7 @@ "@types/jest": "^29.5.12", "@types/lodash.merge": "^4.6.9", "@types/pako": "^2.0.3", + "@types/pluralize": "^0.0.33", "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", "@typescript-eslint/eslint-plugin": "^6.19.1", diff --git a/react/src/components/elements/included-features/IncludedFeatures.tsx b/react/src/components/elements/included-features/IncludedFeatures.tsx index 8308a399..19e86361 100644 --- a/react/src/components/elements/included-features/IncludedFeatures.tsx +++ b/react/src/components/elements/included-features/IncludedFeatures.tsx @@ -1,5 +1,6 @@ import { forwardRef, useMemo } from "react"; import { useTheme } from "styled-components"; +import pluralize from "pluralize"; import { useEmbed } from "../../../hooks"; import { type FontStyle } from "../../../context"; import type { RecursivePartial, ElementProps } from "../../../types"; @@ -179,8 +180,8 @@ export const IncludedFeatures = forwardRef< } > {typeof allocation === "number" - ? `${allocation} ${feature.name}` - : `Unlimited ${feature.name}`} + ? pluralize(feature.name, allocation, true) + : `Unlimited ${pluralize(feature.name)}`} )} diff --git a/react/src/components/elements/payment-method/PaymentMethod.tsx b/react/src/components/elements/payment-method/PaymentMethod.tsx index 6a6cd20d..38c3bbec 100644 --- a/react/src/components/elements/payment-method/PaymentMethod.tsx +++ b/react/src/components/elements/payment-method/PaymentMethod.tsx @@ -53,8 +53,12 @@ export const PaymentMethod = forwardRef< let monthsToExpiration: number | undefined; if (typeof cardExpYear === "number" && typeof cardExpMonth === "number") { + const today = new Date(); + const currentYear = today.getFullYear(); + const currentMonth = today.getMonth(); const timeToExpiration = Math.round( - +new Date(cardExpYear, cardExpMonth - 1) - +new Date(), + +new Date(cardExpYear, cardExpMonth - 1) - + +new Date(currentYear, currentMonth), ); monthsToExpiration = Math.round( timeToExpiration / (1000 * 60 * 60 * 24 * 30), @@ -93,7 +97,7 @@ export const PaymentMethod = forwardRef< {typeof paymentMethod.monthsToExpiration === "number" && - Math.abs(paymentMethod.monthsToExpiration) < 4 && ( + paymentMethod.monthsToExpiration < 4 && ( { + const theme = useTheme(); + + if (!entitlement.feature?.name) { + return null; + } + + if ( + entitlement.valueType === "numeric" || + entitlement.valueType === "trait" + ) { + let period; + if (entitlement.metricPeriod) { + period = { + current_day: "day", + current_month: "mo", + current_year: "yr", + }[entitlement.metricPeriod]; + } + + return ( + + + {typeof entitlement.valueNumeric === "number" + ? pluralize( + entitlement.feature.name, + entitlement.valueNumeric, + true, + ) + : `Unlimited ${pluralize(entitlement.feature.name)}`} + {period && `/${period}`} + + + ); + } + + return ( + + + {entitlement.feature.name} + + + ); +}; + export const CheckoutDialog = () => { const [checkoutStage, setCheckoutStage] = useState<"plan" | "checkout">( "plan", @@ -317,26 +380,33 @@ export const CheckoutDialog = () => { $height="auto" $padding="1.5rem" > - {plan.features.map((feature) => { + {plan.entitlements.map((entitlement) => { return ( - - - - {feature.name} + + {entitlement.feature?.icon && ( + + )} + + );