diff --git a/src/api/api.ts b/src/api/api.ts index a854254..929a879 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -25,8 +25,8 @@ import { AppleAuth, AIRequestsV2, Assistants, - OpenAI - SinglePayment, + OpenAI, + SinglePayment } from './resources' const api = { diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index 7713ecb..7cc558b 100755 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -231,6 +231,7 @@ function App(): JSX.Element { }> {/* Email - Pay - Email */} + } /> } /> } /> } /> diff --git a/src/components/PaymentPage/methods/Stripe/CheckoutForm.tsx b/src/components/PaymentPage/methods/Stripe/CheckoutForm.tsx index 556ea57..0cc4cd5 100644 --- a/src/components/PaymentPage/methods/Stripe/CheckoutForm.tsx +++ b/src/components/PaymentPage/methods/Stripe/CheckoutForm.tsx @@ -71,7 +71,10 @@ export default function CheckoutForm({ onSubmit={handleSubmit} > {children ? children : null} - setFormReady(true)} /> + setFormReady(true)} + /> { const isShowTryApp = targetId === "i"; @@ -18,6 +20,9 @@ function GenderPage(): JSX.Element { const selectGender = (gender: Gender) => { dispatch(actions.questionnaire.update({ gender: gender.id })); + if (pathName === "/epe/gender") { + return navigate(routes.client.epeBirthdate()); + } navigate(`/questionnaire/profile/flowChoice`); }; diff --git a/src/components/pages/PaymentWithEmailPage/index.tsx b/src/components/pages/PaymentWithEmailPage/index.tsx index 53ec033..1dd5e80 100644 --- a/src/components/pages/PaymentWithEmailPage/index.tsx +++ b/src/components/pages/PaymentWithEmailPage/index.tsx @@ -1,6 +1,6 @@ import EmailInput from "@/components/EmailEnterPage/EmailInput"; import styles from "./styles.module.css"; -import { useEffect, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { actions, selectors } from "@/store"; import { useDispatch, useSelector } from "react-redux"; @@ -14,16 +14,20 @@ import Title from "@/components/Title"; import NameInput from "@/components/EmailEnterPage/NameInput"; import { getZodiacSignByDate } from "@/services/zodiac-sign"; import { + ResponseGet, ResponsePost, ResponsePostExistPaymentData, } from "@/api/resources/SinglePayment"; import { useNavigate } from "react-router-dom"; import routes from "@/routes"; import PaymentForm from "./PaymentForm"; +import { getPriceCentsToDollars } from "@/services/price"; +import { User } from "@/api/resources/User"; function PaymentWithEmailPage() { const { t, i18n } = useTranslation(); - const { signUp } = useAuth(); + const tokenFromStore = useSelector(selectors.selectToken); + const { signUp, user: userFromStore } = useAuth(); const api = useApi(); const navigate = useNavigate(); const timezone = getClientTimezone(); @@ -36,12 +40,14 @@ function PaymentWithEmailPage() { const [isValidName, setIsValidName] = useState(true); const [isDisabled, setIsDisabled] = useState(true); const [isLoading, setIsLoading] = useState(false); + const [isLoadingPage, setIsLoadingPage] = useState(false); const [isAuth, setIsAuth] = useState(false); const [apiError, setApiError] = useState(null); const [error, setError] = useState(false); const [paymentIntent, setPaymentIntent] = useState< ResponsePost | ResponsePostExistPaymentData | null >(null); + const [currentProduct, setCurrentProduct] = useState(); const returnUrl = `${window.location.protocol}//${window.location.host}/payment/result/?type=epe`; useEffect(() => { @@ -108,25 +114,30 @@ function PaymentWithEmailPage() { } }; - const handleClick = async () => { - const authData = await authorization(); - if (!authData) { - return; - } - const { user, token } = authData; - console.log(token); - + const getCurrentProduct = async (token: string) => { const productsSinglePayment = await api.getSinglePaymentProducts({ token, }); - const { productId } = productsSinglePayment[0]; - const createSinglePayment = await api.createSinglePayment({ + const currentProduct = productsSinglePayment.find( + (product) => product.key === "compatibility.pdf" + ); + return currentProduct; + }; + + const createSinglePayment = async ( + user: User, + productId: string, + token: string, + email: string, + name: string | null + ) => { + return await api.createSinglePayment({ token, data: { user: { id: `${user?.id}`, email, - name, + name: name || "", sign: user?.profile?.sign?.sign || getZodiacSignByDate(birthday), age: user?.profile?.age?.years || 1, }, @@ -140,25 +151,94 @@ function PaymentWithEmailPage() { return_url: returnUrl, }, }); - setPaymentIntent(createSinglePayment); + }; + + const handleClick = async () => { + const authData = await authorization(); + if (!authData) { + return; + } + const { user, token } = authData; + + const currentProduct = await getCurrentProduct(token); + if (!currentProduct) { + setError(true); + return; + } + setCurrentProduct(currentProduct); + + const { productId } = currentProduct; + const paymentIntent = await createSinglePayment( + user, + productId, + token, + email, + name + ); + setPaymentIntent(paymentIntent); setIsLoading(false); - if ("payment" in createSinglePayment) { - if (createSinglePayment.payment.status === "paid") + if ("payment" in paymentIntent) { + if (paymentIntent.payment.status === "paid") return navigate(routes.client.epeSuccessPayment()); return navigate(routes.client.epeFailPayment()); } }; + const handleAuthUser = useCallback(async () => { + if (!tokenFromStore.length || !userFromStore) { + return; + } + setIsLoadingPage(true); + const currentProduct = await getCurrentProduct(tokenFromStore); + if (!currentProduct) { + setError(true); + return; + } + setCurrentProduct(currentProduct); + + const { productId } = currentProduct; + const paymentIntent = await createSinglePayment( + userFromStore, + productId, + tokenFromStore, + userFromStore.email, + userFromStore.profile.full_name + ); + setPaymentIntent(paymentIntent); + setIsLoadingPage(false); + setIsLoading(false); + if ("payment" in paymentIntent) { + if (paymentIntent.payment.status === "paid") + return navigate(routes.client.epeSuccessPayment()); + return navigate(routes.client.epeFailPayment()); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + handleAuthUser(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + return (
- {paymentIntent && "paymentIntent" in paymentIntent && ( - - )} - {!paymentIntent && ( + {isLoadingPage && } + {!isLoadingPage && + paymentIntent && + "paymentIntent" in paymentIntent && + !!tokenFromStore.length && ( + <> + + {getPriceCentsToDollars(currentProduct?.amount || 0)}$ + + + + )} + {(!tokenFromStore || !paymentIntent) && !isLoadingPage && ( <> [host, "advisors"].join("/"), advisorChat: (id: number) => [host, "advisors", id].join("/"), // Email - Pay - Email + epeGender: () => [host, "epe", "gender"].join("/"), epeBirthdate: () => [host, "epe", "birthdate"].join("/"), epePayment: () => [host, "epe", "payment"].join("/"), epeSuccessPayment: () => [host, "epe", "success-payment"].join("/"), diff --git a/src/services/price/index.ts b/src/services/price/index.ts index 053aec7..01cb9f0 100755 --- a/src/services/price/index.ts +++ b/src/services/price/index.ts @@ -22,3 +22,7 @@ export const getPriceFromTrial = (trial: ITrial | null) => { } return (trial.price_cents === 100 ? 99 : trial.price_cents || 0) / 100; }; + +export const getPriceCentsToDollars = (cents: number) => { + return (cents / 100).toFixed(2); +};