From 2178c7572922b000bc2fed1d29789df544dc5e3e Mon Sep 17 00:00:00 2001 From: Guilherme Popolin Date: Mon, 3 Jul 2023 14:40:55 +0200 Subject: [PATCH 1/4] feat(OfferPresenter): display discount --- .../CartInventory/CartInventory.helpers.tsx | 26 -------- .../CartInventory/CartInventory.tsx | 6 +- .../ConfirmationPage.stories.tsx | 14 +++++ .../PurchaseForm/OfferPresenter.tsx | 63 +++++++++++++------ .../src/graphql/ProductOfferFragment.graphql | 14 +++++ apps/store/src/pages/cart.tsx | 2 +- apps/store/src/pages/checkout/index.tsx | 2 +- .../store/src/utils/useDiscountExplanation.ts | 29 +++++++++ packages/ui/src/components/Text/Text.tsx | 4 +- 9 files changed, 107 insertions(+), 53 deletions(-) create mode 100644 apps/store/src/utils/useDiscountExplanation.ts diff --git a/apps/store/src/components/CartInventory/CartInventory.helpers.tsx b/apps/store/src/components/CartInventory/CartInventory.helpers.tsx index 80d77aa5a1..e853d34279 100644 --- a/apps/store/src/components/CartInventory/CartInventory.helpers.tsx +++ b/apps/store/src/components/CartInventory/CartInventory.helpers.tsx @@ -10,32 +10,6 @@ import { Money } from '@/utils/formatter' import { useFormatter } from '@/utils/useFormatter' import { CartEntry } from './CartInventory.types' -export const useGetDiscountExplanation = () => { - const { t } = useTranslation('cart') - const formatter = useFormatter() - - return (discount: CampaignDiscount) => { - switch (discount.type) { - case CampaignDiscountType.MonthlyCost: - return `-${formatter.monthlyPrice(discount.amount)}` - - case CampaignDiscountType.FreeMonths: - return t('DISCOUNT_STATE_FREE_MONTHS', { count: discount.months }) - - case CampaignDiscountType.MonthlyPercentage: - return t('DISCOUNT_STATE_MONTHLY_PERCENTAGE', { - percentage: discount.percentage, - count: discount.months, - }) - - case CampaignDiscountType.IndefinitePercentage: - return t('DISCOUNT_STATE_INDEFINITE_PERCENTAGE', { - percentage: discount.percentage, - }) - } - } -} - export const useGetDiscountDurationExplanation = () => { const { t } = useTranslation('cart') const formatter = useFormatter() diff --git a/apps/store/src/components/CartInventory/CartInventory.tsx b/apps/store/src/components/CartInventory/CartInventory.tsx index 50d62779df..0b072e3774 100644 --- a/apps/store/src/components/CartInventory/CartInventory.tsx +++ b/apps/store/src/components/CartInventory/CartInventory.tsx @@ -2,13 +2,11 @@ import styled from '@emotion/styled' import { Space, theme } from 'ui' import { CampaignDiscountType, CartFragmentFragment } from '@/services/apollo/generated' import { convertToDate } from '@/utils/date' +import { useGetDiscountExplanation } from '@/utils/useDiscountExplanation' import { CampaignsSection } from './CampaignsSection' import { CartEntryItem } from './CartEntryItem/CartEntryItem' import { CartEntryList } from './CartEntryList' -import { - useGetDiscountDurationExplanation, - useGetDiscountExplanation, -} from './CartInventory.helpers' +import { useGetDiscountDurationExplanation } from './CartInventory.helpers' import { CostSummary } from './CostSummary' import { ReadOnlyCampaignCodeList } from './ReadOnlyCampaignCodeList' diff --git a/apps/store/src/components/ConfirmationPage/ConfirmationPage.stories.tsx b/apps/store/src/components/ConfirmationPage/ConfirmationPage.stories.tsx index 4c67a10a61..ab64fcd9be 100644 --- a/apps/store/src/components/ConfirmationPage/ConfirmationPage.stories.tsx +++ b/apps/store/src/components/ConfirmationPage/ConfirmationPage.stories.tsx @@ -100,6 +100,20 @@ const cart = { amount: 125, currencyCode: CurrencyCode.Sek, }, + cost: { + gross: { + amount: 125, + currencyCode: CurrencyCode.Sek, + }, + net: { + amount: 125, + currencyCode: CurrencyCode.Sek, + }, + discount: { + amount: 0, + currencyCode: CurrencyCode.Sek, + }, + }, cancellation: { option: ExternalInsuranceCancellationOption.None, requested: false, diff --git a/apps/store/src/components/ProductPage/PurchaseForm/OfferPresenter.tsx b/apps/store/src/components/ProductPage/PurchaseForm/OfferPresenter.tsx index 194a65df4f..a4265921ad 100644 --- a/apps/store/src/components/ProductPage/PurchaseForm/OfferPresenter.tsx +++ b/apps/store/src/components/ProductPage/PurchaseForm/OfferPresenter.tsx @@ -13,12 +13,14 @@ import { SpaceFlex } from '@/components/SpaceFlex/SpaceFlex' import { ExternalInsuranceCancellationOption, ProductOfferFragment, + RedeemedCampaign, } from '@/services/apollo/generated' import { PriceIntent } from '@/services/priceIntent/priceIntent.types' import { ShopSession } from '@/services/shopSession/ShopSession.types' import { useTracking } from '@/services/Tracking/useTracking' import { convertToDate } from '@/utils/date' import { PageLink } from '@/utils/PageLink' +import { useGetDiscountExplanation } from '@/utils/useDiscountExplanation' import { useFormatter } from '@/utils/useFormatter' import { CancellationForm, CancellationOption } from './CancellationForm/CancellationForm' import { ComparisonTableModal } from './ComparisonTableModal' @@ -51,6 +53,7 @@ export const OfferPresenter = (props: Props) => { const [, setSelectedOffer] = useSelectedOffer() const { t } = useTranslation('purchase-form') const formatter = useFormatter() + const getDiscountExplanation = useGetDiscountExplanation() const [addToCartRedirect, setAddToCartRedirect] = useState(null) const handleOfferChange = (offerId: string) => { @@ -100,7 +103,9 @@ export const OfferPresenter = (props: Props) => { const [handleUpdateCancellation, updateCancellationInfo] = useUpdateCancellation({ priceIntent }) - const displayPrice = formatter.monthlyPrice(selectedOffer.price) + const crossedOutPrice = + selectedOffer.cost.discount.amount > 0 ? formatter.monthlyPrice(selectedOffer.cost.gross) : null + const displayPrice = formatter.monthlyPrice(selectedOffer.cost.net) const cancellationOption = getCancellationOption({ priceIntent, @@ -111,28 +116,39 @@ export const OfferPresenter = (props: Props) => { loadingAddToCart || updateCancellationInfo.loading || updateStartDateResult.loading const discountTooltipProps = useMemo(() => { - if (!selectedOffer.priceMatch) return null + if (selectedOffer.priceMatch) { + const company = selectedOffer.priceMatch.externalInsurer.displayName + + if (selectedOffer.priceMatch.priceReduction.amount < 1) { + // No price reduction due to incomparable offers + const amount = formatter.monthlyPrice(selectedOffer.priceMatch.externalPrice) + return { + children: t('PRICE_MATCH_BUBBLE_INCOMPARABLE_TITLE', { amount, company }), + subtitle: t('PRICE_MATCH_BUBBLE_INCOMPARABLE_SUBTITLE'), + color: 'gray', + } as const + } - const company = selectedOffer.priceMatch.externalInsurer.displayName + const priceReduction = formatter.monthlyPrice(selectedOffer.priceMatch.priceReduction) - if (selectedOffer.priceMatch.priceReduction.amount < 1) { - // No price reduction due to incomparable offers - const amount = formatter.monthlyPrice(selectedOffer.priceMatch.externalPrice) return { - children: t('PRICE_MATCH_BUBBLE_INCOMPARABLE_TITLE', { amount, company }), - subtitle: t('PRICE_MATCH_BUBBLE_INCOMPARABLE_SUBTITLE'), - color: 'gray', + children: t('PRICE_MATCH_BUBBLE_SUCCESS_TITLE', { amount: priceReduction }), + subtitle: t('PRICE_MATCH_BUBBLE_SUCCESS_SUBTITLE', { company }), + color: 'green', } as const } - const priceReduction = formatter.monthlyPrice(selectedOffer.priceMatch.priceReduction) - - return { - children: t('PRICE_MATCH_BUBBLE_SUCCESS_TITLE', { amount: priceReduction }), - subtitle: t('PRICE_MATCH_BUBBLE_SUCCESS_SUBTITLE', { company }), - color: 'green', - } as const - }, [selectedOffer.priceMatch, formatter, t]) + const redeemedCampaign = shopSession.cart.redeemedCampaigns[0] as RedeemedCampaign | undefined + if (redeemedCampaign && selectedOffer.cost.discount.amount > 0) { + return { + children: getDiscountExplanation({ + ...redeemedCampaign.discount, + amount: selectedOffer.cost.discount, + }), + color: 'green', + } as const + } + }, [selectedOffer, formatter, getDiscountExplanation, shopSession, t]) const startDate = convertToDate(selectedOffer.startDate) @@ -182,9 +198,16 @@ export const OfferPresenter = (props: Props) => { {discountTooltipProps && } - - {displayPrice} - + + {crossedOutPrice && ( + + {crossedOutPrice} + + )} + + {displayPrice} + + diff --git a/apps/store/src/graphql/ProductOfferFragment.graphql b/apps/store/src/graphql/ProductOfferFragment.graphql index e403164eb4..26c08f7d89 100644 --- a/apps/store/src/graphql/ProductOfferFragment.graphql +++ b/apps/store/src/graphql/ProductOfferFragment.graphql @@ -26,6 +26,20 @@ fragment ProductOffer on ProductOffer { amount currencyCode } + cost { + gross { + amount + currencyCode + } + net { + amount + currencyCode + } + discount { + amount + currencyCode + } + } startDate cancellation { option diff --git a/apps/store/src/pages/cart.tsx b/apps/store/src/pages/cart.tsx index c411b01951..63aaf488e2 100644 --- a/apps/store/src/pages/cart.tsx +++ b/apps/store/src/pages/cart.tsx @@ -6,7 +6,6 @@ import { useMemo } from 'react' import { getCrossOut, useGetDiscountDurationExplanation, - useGetDiscountExplanation, getTotal, getCartEntry, } from '@/components/CartInventory/CartInventory.helpers' @@ -21,6 +20,7 @@ import { useShopSession } from '@/services/shopSession/ShopSessionContext' import { getGlobalStory } from '@/services/storyblok/storyblok' import { GLOBAL_STORY_PROP_NAME } from '@/services/storyblok/Storyblok.constant' import { isRoutingLocale } from '@/utils/l10n/localeUtils' +import { useGetDiscountExplanation } from '@/utils/useDiscountExplanation' const NextCartPage: NextPageWithLayout = (props) => { const { shopSession } = useShopSession() diff --git a/apps/store/src/pages/checkout/index.tsx b/apps/store/src/pages/checkout/index.tsx index 1f4bac3e87..07b3c297d3 100644 --- a/apps/store/src/pages/checkout/index.tsx +++ b/apps/store/src/pages/checkout/index.tsx @@ -7,7 +7,6 @@ import { getCrossOut, getTotal, useGetDiscountDurationExplanation, - useGetDiscountExplanation, } from '@/components/CartInventory/CartInventory.helpers' import { CheckoutStep } from '@/components/CheckoutHeader/Breadcrumbs' import { fetchCheckoutSteps } from '@/components/CheckoutHeader/CheckoutHeader.helpers' @@ -23,6 +22,7 @@ import { useShopSession } from '@/services/shopSession/ShopSessionContext' import { getShouldCollectEmail, getShouldCollectName } from '@/utils/customer' import { isRoutingLocale } from '@/utils/l10n/localeUtils' import { PageLink } from '@/utils/PageLink' +import { useGetDiscountExplanation } from '@/utils/useDiscountExplanation' type NextPageProps = Omit diff --git a/apps/store/src/utils/useDiscountExplanation.ts b/apps/store/src/utils/useDiscountExplanation.ts new file mode 100644 index 0000000000..5a5001ff8d --- /dev/null +++ b/apps/store/src/utils/useDiscountExplanation.ts @@ -0,0 +1,29 @@ +import { useTranslation } from 'next-i18next' +import { CampaignDiscount, CampaignDiscountType } from '@/services/apollo/generated' +import { useFormatter } from './useFormatter' + +export const useGetDiscountExplanation = () => { + const { t } = useTranslation('cart') + const formatter = useFormatter() + + return (discount: CampaignDiscount) => { + switch (discount.type) { + case CampaignDiscountType.MonthlyCost: + return `-${formatter.monthlyPrice(discount.amount)}` + + case CampaignDiscountType.FreeMonths: + return t('DISCOUNT_STATE_FREE_MONTHS', { count: discount.months }) + + case CampaignDiscountType.MonthlyPercentage: + return t('DISCOUNT_STATE_MONTHLY_PERCENTAGE', { + percentage: discount.percentage, + count: discount.months, + }) + + case CampaignDiscountType.IndefinitePercentage: + return t('DISCOUNT_STATE_INDEFINITE_PERCENTAGE', { + percentage: discount.percentage, + }) + } + } +} diff --git a/packages/ui/src/components/Text/Text.tsx b/packages/ui/src/components/Text/Text.tsx index fe61851a12..68044dbfd4 100644 --- a/packages/ui/src/components/Text/Text.tsx +++ b/packages/ui/src/components/Text/Text.tsx @@ -29,6 +29,7 @@ export type TextProps = { children?: ReactNode className?: string uppercase?: boolean + strikethrough?: boolean } const elementConfig = { @@ -38,11 +39,12 @@ const elementConfig = { export const TextBase = styled( Space, elementConfig, -)(({ align, color, size = 'md', uppercase = false }) => ({ +)(({ align, color, size = 'md', uppercase = false, strikethrough = false }) => ({ color: color ? theme.colors[color] : 'inherit', ...getFontSize(size), ...(align && { textAlign: align }), ...(uppercase && { textTransform: 'uppercase' }), + ...(strikethrough && { textDecorationLine: 'line-through' }), })) export const Text = ({ as, balance, children, className, ...rest }: TextProps) => ( From 7e24eff48133ddf833ac68b31c3f23ce4a2381cc Mon Sep 17 00:00:00 2001 From: Guilherme Popolin Date: Tue, 4 Jul 2023 10:26:00 +0200 Subject: [PATCH 2/4] refact(OfferPresenter): added useDiscountTooltipProps hook --- apps/store/public/locales/en/cart.json | 1 + apps/store/public/locales/sv-se/cart.json | 1 + .../DiscountTooltip/DiscountTooltip.tsx | 8 +- .../PurchaseForm/OfferPresenter.tsx | 106 ++++++++++-------- 4 files changed, 62 insertions(+), 54 deletions(-) diff --git a/apps/store/public/locales/en/cart.json b/apps/store/public/locales/en/cart.json index bf3a3bcb35..5d76e56a05 100644 --- a/apps/store/public/locales/en/cart.json +++ b/apps/store/public/locales/en/cart.json @@ -39,6 +39,7 @@ "DETAILS_SHEET_DISMISS_BUTTON": "Done", "DISCOUNT_DURATION_EXPLANATION_one": "For {{count}} month, then {{monthlyPrice}}", "DISCOUNT_DURATION_EXPLANATION_other": "for {{count}} months, then {{monthlyPrice}}", + "DISCOUNT_PRICE_AFTER_EXPIRATION": "Then you pay {{amount}}", "DISCOUNT_STATE_FREE_MONTHS_one": "Free for {{count}} month", "DISCOUNT_STATE_FREE_MONTHS_other": "Free for {{count}} months", "DISCOUNT_STATE_INDEFINITE_PERCENTAGE": "{{percentage}}% discount", diff --git a/apps/store/public/locales/sv-se/cart.json b/apps/store/public/locales/sv-se/cart.json index df13220992..9c441e2d3b 100644 --- a/apps/store/public/locales/sv-se/cart.json +++ b/apps/store/public/locales/sv-se/cart.json @@ -39,6 +39,7 @@ "DETAILS_SHEET_DISMISS_BUTTON": "Klar", "DISCOUNT_DURATION_EXPLANATION_one": "I {{count}} månad, sedan {{monthlyPrice}}", "DISCOUNT_DURATION_EXPLANATION_other": "i {{count}} månader, sedan {{monthlyPrice}}", + "DISCOUNT_PRICE_AFTER_EXPIRATION": "Sedan betalar du {{amount}}", "DISCOUNT_STATE_FREE_MONTHS_one": "Gratis i {{count}} månad", "DISCOUNT_STATE_FREE_MONTHS_other": "Gratis i {{count}} månader", "DISCOUNT_STATE_INDEFINITE_PERCENTAGE": "{{percentage}}% rabatt", diff --git a/apps/store/src/components/ProductPage/PurchaseForm/DiscountTooltip/DiscountTooltip.tsx b/apps/store/src/components/ProductPage/PurchaseForm/DiscountTooltip/DiscountTooltip.tsx index 94f3d02545..482b3d62df 100644 --- a/apps/store/src/components/ProductPage/PurchaseForm/DiscountTooltip/DiscountTooltip.tsx +++ b/apps/store/src/components/ProductPage/PurchaseForm/DiscountTooltip/DiscountTooltip.tsx @@ -13,15 +13,11 @@ export const DiscountTooltip = ({ children, subtitle, color = 'green' }: Props) return ( - + {children} {subtitle && ( - + {subtitle} )} diff --git a/apps/store/src/components/ProductPage/PurchaseForm/OfferPresenter.tsx b/apps/store/src/components/ProductPage/PurchaseForm/OfferPresenter.tsx index a4265921ad..22a442d4d9 100644 --- a/apps/store/src/components/ProductPage/PurchaseForm/OfferPresenter.tsx +++ b/apps/store/src/components/ProductPage/PurchaseForm/OfferPresenter.tsx @@ -53,7 +53,6 @@ export const OfferPresenter = (props: Props) => { const [, setSelectedOffer] = useSelectedOffer() const { t } = useTranslation('purchase-form') const formatter = useFormatter() - const getDiscountExplanation = useGetDiscountExplanation() const [addToCartRedirect, setAddToCartRedirect] = useState(null) const handleOfferChange = (offerId: string) => { @@ -103,8 +102,11 @@ export const OfferPresenter = (props: Props) => { const [handleUpdateCancellation, updateCancellationInfo] = useUpdateCancellation({ priceIntent }) - const crossedOutPrice = - selectedOffer.cost.discount.amount > 0 ? formatter.monthlyPrice(selectedOffer.cost.gross) : null + const discountTooltipProps = useDiscountTooltipProps( + selectedOffer, + shopSession.cart.redeemedCampaigns, + ) + const displayPrice = formatter.monthlyPrice(selectedOffer.cost.net) const cancellationOption = getCancellationOption({ @@ -115,41 +117,6 @@ export const OfferPresenter = (props: Props) => { const loading = loadingAddToCart || updateCancellationInfo.loading || updateStartDateResult.loading - const discountTooltipProps = useMemo(() => { - if (selectedOffer.priceMatch) { - const company = selectedOffer.priceMatch.externalInsurer.displayName - - if (selectedOffer.priceMatch.priceReduction.amount < 1) { - // No price reduction due to incomparable offers - const amount = formatter.monthlyPrice(selectedOffer.priceMatch.externalPrice) - return { - children: t('PRICE_MATCH_BUBBLE_INCOMPARABLE_TITLE', { amount, company }), - subtitle: t('PRICE_MATCH_BUBBLE_INCOMPARABLE_SUBTITLE'), - color: 'gray', - } as const - } - - const priceReduction = formatter.monthlyPrice(selectedOffer.priceMatch.priceReduction) - - return { - children: t('PRICE_MATCH_BUBBLE_SUCCESS_TITLE', { amount: priceReduction }), - subtitle: t('PRICE_MATCH_BUBBLE_SUCCESS_SUBTITLE', { company }), - color: 'green', - } as const - } - - const redeemedCampaign = shopSession.cart.redeemedCampaigns[0] as RedeemedCampaign | undefined - if (redeemedCampaign && selectedOffer.cost.discount.amount > 0) { - return { - children: getDiscountExplanation({ - ...redeemedCampaign.discount, - amount: selectedOffer.cost.discount, - }), - color: 'green', - } as const - } - }, [selectedOffer, formatter, getDiscountExplanation, shopSession, t]) - const startDate = convertToDate(selectedOffer.startDate) // Sort deductibles based on monthly price @@ -198,16 +165,9 @@ export const OfferPresenter = (props: Props) => { {discountTooltipProps && } - - {crossedOutPrice && ( - - {crossedOutPrice} - - )} - - {displayPrice} - - + + {displayPrice} + @@ -324,6 +284,56 @@ type GetCancellationOptionParams = { productOffer: ProductOfferFragment } +const useDiscountTooltipProps = ( + selectedOffer: ProductOfferFragment, + redeemedCampaigns?: Array, +) => { + const { t } = useTranslation(['purchase-form', 'cart']) + const formatter = useFormatter() + const getDiscountExplanation = useGetDiscountExplanation() + + const tooltipProps = useMemo(() => { + if (selectedOffer.priceMatch) { + const company = selectedOffer.priceMatch.externalInsurer.displayName + + if (selectedOffer.priceMatch.priceReduction.amount < 1) { + // No price reduction due to incomparable offers + const amount = formatter.monthlyPrice(selectedOffer.priceMatch.externalPrice) + return { + children: t('PRICE_MATCH_BUBBLE_INCOMPARABLE_TITLE', { amount, company }), + subtitle: t('PRICE_MATCH_BUBBLE_INCOMPARABLE_SUBTITLE'), + color: 'gray', + } as const + } + + const priceReduction = formatter.monthlyPrice(selectedOffer.priceMatch.priceReduction) + + return { + children: t('PRICE_MATCH_BUBBLE_SUCCESS_TITLE', { amount: priceReduction }), + subtitle: t('PRICE_MATCH_BUBBLE_SUCCESS_SUBTITLE', { company }), + color: 'green', + } as const + } + + const redeemedCampaign = redeemedCampaigns?.[0] + if (redeemedCampaign && selectedOffer.cost.discount.amount > 0) { + return { + children: getDiscountExplanation({ + ...redeemedCampaign.discount, + amount: selectedOffer.cost.discount, + }), + subtitle: t('DISCOUNT_PRICE_AFTER_EXPIRATION', { + amount: formatter.monthlyPrice(selectedOffer.cost.gross), + ns: 'cart', + }), + color: 'green', + } as const + } + }, [t, formatter, getDiscountExplanation, selectedOffer, redeemedCampaigns]) + + return tooltipProps +} + const getCancellationOption = (params: GetCancellationOptionParams): CancellationOption => { const { productOffer: { cancellation, startDate }, From 52c51b654e7c1d70cdbfd61b9dd953565d2690aa Mon Sep 17 00:00:00 2001 From: Guilherme Popolin Date: Wed, 5 Jul 2023 10:08:57 +0200 Subject: [PATCH 3/4] refact(OfferPresenter): hide changes under DISCOUNTS feature flag --- apps/store/.env.local.example | 1 + .../PurchaseForm/OfferPresenter.tsx | 31 ++++++++++--------- apps/store/src/utils/Features.ts | 1 + 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/apps/store/.env.local.example b/apps/store/.env.local.example index 33f3fc6a0b..cdb6eea64b 100644 --- a/apps/store/.env.local.example +++ b/apps/store/.env.local.example @@ -41,6 +41,7 @@ NEXT_PUBLIC_FEATURE_ENGLISH_LANGUAGE=true NEXT_PUBLIC_FEATURE_COUNTRY_SELECTOR=true NEXT_PUBLIC_FEATURE_SAS_PARTNERSHIP=true NEXT_PUBLIC_FEATURE_HOMECOMING=true +NEXT_PUBLIC_FEATURE_DISCOUNTS=true # Vercel Edge Config Connection String (https://github.com/vercel/edge-config) EDGE_CONFIG= diff --git a/apps/store/src/components/ProductPage/PurchaseForm/OfferPresenter.tsx b/apps/store/src/components/ProductPage/PurchaseForm/OfferPresenter.tsx index 22a442d4d9..795c5ef87e 100644 --- a/apps/store/src/components/ProductPage/PurchaseForm/OfferPresenter.tsx +++ b/apps/store/src/components/ProductPage/PurchaseForm/OfferPresenter.tsx @@ -19,6 +19,7 @@ import { PriceIntent } from '@/services/priceIntent/priceIntent.types' import { ShopSession } from '@/services/shopSession/ShopSession.types' import { useTracking } from '@/services/Tracking/useTracking' import { convertToDate } from '@/utils/date' +import { Features } from '@/utils/Features' import { PageLink } from '@/utils/PageLink' import { useGetDiscountExplanation } from '@/utils/useDiscountExplanation' import { useFormatter } from '@/utils/useFormatter' @@ -296,7 +297,7 @@ const useDiscountTooltipProps = ( if (selectedOffer.priceMatch) { const company = selectedOffer.priceMatch.externalInsurer.displayName - if (selectedOffer.priceMatch.priceReduction.amount < 1) { + if (selectedOffer.priceMatch.priceReduction.amount <= 0) { // No price reduction due to incomparable offers const amount = formatter.monthlyPrice(selectedOffer.priceMatch.externalPrice) return { @@ -315,19 +316,21 @@ const useDiscountTooltipProps = ( } as const } - const redeemedCampaign = redeemedCampaigns?.[0] - if (redeemedCampaign && selectedOffer.cost.discount.amount > 0) { - return { - children: getDiscountExplanation({ - ...redeemedCampaign.discount, - amount: selectedOffer.cost.discount, - }), - subtitle: t('DISCOUNT_PRICE_AFTER_EXPIRATION', { - amount: formatter.monthlyPrice(selectedOffer.cost.gross), - ns: 'cart', - }), - color: 'green', - } as const + if (Features.enabled('DISCOUNTS')) { + const redeemedCampaign = redeemedCampaigns?.[0] + if (redeemedCampaign && selectedOffer.cost.discount.amount > 0) { + return { + children: getDiscountExplanation({ + ...redeemedCampaign.discount, + amount: selectedOffer.cost.discount, + }), + subtitle: t('DISCOUNT_PRICE_AFTER_EXPIRATION', { + amount: formatter.monthlyPrice(selectedOffer.cost.gross), + ns: 'cart', + }), + color: 'green', + } as const + } } }, [t, formatter, getDiscountExplanation, selectedOffer, redeemedCampaigns]) diff --git a/apps/store/src/utils/Features.ts b/apps/store/src/utils/Features.ts index 456d810bc7..625e85c501 100644 --- a/apps/store/src/utils/Features.ts +++ b/apps/store/src/utils/Features.ts @@ -14,6 +14,7 @@ const config = { SAS_PARTNERSHIP: process.env.NEXT_PUBLIC_FEATURE_SAS_PARTNERSHIP === 'true', INSURELY_CAR: process.env.NEXT_PUBLIC_FEATURE_INSURELY_CAR === 'true', HOMECOMING: process.env.NEXT_PUBLIC_FEATURE_HOMECOMING === 'true', + DISCOUNTS: process.env.NEXT_PUBLIC_FEATURE_DISCOUNTS === 'true', } as const export type FeatureFlag = keyof typeof config From 7554ad2f55dfdd18716402042c4f31e734038953 Mon Sep 17 00:00:00 2001 From: Guilherme Popolin Date: Wed, 5 Jul 2023 16:25:36 +0200 Subject: [PATCH 4/4] Revert "refact(OfferPresenter): hide changes under DISCOUNTS feature flag" This reverts commit b109c6304f9d35cbbf4a40d2eefeb3fbc71d7ce5. --- apps/store/.env.local.example | 1 - .../PurchaseForm/OfferPresenter.tsx | 31 +++++++++---------- apps/store/src/utils/Features.ts | 1 - 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/apps/store/.env.local.example b/apps/store/.env.local.example index cdb6eea64b..33f3fc6a0b 100644 --- a/apps/store/.env.local.example +++ b/apps/store/.env.local.example @@ -41,7 +41,6 @@ NEXT_PUBLIC_FEATURE_ENGLISH_LANGUAGE=true NEXT_PUBLIC_FEATURE_COUNTRY_SELECTOR=true NEXT_PUBLIC_FEATURE_SAS_PARTNERSHIP=true NEXT_PUBLIC_FEATURE_HOMECOMING=true -NEXT_PUBLIC_FEATURE_DISCOUNTS=true # Vercel Edge Config Connection String (https://github.com/vercel/edge-config) EDGE_CONFIG= diff --git a/apps/store/src/components/ProductPage/PurchaseForm/OfferPresenter.tsx b/apps/store/src/components/ProductPage/PurchaseForm/OfferPresenter.tsx index 795c5ef87e..22a442d4d9 100644 --- a/apps/store/src/components/ProductPage/PurchaseForm/OfferPresenter.tsx +++ b/apps/store/src/components/ProductPage/PurchaseForm/OfferPresenter.tsx @@ -19,7 +19,6 @@ import { PriceIntent } from '@/services/priceIntent/priceIntent.types' import { ShopSession } from '@/services/shopSession/ShopSession.types' import { useTracking } from '@/services/Tracking/useTracking' import { convertToDate } from '@/utils/date' -import { Features } from '@/utils/Features' import { PageLink } from '@/utils/PageLink' import { useGetDiscountExplanation } from '@/utils/useDiscountExplanation' import { useFormatter } from '@/utils/useFormatter' @@ -297,7 +296,7 @@ const useDiscountTooltipProps = ( if (selectedOffer.priceMatch) { const company = selectedOffer.priceMatch.externalInsurer.displayName - if (selectedOffer.priceMatch.priceReduction.amount <= 0) { + if (selectedOffer.priceMatch.priceReduction.amount < 1) { // No price reduction due to incomparable offers const amount = formatter.monthlyPrice(selectedOffer.priceMatch.externalPrice) return { @@ -316,21 +315,19 @@ const useDiscountTooltipProps = ( } as const } - if (Features.enabled('DISCOUNTS')) { - const redeemedCampaign = redeemedCampaigns?.[0] - if (redeemedCampaign && selectedOffer.cost.discount.amount > 0) { - return { - children: getDiscountExplanation({ - ...redeemedCampaign.discount, - amount: selectedOffer.cost.discount, - }), - subtitle: t('DISCOUNT_PRICE_AFTER_EXPIRATION', { - amount: formatter.monthlyPrice(selectedOffer.cost.gross), - ns: 'cart', - }), - color: 'green', - } as const - } + const redeemedCampaign = redeemedCampaigns?.[0] + if (redeemedCampaign && selectedOffer.cost.discount.amount > 0) { + return { + children: getDiscountExplanation({ + ...redeemedCampaign.discount, + amount: selectedOffer.cost.discount, + }), + subtitle: t('DISCOUNT_PRICE_AFTER_EXPIRATION', { + amount: formatter.monthlyPrice(selectedOffer.cost.gross), + ns: 'cart', + }), + color: 'green', + } as const } }, [t, formatter, getDiscountExplanation, selectedOffer, redeemedCampaigns]) diff --git a/apps/store/src/utils/Features.ts b/apps/store/src/utils/Features.ts index 625e85c501..456d810bc7 100644 --- a/apps/store/src/utils/Features.ts +++ b/apps/store/src/utils/Features.ts @@ -14,7 +14,6 @@ const config = { SAS_PARTNERSHIP: process.env.NEXT_PUBLIC_FEATURE_SAS_PARTNERSHIP === 'true', INSURELY_CAR: process.env.NEXT_PUBLIC_FEATURE_INSURELY_CAR === 'true', HOMECOMING: process.env.NEXT_PUBLIC_FEATURE_HOMECOMING === 'true', - DISCOUNTS: process.env.NEXT_PUBLIC_FEATURE_DISCOUNTS === 'true', } as const export type FeatureFlag = keyof typeof config