w-aura/src/components/pages/PaymentWithEmailPage/index.tsx
2024-05-27 20:43:52 +00:00

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;