156 lines
4.9 KiB
TypeScript
156 lines
4.9 KiB
TypeScript
import Loader from '@/components/Loader';
|
|
|
|
import styles from './styles.module.scss';
|
|
|
|
import cn from 'classnames';
|
|
import { EPlacementKeys, IPaywallProduct } from '@/api/resources/Paywall';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { Dispatch, LegacyRef, SetStateAction, useEffect, useMemo, useRef, useState } from 'react';
|
|
import { loadStripe, Stripe } from '@stripe/stripe-js';
|
|
import { usePaywall } from '@/hooks/paywall/usePaywall';
|
|
import { useMakePayment } from '@/hooks/payment/useMakePayment';
|
|
import { getFormattedPrice } from '@/utils/price.utils';
|
|
import routes from '@/routes';
|
|
import Title from '@/components/Title';
|
|
import { Elements } from '@stripe/react-stripe-js';
|
|
import ExpressCheckoutStripe from '@/components/PaymentPage/methods/ExpressCheckoutStripe';
|
|
import SecurityPayments from '@/components/pages/TrialPayment/components/SecurityPayments';
|
|
import PaymentCardModal from '@/components/PaymentModalNew/PaymentCardModal';
|
|
import CreditCardIcon from '@/components/PaymentModalNew/PaymentCardModal/CreditCardIcon';
|
|
|
|
interface IPaymentModalNewProps {
|
|
returnUrl: string;
|
|
placementKey: EPlacementKeys;
|
|
activeProduct: IPaywallProduct;
|
|
setHeight?: Dispatch<SetStateAction<number>>;
|
|
}
|
|
|
|
export default function PaymentModalNew({
|
|
returnUrl,
|
|
activeProduct,
|
|
placementKey,
|
|
setHeight,
|
|
}: IPaymentModalNewProps) {
|
|
const navigate = useNavigate();
|
|
const ref = useRef<HTMLDivElement>();
|
|
const [stripePromise, setStripePromise] =
|
|
useState<Promise<Stripe | null> | null>(null);
|
|
|
|
const {products, placementId, paywallId} = usePaywall({
|
|
placementKey,
|
|
});
|
|
|
|
const [isOpenCardModal, setIsOpenCardModal] = useState(false);
|
|
|
|
const {
|
|
paymentIntentId,
|
|
clientSecret,
|
|
returnUrl: checkoutUrl,
|
|
paymentType,
|
|
publicKey,
|
|
isLoading: isLoadingPayment,
|
|
error,
|
|
} = useMakePayment({
|
|
productId: activeProduct?._id || '',
|
|
placementId,
|
|
paywallId,
|
|
returnPaidUrl: returnUrl,
|
|
});
|
|
|
|
const [isLoadingExpressCheckout, setIsLoadingExpressCheckout] =
|
|
useState(true);
|
|
|
|
const isLoading = useMemo(() => {
|
|
return isLoadingPayment || isLoadingExpressCheckout;
|
|
}, [isLoadingPayment, isLoadingExpressCheckout]);
|
|
|
|
if (checkoutUrl?.length) {
|
|
window.location.href = checkoutUrl;
|
|
}
|
|
|
|
useEffect(() => {
|
|
(async () => {
|
|
if (!products?.length || !publicKey) return;
|
|
setStripePromise(loadStripe(publicKey));
|
|
const isActiveProduct = products.find(
|
|
(product) => product._id === activeProduct?._id,
|
|
);
|
|
if (!activeProduct || !isActiveProduct) {
|
|
navigate(routes.client.trialChoice());
|
|
}
|
|
})();
|
|
}, [activeProduct, navigate, products, publicKey]);
|
|
|
|
const resizeHandler = () => {
|
|
setHeight?.(ref?.current?.clientHeight || 32);
|
|
};
|
|
|
|
if (error?.length) {
|
|
setTimeout(resizeHandler, 300);
|
|
return (
|
|
<div ref={ref as LegacyRef<HTMLDivElement>} className={styles['payment-modal']}>
|
|
<Title variant="h3" className={styles.title}>
|
|
Something went wrong
|
|
</Title>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div ref={ref as LegacyRef<HTMLDivElement>}
|
|
className={cn(styles.paymentModalContainer, isLoading && styles.paymentModalContainerLoading)}>
|
|
{isLoading && <div className={cn(styles.paymentModalLoader)}>
|
|
<Loader/>
|
|
</div>
|
|
}
|
|
|
|
<div className={styles.paymentModalPrice}>Total due today:
|
|
${getFormattedPrice(activeProduct.trialPrice)}</div>
|
|
|
|
{!isLoadingPayment &&
|
|
<>
|
|
{!isLoading &&
|
|
<div className={styles.paymentCreditCard} onClick={() => setIsOpenCardModal(true)}>
|
|
<CreditCardIcon/>
|
|
<div>Credit / Debit Card</div>
|
|
</div>
|
|
}
|
|
<Elements stripe={stripePromise} options={{clientSecret}}>
|
|
<ExpressCheckoutStripe
|
|
clientSecret={clientSecret!}
|
|
returnUrl={returnUrl}
|
|
paymentMethodOrderList={['google_pay', 'apple_pay', 'link']}
|
|
onChangeLoading={(isLoading) => {
|
|
setIsLoadingExpressCheckout(isLoading);
|
|
setTimeout(resizeHandler, 300);
|
|
}
|
|
}
|
|
/>
|
|
</Elements>
|
|
|
|
<PaymentCardModal
|
|
isOpen={isOpenCardModal}
|
|
setIsOpen={setIsOpenCardModal}
|
|
clientSecret={clientSecret}
|
|
stripePromise={stripePromise}
|
|
paymentType={paymentType}
|
|
paymentIntentId={paymentIntentId}
|
|
returnUrl={returnUrl}
|
|
/>
|
|
{!isLoading &&
|
|
<>
|
|
<div className={styles.infoContainer}>
|
|
<SecurityPayments/>
|
|
<p className={styles.address}>1123 Rimer Dr Moraga, California 94556</p>
|
|
</div>
|
|
</>
|
|
}
|
|
</>
|
|
}
|
|
|
|
|
|
</div>
|
|
);
|
|
}
|
|
|