247 lines
7.2 KiB
TypeScript
247 lines
7.2 KiB
TypeScript
import EmailInput from "@/components/EmailEnterPage/EmailInput";
|
|
import styles from "./styles.module.css";
|
|
import { useCallback, useEffect, useState } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { actions, selectors } from "@/store";
|
|
import { useDispatch, useSelector } from "react-redux";
|
|
import MainButton from "@/components/MainButton";
|
|
import Loader, { LoaderColor } from "@/components/Loader";
|
|
import { useAuth } from "@/auth";
|
|
import { ApiError, extractErrorMessage, useApi } from "@/api";
|
|
import { getClientTimezone } from "@/locales";
|
|
import ErrorText from "@/components/ErrorText";
|
|
import Title from "@/components/Title";
|
|
import NameInput from "@/components/EmailEnterPage/NameInput";
|
|
import { useParams } from "react-router-dom";
|
|
import routes from "@/routes";
|
|
import PaymentForm from "./PaymentForm";
|
|
import { getPriceCentsToDollars } from "@/services/price";
|
|
import { useSinglePayment } from "@/hooks/payment/useSinglePayment";
|
|
|
|
function PaymentWithEmailPage() {
|
|
const { productId } = useParams();
|
|
const { t, i18n } = useTranslation();
|
|
// const tokenFromStore = useSelector(selectors.selectToken);
|
|
const { signUp, user: userFromStore, token: tokenFromStore } = useAuth();
|
|
const api = useApi();
|
|
const timezone = getClientTimezone();
|
|
const dispatch = useDispatch();
|
|
const birthday = useSelector(selectors.selectBirthday);
|
|
const locale = i18n.language;
|
|
const [email, setEmail] = useState("");
|
|
const [name, setName] = useState("");
|
|
const [isValidEmail, setIsValidEmail] = useState(false);
|
|
const [isValidName, setIsValidName] = useState(productId !== "chat.aura");
|
|
const [isDisabled, setIsDisabled] = useState(true);
|
|
const [isAuth, setIsAuth] = useState(false);
|
|
const [apiError, setApiError] = useState<ApiError | null>(null);
|
|
const [error, setError] = useState<boolean>(false);
|
|
const returnUrl = `${window.location.protocol}//${
|
|
window.location.host
|
|
}${routes.client.paymentResult()}`;
|
|
|
|
const [isLoadingAuth, setIsLoadingAuth] = useState<boolean>(false);
|
|
|
|
const {
|
|
product,
|
|
paymentIntent,
|
|
createSinglePayment,
|
|
isLoading: isLoadingSinglePayment,
|
|
error: errorSinglePayment,
|
|
} = useSinglePayment();
|
|
|
|
useEffect(() => {
|
|
if (
|
|
isValidName &&
|
|
isValidEmail &&
|
|
!(error || apiError || errorSinglePayment?.error)
|
|
) {
|
|
setIsDisabled(false);
|
|
} else {
|
|
setIsDisabled(true);
|
|
}
|
|
}, [
|
|
isValidEmail,
|
|
email,
|
|
isValidName,
|
|
name,
|
|
error,
|
|
apiError,
|
|
errorSinglePayment?.error,
|
|
]);
|
|
|
|
const handleValidEmail = (email: string) => {
|
|
dispatch(actions.form.addEmail(email));
|
|
setEmail(email);
|
|
setIsValidEmail(true);
|
|
};
|
|
|
|
const handleValidName = (name: string) => {
|
|
setName(name);
|
|
setIsValidName(true);
|
|
};
|
|
|
|
const authorization = async () => {
|
|
try {
|
|
setIsLoadingAuth(true);
|
|
const auth = await api.auth({ email, timezone, locale });
|
|
const {
|
|
auth: { token, user },
|
|
} = auth;
|
|
signUp(token, user);
|
|
const payload = {
|
|
user: {
|
|
profile_attributes: {
|
|
birthday,
|
|
full_name: name,
|
|
},
|
|
},
|
|
token,
|
|
};
|
|
const updatedUser = await api.updateUser(payload).catch((error) => {
|
|
console.log("Error: ", error);
|
|
});
|
|
|
|
if (updatedUser?.user) {
|
|
dispatch(actions.user.update(updatedUser.user));
|
|
}
|
|
if (name) {
|
|
dispatch(
|
|
actions.user.update({
|
|
username: name,
|
|
})
|
|
);
|
|
}
|
|
dispatch(actions.status.update("registred"));
|
|
setIsAuth(true);
|
|
const userUpdated = await api.getUser({ token });
|
|
setIsLoadingAuth(false);
|
|
return { user: userUpdated?.user, token };
|
|
} catch (error) {
|
|
console.error(error);
|
|
if (error instanceof ApiError) {
|
|
setApiError(error as ApiError);
|
|
} else {
|
|
setError(true);
|
|
}
|
|
setIsLoadingAuth(false);
|
|
}
|
|
};
|
|
|
|
const handleClick = async () => {
|
|
const authData = await authorization();
|
|
if (!authData) {
|
|
return;
|
|
}
|
|
const { user, token } = authData;
|
|
|
|
await createSinglePayment({
|
|
user,
|
|
token,
|
|
targetProductKey: productId || "",
|
|
returnUrl,
|
|
});
|
|
};
|
|
|
|
const handleAuthUser = useCallback(async () => {
|
|
if (!tokenFromStore.length || !userFromStore) {
|
|
return;
|
|
}
|
|
|
|
await createSinglePayment({
|
|
user: userFromStore,
|
|
token: tokenFromStore,
|
|
targetProductKey: productId || "",
|
|
returnUrl,
|
|
});
|
|
}, [
|
|
createSinglePayment,
|
|
productId,
|
|
returnUrl,
|
|
tokenFromStore,
|
|
userFromStore,
|
|
]);
|
|
|
|
useEffect(() => {
|
|
handleAuthUser();
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, []);
|
|
|
|
return (
|
|
<div className={`${styles.page} page`}>
|
|
{(isLoadingSinglePayment || isLoadingSinglePayment) && (
|
|
<Loader color={LoaderColor.Black} />
|
|
)}
|
|
{!isLoadingSinglePayment &&
|
|
!isLoadingAuth &&
|
|
paymentIntent &&
|
|
"paymentIntent" in paymentIntent &&
|
|
!!tokenFromStore.length && (
|
|
<>
|
|
<Title variant="h1" className={styles.title}>
|
|
{getPriceCentsToDollars(product?.price || 0)}$
|
|
</Title>
|
|
<PaymentForm
|
|
stripePublicKey={paymentIntent.paymentIntent.data.public_key}
|
|
clientSecret={paymentIntent.paymentIntent.data.client_secret}
|
|
returnUrl={`${returnUrl}?redirect_type=${product?.key}`}
|
|
/>
|
|
</>
|
|
)}
|
|
{(!tokenFromStore || !paymentIntent) &&
|
|
// || (productId !== "chat.aura" && !name.length)
|
|
!isLoadingSinglePayment &&
|
|
!isLoadingAuth && (
|
|
<>
|
|
<NameInput
|
|
value={name}
|
|
placeholder="Your name"
|
|
onValid={handleValidName}
|
|
onInvalid={() => setIsValidName(productId !== "chat.aura")}
|
|
/>
|
|
<EmailInput
|
|
name="email"
|
|
value={email}
|
|
placeholder={t("your_email")}
|
|
onValid={handleValidEmail}
|
|
onInvalid={() => setIsValidEmail(false)}
|
|
/>
|
|
|
|
<MainButton
|
|
className={styles.button}
|
|
onClick={handleClick}
|
|
disabled={isDisabled}
|
|
>
|
|
{isLoadingSinglePayment && <Loader color={LoaderColor.White} />}
|
|
{!isLoadingSinglePayment &&
|
|
!(!apiError && !error && !isLoadingSinglePayment && isAuth) &&
|
|
t("_continue")}
|
|
{!apiError && !error && !isLoadingSinglePayment && isAuth && (
|
|
<img
|
|
className={styles["success-icon"]}
|
|
src="/SuccessIcon.png"
|
|
alt="Success Icon"
|
|
/>
|
|
)}
|
|
</MainButton>
|
|
</>
|
|
)}
|
|
{(error || apiError || errorSinglePayment?.error) && (
|
|
<Title variant="h3" style={{ color: "red", margin: 0 }}>
|
|
Something went wrong:{" "}
|
|
{errorSinglePayment?.error?.length && errorSinglePayment?.error}
|
|
</Title>
|
|
)}
|
|
{apiError && (
|
|
<ErrorText
|
|
size="medium"
|
|
isShown={Boolean(apiError)}
|
|
message={apiError ? extractErrorMessage(apiError) : null}
|
|
/>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default PaymentWithEmailPage;
|