134 lines
4.3 KiB
TypeScript
134 lines
4.3 KiB
TypeScript
import Title from "@/components/Title";
|
|
import styles from "./styles.module.css";
|
|
import ConsultationTable from "../../components/ConsultationTable";
|
|
import PaymentAddress from "../../components/PaymentAddress";
|
|
import FooterButton from "../../components/FooterButton";
|
|
import { useNavigate } from "react-router-dom";
|
|
import routes from "@/routes";
|
|
import { useAuth } from "@/auth";
|
|
import { SinglePayment, useApi, useApiCall } from "@/api";
|
|
import { useSelector } from "react-redux";
|
|
import { selectors } from "@/store";
|
|
import { useCallback, useState } from "react";
|
|
import {
|
|
ResponsePost,
|
|
} from "@/api/resources/SinglePayment";
|
|
import { createSinglePayment } from "@/services/singlePayment";
|
|
import Modal from "@/components/Modal";
|
|
import PaymentForm from "@/components/pages/PaymentWithEmailPage/PaymentForm";
|
|
import { getPriceCentsToDollars } from "@/services/price";
|
|
import Loader, { LoaderColor } from "@/components/Loader";
|
|
|
|
function AddConsultationPage() {
|
|
const navigate = useNavigate();
|
|
const { user: userFromStore } = useAuth();
|
|
const api = useApi();
|
|
const tokenFromStore = useSelector(selectors.selectToken);
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [paymentIntent, setPaymentIntent] = useState<
|
|
ResponsePost | null
|
|
>(null);
|
|
const [isError, setIsError] = useState(false);
|
|
const returnUrl = `${window.location.protocol}//${
|
|
window.location.host
|
|
}${routes.client.getInformationPartner()}`;
|
|
|
|
const loadData = useCallback(async () => {
|
|
return await api.getSinglePaymentProducts({ token: tokenFromStore });
|
|
}, [api, tokenFromStore]);
|
|
|
|
const { data: products, isPending: isPendingProducts } =
|
|
useApiCall<SinglePayment.ResponseGet[]>(loadData);
|
|
|
|
const currentProduct = products?.find(
|
|
(product) => product.key === "main.unique.individual.consultation"
|
|
);
|
|
|
|
const handleClick = async () => {
|
|
if (!userFromStore || !currentProduct) return;
|
|
setIsLoading(true);
|
|
const { productId, key } = currentProduct;
|
|
const paymentInfo = {
|
|
productId,
|
|
key,
|
|
};
|
|
const paymentIntent = await createSinglePayment(
|
|
userFromStore,
|
|
paymentInfo,
|
|
tokenFromStore,
|
|
userFromStore.email,
|
|
userFromStore.profile.full_name,
|
|
userFromStore.profile.birthday,
|
|
returnUrl,
|
|
api
|
|
);
|
|
setPaymentIntent(paymentIntent);
|
|
setIsLoading(false);
|
|
if ("payment" in paymentIntent) {
|
|
if (paymentIntent.payment.status === "paid")
|
|
return navigate(routes.client.getInformationPartner());
|
|
return setIsError(true);
|
|
}
|
|
};
|
|
|
|
const handleClickSkip = () => {
|
|
navigate(routes.client.getInformationPartner());
|
|
};
|
|
return (
|
|
<div className={styles.container}>
|
|
{!isLoading &&
|
|
paymentIntent &&
|
|
"paymentIntent" in paymentIntent &&
|
|
!!tokenFromStore.length && (
|
|
<>
|
|
<Modal
|
|
open={!!paymentIntent}
|
|
onClose={() => setPaymentIntent(null)}
|
|
>
|
|
<Title variant="h1" className={styles["modal-title"]}>
|
|
{getPriceCentsToDollars(currentProduct?.amount || 0)}$
|
|
</Title>
|
|
<PaymentForm
|
|
stripePublicKey={paymentIntent.paymentIntent.data.public_key}
|
|
clientSecret={paymentIntent.paymentIntent.data.client_secret}
|
|
returnUrl={returnUrl}
|
|
/>
|
|
</Modal>
|
|
</>
|
|
)}
|
|
<Title variant="h2" className={styles.title}>
|
|
More for you
|
|
</Title>
|
|
<Title variant="h2" className={styles.subtitle}>
|
|
Exclusive offer recommended for you to achieve your goals faster
|
|
</Title>
|
|
<ConsultationTable />
|
|
<p className={styles.description}>
|
|
*You will be charged for the add-on services or offers selected at the
|
|
time of purchase.
|
|
<br />
|
|
This is a non-recuring payment.
|
|
</p>
|
|
<PaymentAddress />
|
|
{isError && (
|
|
<p className={styles.error}>
|
|
Something went wrong. Please try again later.
|
|
</p>
|
|
)}
|
|
<FooterButton
|
|
onClick={handleClick}
|
|
onClickSkip={handleClickSkip}
|
|
disabled={isPendingProducts || isLoading}
|
|
>
|
|
{isPendingProducts || isLoading ? (
|
|
<Loader color={LoaderColor.White} />
|
|
) : (
|
|
"Get my consultation"
|
|
)}
|
|
</FooterButton>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default AddConsultationPage;
|