1 import type { ReactNode } from 'react';
2 import { useState } from 'react';
4 import { c } from 'ttag';
6 import { useSubscription } from '@proton/account/subscription/hooks';
7 import { Button } from '@proton/atoms';
8 import PrimaryButton from '@proton/components/components/button/PrimaryButton';
9 import type { ModalProps } from '@proton/components/components/modalTwo/Modal';
10 import Prompt from '@proton/components/components/prompt/Prompt';
11 import Toggle from '@proton/components/components/toggle/Toggle';
12 import { Autopay } from '@proton/payments';
13 import { getHasConsumerVpnPlan } from '@proton/shared/lib/helpers/subscription';
15 import { useModalTwo } from '../../components/modalTwo/useModalTwo';
17 type DisableRenewModalOwnProps = { isVPNPlan: boolean };
18 type DisableRenewModalPromiseProps = { onResolve: (result: boolean) => void; onReject: () => void };
19 type DisableRenewModalProps = ModalProps & DisableRenewModalPromiseProps & DisableRenewModalOwnProps;
21 export const DisableRenewModal = ({ isVPNPlan, onResolve, onReject, ...rest }: DisableRenewModalProps) => {
24 data-testid="disable-renew-modal"
25 title={c('Subscription renewal state').t`Are you sure?`}
27 <Button data-testid="action-disable-autopay" onClick={() => onResolve(true)}>{c(
28 'Subscription renewal state'
29 ).t`Disable`}</Button>,
30 <PrimaryButton data-testid="action-keep-autopay" onClick={() => onResolve(false)}>{c(
31 'Subscription renewal state'
32 ).t`Keep auto-pay`}</PrimaryButton>,
38 ? c('Subscription renewal state')
39 .t`Our system will no longer auto-charge you using this payment method, but your subscription will still renew at the end of the billing cycle. If you want to downgrade or change your subscription, you still need to do that yourself before the end of the billing period. Furthermore, if you forget to make a manual payment and auto-pay is disabled for all payment methods, we may auto-downgrade your account which will lead to the loss of many features.`
40 : c('Subscription renewal state')
41 .t`Our system will no longer auto-charge you using this payment method, but your subscription will still renew at the end of the billing cycle. If you want to downgrade or change your subscription, you still need to do that yourself before the end of the billing period. We cannot auto-downgrade you because if you are over free plan storage quota or using other paid features, we cannot auto delete files, emails, or other data for you. If you disable automatic payment, remember to pay your next subscription invoice before the due date to prevent account suspension.`}
47 export interface UseRenewToggleOptions {
48 initialRenewState?: Autopay;
51 export interface UseRenewToggleResult {
52 onChange: () => Promise<Autopay | null>;
53 disableRenewModal: ReactNode | null;
55 setRenewState: (newState: Autopay) => void;
58 export const useRenewToggle = ({ initialRenewState = Autopay.ENABLE }: UseRenewToggleOptions): UseRenewToggleResult => {
59 const [subscription] = useSubscription();
60 const isVPNPlan = getHasConsumerVpnPlan(subscription);
62 const [disableRenewModal, showDisableRenewModal] = useModalTwo(DisableRenewModal);
64 const [renewState, setRenewState] = useState(initialRenewState);
65 const onChange = async (): Promise<Autopay | null> => {
66 let newState: Autopay;
67 if (renewState === Autopay.ENABLE) {
68 const userDecidedDisable = await showDisableRenewModal({ isVPNPlan });
69 if (!userDecidedDisable) {
73 newState = Autopay.DISABLE;
75 newState = Autopay.ENABLE;
78 setRenewState(newState);
82 return { onChange, disableRenewModal, renewState, setRenewState };
88 } & Pick<UseRenewToggleResult, 'renewState' | 'disableRenewModal'>;
90 const RenewToggle = ({ renewState, onChange, disableRenewModal, loading }: Props) => {
91 const toggleId = 'toggle-subscription-renew';
92 const checked = renewState === Autopay.ENABLE;
97 <div className="flex justify-space-between mx-2">
98 <label htmlFor={toggleId}>
99 <span>{c('Subscription renewal state').t`Enable auto-pay support`}</span>
106 data-testid="toggle-subscription-renew"
113 export default RenewToggle;