276 lines
8.9 KiB
TypeScript
276 lines
8.9 KiB
TypeScript
import styles from "./styles.module.scss";
|
|
import Title from "@/components/Title";
|
|
import { addCurrency, ELocalesPlacement } from "@/locales";
|
|
import { getPriceCentsToDollars } from "@/services/price";
|
|
import { useSelector } from "react-redux";
|
|
import { selectors } from "@/store";
|
|
import Loader, { LoaderColor } from "@/components/Loader";
|
|
import { useCallback, useEffect, useState } from "react";
|
|
import { useApi } from "@/api";
|
|
import { useAuth } from "@/auth";
|
|
import { useNavigate } from "react-router-dom";
|
|
import routes from "@/routes";
|
|
import { loadStripe, Stripe } from "@stripe/stripe-js";
|
|
import { ResponseGet } from "@/api/resources/SinglePayment";
|
|
import { Elements } from "@stripe/react-stripe-js";
|
|
import CheckoutForm from "@/components/PaymentPage/methods/CheckoutForm";
|
|
import { useSinglePayment } from "@/hooks/payment/useSinglePayment";
|
|
import { useTranslations } from "@/hooks/translations";
|
|
import ThankYouBanner from "../../components/ThankYouBanner";
|
|
|
|
const currentProductKey = "skip.trial.subscription.aura";
|
|
const returnUrl = `${window.location.host}${routes.client.addConsultant()}`;
|
|
|
|
function SkipTrial() {
|
|
const { translate } = useTranslations(ELocalesPlacement.PalmistryV1);
|
|
const navigate = useNavigate();
|
|
const api = useApi();
|
|
const { token, user } = useAuth();
|
|
const currency = useSelector(selectors.selectCurrency);
|
|
const [price, setPrice] = useState(0);
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [stripePromise, setStripePromise] =
|
|
useState<Promise<Stripe | null> | null>(null);
|
|
const [stripePublicKey, setStripePublicKey] = useState<string>("");
|
|
const [clientSecret, setClientSecret] = useState<string | null>(null);
|
|
const [product, setProduct] = useState<ResponseGet>();
|
|
const { checkProductPurchased } = useSinglePayment();
|
|
|
|
const activeProductFromStore = useSelector(selectors.selectActiveProduct);
|
|
|
|
useEffect(() => {
|
|
(async () => {
|
|
const isPurchasedSkipTrial = await checkProductPurchased(
|
|
currentProductKey,
|
|
token
|
|
);
|
|
const isPurchasedPremiumBundle = await checkProductPurchased(
|
|
"premium.bundle.aura",
|
|
token
|
|
);
|
|
if (isPurchasedSkipTrial || isPurchasedPremiumBundle) {
|
|
return navigate(routes.client.addConsultant());
|
|
}
|
|
})();
|
|
}, [checkProductPurchased, navigate, token]);
|
|
|
|
useEffect(() => {
|
|
(async () => {
|
|
const products = await api.getSinglePaymentProducts({ token });
|
|
|
|
const product = products.find(
|
|
(product) => product.key === currentProductKey
|
|
);
|
|
|
|
if (product && product.price) {
|
|
setPrice(product?.price);
|
|
setProduct(product);
|
|
}
|
|
})();
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (!stripePublicKey) return;
|
|
|
|
setStripePromise(loadStripe(stripePublicKey));
|
|
}, [stripePublicKey]);
|
|
|
|
const goPremiumBundle = () => {
|
|
navigate(routes.client.addConsultant());
|
|
};
|
|
|
|
const buy = async () => {
|
|
if (!user?.id || !product) return;
|
|
|
|
const { _id, key } = product;
|
|
const paymentInfo = {
|
|
productId: _id,
|
|
key,
|
|
};
|
|
|
|
try {
|
|
setIsLoading(true);
|
|
const response = await api.createSinglePayment({
|
|
token: token,
|
|
data: {
|
|
user: {
|
|
id: user.id,
|
|
email: user.email,
|
|
name: user.username || "",
|
|
sign: user.profile?.sign?.sign || "",
|
|
age: user.profile.age?.years || 0,
|
|
},
|
|
partner: {
|
|
sign: "",
|
|
age: 0,
|
|
},
|
|
paymentInfo,
|
|
return_url: returnUrl,
|
|
},
|
|
});
|
|
|
|
if (
|
|
("paymentIntent" in response &&
|
|
response.paymentIntent.status === "paid") ||
|
|
("payment" in response && response.payment.status === "paid") ||
|
|
("invoiceId" in response && response.invoiceId === "paid")
|
|
) {
|
|
goPremiumBundle();
|
|
} else if ("paymentIntent" in response) {
|
|
setClientSecret(response.paymentIntent.data.client_secret);
|
|
setStripePublicKey(response.paymentIntent.data.public_key);
|
|
}
|
|
} catch (error) {
|
|
console.log("Error: ", error);
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
const getBenefits = useCallback(() => {
|
|
return Math.ceil(
|
|
Math.abs(
|
|
((price || 0) / ((activeProductFromStore?.price || 0) * 4) - 1) * 100
|
|
)
|
|
);
|
|
}, [activeProductFromStore?.price, price]);
|
|
|
|
return (
|
|
<>
|
|
<ThankYouBanner containerClassName={styles["thank-you"]} />
|
|
<Title className={styles.title} variant="h2">
|
|
{translate("/skip-trial.title")}
|
|
</Title>
|
|
|
|
<div className="discount-screen__blocks">
|
|
<section
|
|
className={`discount-screen__block ${styles["discount-screen__block"]}`}
|
|
>
|
|
<span className="discount-screen__price-block">
|
|
{translate("/skip-trial.price_per_week", {
|
|
price: addCurrency(
|
|
(activeProductFromStore?.price || 0) / 100,
|
|
currency
|
|
),
|
|
})}
|
|
</span>
|
|
|
|
<div className="discount-screen__details">
|
|
<span className="discount-screen__details-name">
|
|
{translate("/skip-trial.billing_period")}
|
|
</span>
|
|
<span className="discount-screen__details-value">
|
|
{translate("/skip-trial.start_trial.every_week")}
|
|
</span>
|
|
</div>
|
|
|
|
<div className="discount-screen__details">
|
|
<span className="discount-screen__details-name">
|
|
{translate("/skip-trial.billed_amount")}
|
|
</span>
|
|
<span className="discount-screen__details-value">
|
|
{addCurrency(
|
|
(activeProductFromStore?.price || 0) / 100,
|
|
currency
|
|
)}
|
|
</span>
|
|
</div>
|
|
|
|
<div className="discount-screen__details">
|
|
<span className="discount-screen__details-name">
|
|
{translate("/skip-trial.billed_in_4_weeks")}
|
|
</span>
|
|
<span className="discount-screen__details-value">
|
|
{addCurrency(
|
|
((activeProductFromStore?.price || 0) / 100) * 4,
|
|
currency
|
|
)}
|
|
</span>
|
|
</div>
|
|
|
|
<button
|
|
className={`discount-screen__button ${styles["discount-screen__button"]}`}
|
|
onClick={goPremiumBundle}
|
|
>
|
|
{translate("/skip-trial.start_trial.start_trial")}
|
|
</button>
|
|
</section>
|
|
|
|
<section
|
|
className={`discount-screen__block ${styles["discount-screen__block"]}`}
|
|
>
|
|
<div className="discount-screen__header-block">
|
|
{translate("/skip-trial.skip_trial.save", {
|
|
save: getBenefits(),
|
|
})}
|
|
</div>
|
|
|
|
<span className="discount-screen__price-block">
|
|
{translate("/skip-trial.price_per_week", {
|
|
price: addCurrency(
|
|
getPriceCentsToDollars((price || 0) / 4),
|
|
currency
|
|
),
|
|
})}
|
|
</span>
|
|
|
|
<div className="discount-screen__details">
|
|
<span className="discount-screen__details-name">
|
|
{translate("/skip-trial.billing_period")}
|
|
</span>
|
|
<span className="discount-screen__details-value">
|
|
{translate("/skip-trial.skip_trial.every_4_weeks")}
|
|
</span>
|
|
</div>
|
|
|
|
<div className="discount-screen__details">
|
|
<span className="discount-screen__details-name">
|
|
{translate("/skip-trial.billed_amount")}
|
|
</span>
|
|
<span className="discount-screen__details-value">
|
|
{addCurrency(getPriceCentsToDollars(price || 0), currency)}
|
|
</span>
|
|
</div>
|
|
|
|
<div className="discount-screen__details">
|
|
<span className="discount-screen__details-name">
|
|
{translate("/skip-trial.billed_in_4_weeks")}
|
|
</span>
|
|
<span className="discount-screen__details-value">
|
|
{addCurrency(getPriceCentsToDollars(price || 0), currency)}
|
|
</span>
|
|
</div>
|
|
|
|
<button
|
|
className={`discount-screen__button ${styles["discount-screen__button"]}`}
|
|
onClick={buy}
|
|
disabled={isLoading}
|
|
>
|
|
{isLoading ? (
|
|
<Loader
|
|
color={LoaderColor.White}
|
|
className="discount-screen__loader"
|
|
/>
|
|
) : (
|
|
<span style={{ maxWidth: "100px" }}>
|
|
{translate("/skip-trial.skip_trial.skip_trial")}
|
|
</span>
|
|
)}
|
|
</button>
|
|
</section>
|
|
</div>
|
|
|
|
{stripePromise && clientSecret && (
|
|
<div className={`discount-screen__widget`}>
|
|
<Elements stripe={stripePromise} options={{ clientSecret }}>
|
|
<CheckoutForm returnUrl={returnUrl} />
|
|
</Elements>
|
|
</div>
|
|
)}
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default SkipTrial;
|