1 import { type FC, useEffect, useMemo } from 'react';
2 import { useSelector } from 'react-redux';
4 import { c } from 'ttag';
6 import { Button } from '@proton/atoms';
7 import { getSimplePriceString } from '@proton/components/components/price/helper';
8 import { ProtonLogo } from '@proton/components/index';
9 import { useConnectivity } from '@proton/pass/components/Core/ConnectivityProvider';
10 import type { BaseSpotlightMessage } from '@proton/pass/components/Spotlight/SpotlightContent';
12 PASS_FAMILY_BF_2024_MONTHLY_PRICE,
13 PASS_LIFETIME_BF_2024_YEARLY_PRICE,
15 } from '@proton/pass/constants';
16 import { useFeatureFlag } from '@proton/pass/hooks/useFeatureFlag';
17 import { useNavigateToUpgrade } from '@proton/pass/hooks/useNavigateToUpgrade';
18 import { selectUser, selectUserPlan } from '@proton/pass/store/selectors';
19 import type { MaybeNull } from '@proton/pass/types';
20 import { PassFeature } from '@proton/pass/types/api/features';
21 import { pipe } from '@proton/pass/utils/fp/pipe';
22 import { DEFAULT_CURRENCY } from '@proton/payments';
23 import clsx from '@proton/utils/clsx';
24 import noop from '@proton/utils/noop';
26 import './BlackFriday2024Offer.scss';
28 type BF2024Offer = PassFeature.PassBlackFriday2024Family | PassFeature.PassBlackFriday2024Lifetime;
30 /** FIXME: move to `@proton/pass/components/Onboarding` in 1.25.0 */
31 export const BlackFriday2024Offer: FC<BaseSpotlightMessage> = ({ onClose = noop }) => {
32 const online = useConnectivity();
34 const user = useSelector(selectUser);
35 const userPlan = useSelector(selectUserPlan);
36 const lifetime = useFeatureFlag(PassFeature.PassBlackFriday2024Lifetime);
37 const family = useFeatureFlag(PassFeature.PassBlackFriday2024Family);
39 const offer = useMemo<MaybeNull<BF2024Offer>>(() => {
40 switch (userPlan?.InternalName) {
42 return family ? PassFeature.PassBlackFriday2024Family : null;
44 return lifetime ? PassFeature.PassBlackFriday2024Lifetime : null;
50 const content = useMemo(() => {
51 const currency = user?.Currency ?? DEFAULT_CURRENCY;
54 case PassFeature.PassBlackFriday2024Family: {
55 const relativePrice = (
56 <span className="text-nowrap" key="family-price">
57 {getSimplePriceString(currency, PASS_FAMILY_BF_2024_MONTHLY_PRICE)}
62 <strong key="discount" className="pass-bf2024-banner--offer px-0.5">
67 title: c('bf2024: Title')
68 .jt`Save up to ${discountJSX} on Pass Family. Only ${relativePrice}/month.`,
69 subtitle: c('bf2024: Info').t`All premium features. 6 users. 1 easy subscription.`,
73 case PassFeature.PassBlackFriday2024Lifetime: {
74 const relativePrice = (
75 <span className="text-nowrap" key="lifetime-price">
76 {getSimplePriceString(currency, PASS_LIFETIME_BF_2024_YEARLY_PRICE)}
80 const lifetimeAccessJSX = (
81 <strong key="deal" className="pass-bf2024-banner--offer px-0.5">
82 {c('bf2024: Deal').t`lifetime access`}
87 title: c('bf2024: Title')
88 .jt`Pay once and get ${lifetimeAccessJSX} to Pass Plus and SimpleLogin. Only ${relativePrice}.`,
89 subtitle: c('bf2024: Info').t`Limited-stock available!`,
95 const upgrade = useNavigateToUpgrade(
96 offer === PassFeature.PassBlackFriday2024Family
101 plan: 'passfamily2024',
103 upsellRef: UpsellRef.PASS_FAMILY_BF_2024,
107 plan: 'passlifetime2024',
110 upsellRef: UpsellRef.PASS_LIFETIME_BF_2024,
115 /* If the user upgraded in the background */
116 if (!offer) onClose();
122 <div className="flex items-center w-full z-up">
123 <div className="flex flex-column gap-2 w-2/3">
124 <div className="flex gap-2 items-center text-sm">
125 <ProtonLogo size={10} className="h-custom" style={{ '--h-custom': '1.5em' }} color="invert" />{' '}
126 <strong className="pass-bf2024-banner--badge lh120 px-1.5 py-0.5 text-uppercase">
127 {c('bf2024: Title').t`Black Friday`}
131 <strong className="block text-sm">{content.title}</strong>
132 <span className="block text-sm">{content.subtitle}</span>
135 <div className="flex flex-1 justify-end pr-8">
143 'pass-bf2024-banner--btn text-sm text-semibold px-3',
144 offer === PassFeature.PassBlackFriday2024Lifetime && 'pass-bf2024-banner--btn--deal'
146 onClick={pipe(onClose, upgrade)}
147 style={{ backgroundColor: 'var(--interaction-norm-major-3)' }}
149 {c('bf2024: Label').t`Get the deal`}