Merge branch 'preview/email-pay-email' into 'develop'
Revert "fix: remove double image key and update filter of subscription plans" See merge request witapp/aura-webapp!64
This commit is contained in:
commit
ba8da9a188
@ -25,8 +25,8 @@ import {
|
|||||||
AppleAuth,
|
AppleAuth,
|
||||||
AIRequestsV2,
|
AIRequestsV2,
|
||||||
Assistants,
|
Assistants,
|
||||||
OpenAI
|
OpenAI,
|
||||||
SinglePayment,
|
SinglePayment
|
||||||
} from './resources'
|
} from './resources'
|
||||||
|
|
||||||
const api = {
|
const api = {
|
||||||
|
|||||||
@ -231,6 +231,7 @@ function App(): JSX.Element {
|
|||||||
<Routes>
|
<Routes>
|
||||||
<Route element={<Layout setIsSpecialOfferOpen={setIsSpecialOfferOpen} />}>
|
<Route element={<Layout setIsSpecialOfferOpen={setIsSpecialOfferOpen} />}>
|
||||||
{/* Email - Pay - Email */}
|
{/* Email - Pay - Email */}
|
||||||
|
<Route path={routes.client.epeGender()} element={<GenderPage />} />
|
||||||
<Route path={routes.client.epeBirthdate()} element={<BirthdayPage />} />
|
<Route path={routes.client.epeBirthdate()} element={<BirthdayPage />} />
|
||||||
<Route path={routes.client.epePayment()} element={<PaymentWithEmailPage />} />
|
<Route path={routes.client.epePayment()} element={<PaymentWithEmailPage />} />
|
||||||
<Route path={routes.client.epeSuccessPayment()} element={<SuccessPaymentPage />} />
|
<Route path={routes.client.epeSuccessPayment()} element={<SuccessPaymentPage />} />
|
||||||
|
|||||||
@ -71,7 +71,10 @@ export default function CheckoutForm({
|
|||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
>
|
>
|
||||||
{children ? children : null}
|
{children ? children : null}
|
||||||
<PaymentElement onReady={() => setFormReady(true)} />
|
<PaymentElement
|
||||||
|
options={{ terms: { card: "never" } }}
|
||||||
|
onReady={() => setFormReady(true)}
|
||||||
|
/>
|
||||||
<MainButton
|
<MainButton
|
||||||
color="blue"
|
color="blue"
|
||||||
disabled={isProcessing || !formReady}
|
disabled={isProcessing || !formReady}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import styles from "./styles.module.css";
|
import styles from "./styles.module.css";
|
||||||
import Title from "@/components/Title";
|
import Title from "@/components/Title";
|
||||||
import { Gender, genders } from "@/data";
|
import { Gender, genders } from "@/data";
|
||||||
|
import routes from "@/routes";
|
||||||
import { actions } from "@/store";
|
import { actions } from "@/store";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
@ -10,6 +11,7 @@ function GenderPage(): JSX.Element {
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { targetId } = useParams();
|
const { targetId } = useParams();
|
||||||
|
const pathName = window.location.pathname;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const isShowTryApp = targetId === "i";
|
const isShowTryApp = targetId === "i";
|
||||||
@ -18,6 +20,9 @@ function GenderPage(): JSX.Element {
|
|||||||
|
|
||||||
const selectGender = (gender: Gender) => {
|
const selectGender = (gender: Gender) => {
|
||||||
dispatch(actions.questionnaire.update({ gender: gender.id }));
|
dispatch(actions.questionnaire.update({ gender: gender.id }));
|
||||||
|
if (pathName === "/epe/gender") {
|
||||||
|
return navigate(routes.client.epeBirthdate());
|
||||||
|
}
|
||||||
navigate(`/questionnaire/profile/flowChoice`);
|
navigate(`/questionnaire/profile/flowChoice`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import EmailInput from "@/components/EmailEnterPage/EmailInput";
|
import EmailInput from "@/components/EmailEnterPage/EmailInput";
|
||||||
import styles from "./styles.module.css";
|
import styles from "./styles.module.css";
|
||||||
import { useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { actions, selectors } from "@/store";
|
import { actions, selectors } from "@/store";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
@ -14,16 +14,20 @@ import Title from "@/components/Title";
|
|||||||
import NameInput from "@/components/EmailEnterPage/NameInput";
|
import NameInput from "@/components/EmailEnterPage/NameInput";
|
||||||
import { getZodiacSignByDate } from "@/services/zodiac-sign";
|
import { getZodiacSignByDate } from "@/services/zodiac-sign";
|
||||||
import {
|
import {
|
||||||
|
ResponseGet,
|
||||||
ResponsePost,
|
ResponsePost,
|
||||||
ResponsePostExistPaymentData,
|
ResponsePostExistPaymentData,
|
||||||
} from "@/api/resources/SinglePayment";
|
} from "@/api/resources/SinglePayment";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import routes from "@/routes";
|
import routes from "@/routes";
|
||||||
import PaymentForm from "./PaymentForm";
|
import PaymentForm from "./PaymentForm";
|
||||||
|
import { getPriceCentsToDollars } from "@/services/price";
|
||||||
|
import { User } from "@/api/resources/User";
|
||||||
|
|
||||||
function PaymentWithEmailPage() {
|
function PaymentWithEmailPage() {
|
||||||
const { t, i18n } = useTranslation();
|
const { t, i18n } = useTranslation();
|
||||||
const { signUp } = useAuth();
|
const tokenFromStore = useSelector(selectors.selectToken);
|
||||||
|
const { signUp, user: userFromStore } = useAuth();
|
||||||
const api = useApi();
|
const api = useApi();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const timezone = getClientTimezone();
|
const timezone = getClientTimezone();
|
||||||
@ -36,12 +40,14 @@ function PaymentWithEmailPage() {
|
|||||||
const [isValidName, setIsValidName] = useState(true);
|
const [isValidName, setIsValidName] = useState(true);
|
||||||
const [isDisabled, setIsDisabled] = useState(true);
|
const [isDisabled, setIsDisabled] = useState(true);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [isLoadingPage, setIsLoadingPage] = useState(false);
|
||||||
const [isAuth, setIsAuth] = useState(false);
|
const [isAuth, setIsAuth] = useState(false);
|
||||||
const [apiError, setApiError] = useState<ApiError | null>(null);
|
const [apiError, setApiError] = useState<ApiError | null>(null);
|
||||||
const [error, setError] = useState<boolean>(false);
|
const [error, setError] = useState<boolean>(false);
|
||||||
const [paymentIntent, setPaymentIntent] = useState<
|
const [paymentIntent, setPaymentIntent] = useState<
|
||||||
ResponsePost | ResponsePostExistPaymentData | null
|
ResponsePost | ResponsePostExistPaymentData | null
|
||||||
>(null);
|
>(null);
|
||||||
|
const [currentProduct, setCurrentProduct] = useState<ResponseGet>();
|
||||||
const returnUrl = `${window.location.protocol}//${window.location.host}/payment/result/?type=epe`;
|
const returnUrl = `${window.location.protocol}//${window.location.host}/payment/result/?type=epe`;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -108,25 +114,30 @@ function PaymentWithEmailPage() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClick = async () => {
|
const getCurrentProduct = async (token: string) => {
|
||||||
const authData = await authorization();
|
|
||||||
if (!authData) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { user, token } = authData;
|
|
||||||
console.log(token);
|
|
||||||
|
|
||||||
const productsSinglePayment = await api.getSinglePaymentProducts({
|
const productsSinglePayment = await api.getSinglePaymentProducts({
|
||||||
token,
|
token,
|
||||||
});
|
});
|
||||||
const { productId } = productsSinglePayment[0];
|
const currentProduct = productsSinglePayment.find(
|
||||||
const createSinglePayment = await api.createSinglePayment({
|
(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,
|
token,
|
||||||
data: {
|
data: {
|
||||||
user: {
|
user: {
|
||||||
id: `${user?.id}`,
|
id: `${user?.id}`,
|
||||||
email,
|
email,
|
||||||
name,
|
name: name || "",
|
||||||
sign: user?.profile?.sign?.sign || getZodiacSignByDate(birthday),
|
sign: user?.profile?.sign?.sign || getZodiacSignByDate(birthday),
|
||||||
age: user?.profile?.age?.years || 1,
|
age: user?.profile?.age?.years || 1,
|
||||||
},
|
},
|
||||||
@ -140,25 +151,94 @@ function PaymentWithEmailPage() {
|
|||||||
return_url: returnUrl,
|
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);
|
setIsLoading(false);
|
||||||
if ("payment" in createSinglePayment) {
|
if ("payment" in paymentIntent) {
|
||||||
if (createSinglePayment.payment.status === "paid")
|
if (paymentIntent.payment.status === "paid")
|
||||||
return navigate(routes.client.epeSuccessPayment());
|
return navigate(routes.client.epeSuccessPayment());
|
||||||
return navigate(routes.client.epeFailPayment());
|
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 (
|
return (
|
||||||
<div className={`${styles.page} page`}>
|
<div className={`${styles.page} page`}>
|
||||||
{paymentIntent && "paymentIntent" in paymentIntent && (
|
{isLoadingPage && <Loader color={LoaderColor.Black} />}
|
||||||
<PaymentForm
|
{!isLoadingPage &&
|
||||||
stripePublicKey={paymentIntent.paymentIntent.data.public_key}
|
paymentIntent &&
|
||||||
clientSecret={paymentIntent.paymentIntent.data.client_secret}
|
"paymentIntent" in paymentIntent &&
|
||||||
returnUrl={returnUrl}
|
!!tokenFromStore.length && (
|
||||||
/>
|
<>
|
||||||
)}
|
<Title variant="h1" className={styles.title}>
|
||||||
{!paymentIntent && (
|
{getPriceCentsToDollars(currentProduct?.amount || 0)}$
|
||||||
|
</Title>
|
||||||
|
<PaymentForm
|
||||||
|
stripePublicKey={paymentIntent.paymentIntent.data.public_key}
|
||||||
|
clientSecret={paymentIntent.paymentIntent.data.client_secret}
|
||||||
|
returnUrl={returnUrl}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{(!tokenFromStore || !paymentIntent) && !isLoadingPage && (
|
||||||
<>
|
<>
|
||||||
<NameInput
|
<NameInput
|
||||||
value={name}
|
value={name}
|
||||||
|
|||||||
@ -122,6 +122,7 @@ const routes = {
|
|||||||
advisors: () => [host, "advisors"].join("/"),
|
advisors: () => [host, "advisors"].join("/"),
|
||||||
advisorChat: (id: number) => [host, "advisors", id].join("/"),
|
advisorChat: (id: number) => [host, "advisors", id].join("/"),
|
||||||
// Email - Pay - Email
|
// Email - Pay - Email
|
||||||
|
epeGender: () => [host, "epe", "gender"].join("/"),
|
||||||
epeBirthdate: () => [host, "epe", "birthdate"].join("/"),
|
epeBirthdate: () => [host, "epe", "birthdate"].join("/"),
|
||||||
epePayment: () => [host, "epe", "payment"].join("/"),
|
epePayment: () => [host, "epe", "payment"].join("/"),
|
||||||
epeSuccessPayment: () => [host, "epe", "success-payment"].join("/"),
|
epeSuccessPayment: () => [host, "epe", "success-payment"].join("/"),
|
||||||
|
|||||||
@ -22,3 +22,7 @@ export const getPriceFromTrial = (trial: ITrial | null) => {
|
|||||||
}
|
}
|
||||||
return (trial.price_cents === 100 ? 99 : trial.price_cents || 0) / 100;
|
return (trial.price_cents === 100 ? 99 : trial.price_cents || 0) / 100;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getPriceCentsToDollars = (cents: number) => {
|
||||||
|
return (cents / 100).toFixed(2);
|
||||||
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user