Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / packages / components / containers / payments / methods / PaymentMethodsSection.tsx
blob39fbd47822cb25e2de611f264581ee94a4ca6119
1 import { c } from 'ttag';
3 import { usePaymentMethods } from '@proton/account/paymentMethods/hooks';
4 import { useSubscription } from '@proton/account/subscription/hooks';
5 import { useUser } from '@proton/account/user/hooks';
6 import type { ButtonProps } from '@proton/atoms';
7 import { Button } from '@proton/atoms';
8 import Icon from '@proton/components/components/icon/Icon';
9 import Loader from '@proton/components/components/loader/Loader';
10 import useModalState from '@proton/components/components/modalTwo/useModalState';
11 import MozillaInfoPanel from '@proton/components/containers/account/MozillaInfoPanel';
12 import SettingsParagraph from '@proton/components/containers/account/SettingsParagraph';
13 import SettingsSection from '@proton/components/containers/account/SettingsSection';
14 import useConfig from '@proton/components/hooks/useConfig';
15 import useMozillaCheck from '@proton/components/hooks/useMozillaCheck';
16 import { useChargebeeEnabledCache } from '@proton/components/payments/client-extensions/useChargebeeContext';
17 import { usePollEvents } from '@proton/components/payments/client-extensions/usePollEvents';
18 import useLoading from '@proton/hooks/useLoading';
19 import {
20     MethodStorage,
21     PAYMENT_METHOD_TYPES,
22     type SavedPaymentMethod,
23     isOnSessionMigration,
24     isSplittedUser,
25 } from '@proton/payments';
26 import { APPS, EVENT_ACTIONS } from '@proton/shared/lib/constants';
27 import { getKnowledgeBaseUrl } from '@proton/shared/lib/helpers/url';
28 import { ChargebeeEnabled } from '@proton/shared/lib/interfaces';
30 import { useRedirectToAccountApp } from '../../desktop/useRedirectToAccountApp';
31 import EditCardModal from '../EditCardModal';
32 import { default as PayPalV4Modal, PayPalV5Modal } from '../PayPalModal';
33 import PaymentMethodsTable from './PaymentMethodsTable';
35 const AddPaypalButton = ({ onClick, ...rest }: ButtonProps) => {
36     return (
37         <Button shape="outline" onClick={onClick} {...rest}>
38             <Icon name="brand-paypal" className="mr-2" />
39             <span>{c('Action').t`Add PayPal`}</span>
40         </Button>
41     );
44 const PaymentMethodsSection = () => {
45     const { APP_NAME } = useConfig();
46     const [paymentMethods = [], loadingPaymentMethods] = usePaymentMethods();
47     const [isManagedByMozilla, loadingCheck] = useMozillaCheck();
48     const [creditCardModalProps, setCreditCardModalOpen, renderCreditCardModal] = useModalState();
49     const [paypalV4ModalProps, setPaypalV4ModalOpen, renderPaypalV4Modal] = useModalState();
50     const [paypalV5ModalProps, setPaypalV5ModalOpen, renderPaypalV5Modal] = useModalState();
51     const isChargebeeEnabled = useChargebeeEnabledCache();
52     const [subscription] = useSubscription();
53     const [user] = useUser();
54     const pollPaymentMethodsCreate = usePollEvents({
55         subscribeToProperty: 'PaymentMethods',
56         action: EVENT_ACTIONS.CREATE,
57     });
58     const [pollingEvents, withPollingEvents] = useLoading();
59     const redirectToAccountApp = useRedirectToAccountApp();
61     if (loadingPaymentMethods || loadingCheck) {
62         return <Loader />;
63     }
65     if (isManagedByMozilla) {
66         return <MozillaInfoPanel />;
67     }
69     const learnMoreUrl =
70         APP_NAME === APPS.PROTONVPN_SETTINGS
71             ? 'https://protonvpn.com/support/payment-options/'
72             : getKnowledgeBaseUrl('/payment-options');
74     const canAddV4 =
75         isChargebeeEnabled() !== ChargebeeEnabled.CHARGEBEE_FORCED ||
76         (isOnSessionMigration(user.ChargebeeUser, subscription?.BillingPlatform) &&
77             !isSplittedUser(user.ChargebeeUser, user.ChargebeeUserExists, subscription?.BillingPlatform));
79     const paypalPredicate = (method: SavedPaymentMethod) =>
80         method.Type === PAYMENT_METHOD_TYPES.PAYPAL &&
81         (method.External === MethodStorage.INTERNAL || method.External === MethodStorage.EXTERNAL);
83     const canAddPaypalV4 = !paymentMethods.some(paypalPredicate) && canAddV4;
84     const canAddPaypalV5 = !paymentMethods.some(paypalPredicate) && !canAddV4;
86     const loadAddedMethod = () => {
87         void withPollingEvents(pollPaymentMethodsCreate());
88     };
90     return (
91         <SettingsSection>
92             <SettingsParagraph learnMoreUrl={learnMoreUrl}>
93                 {c('Info for payment methods')
94                     .t`You can add a payment method to have your subscription renewed automatically. Other payment methods are also available.`}
95             </SettingsParagraph>
96             <div className="mb-4">
97                 <Button
98                     shape="outline"
99                     className="mr-4"
100                     disabled={pollingEvents}
101                     onClick={() => {
102                         if (redirectToAccountApp()) {
103                             return;
104                         }
106                         setCreditCardModalOpen(true);
107                     }}
108                 >
109                     <Icon name="credit-card" className="mr-2" />
110                     <span>{c('Action').t`Add credit / debit card`}</span>
111                 </Button>
112                 {canAddPaypalV4 && (
113                     <AddPaypalButton
114                         disabled={pollingEvents}
115                         onClick={() => {
116                             if (redirectToAccountApp()) {
117                                 return;
118                             }
120                             setPaypalV4ModalOpen(true);
121                         }}
122                     />
123                 )}
124                 {canAddPaypalV5 && (
125                     <AddPaypalButton
126                         disabled={pollingEvents}
127                         onClick={() => {
128                             if (redirectToAccountApp()) {
129                                 return;
130                             }
132                             setPaypalV5ModalOpen(true);
133                         }}
134                     />
135                 )}
136             </div>
137             <PaymentMethodsTable loading={pollingEvents} methods={paymentMethods} />
138             {renderCreditCardModal && <EditCardModal onMethodAdded={loadAddedMethod} {...creditCardModalProps} />}
139             {renderPaypalV4Modal && <PayPalV4Modal {...paypalV4ModalProps} />}
140             {renderPaypalV5Modal && <PayPalV5Modal onMethodAdded={loadAddedMethod} {...paypalV5ModalProps} />}
141         </SettingsSection>
142     );
145 export default PaymentMethodsSection;