Merge branch 'hotfix/redesign-palmistry' into 'main'

hotfix/redesign-palmistry

See merge request witapp/aura-webapp!576
This commit is contained in:
Daniil Chemerkin 2025-01-31 02:37:08 +00:00
commit f3357ee02a
28 changed files with 617 additions and 291 deletions

View File

@ -26,11 +26,11 @@ export interface PayloadUpdate {
} }
export interface IAnswersSessionPalmistry { export interface IAnswersSessionPalmistry {
what_aspects: 'love_relationships' | 'health_vitality' | 'career_destiny', // Type: string, optional - 'love_relationships' | 'health_vitality' | 'career_destiny'; what_aspects: 'love_relationships' | 'health_vitality' | 'career_destiny' | 'life_transitions', // Type: string, optional - 'love_relationships' | 'health_vitality' | 'career_destiny';
relationship_status: 'single' | 'in_relationship', // Type: string, optional - 'single' | 'in_relationship'; relationship_status: 'single' | 'in_relationship' | 'engaged' | 'divorced' | 'complicated', // Type: string, optional - 'single' | 'in_relationship';
element_resonates: 'water' | 'fire' | 'air' | 'earth', // Type: string, optional - 'water' | 'fire' | 'air' | 'earth'; element_resonates: 'water' | 'fire' | 'air' | 'earth' | 'light' | 'darkness', // Type: string, optional - 'water' | 'fire' | 'air' | 'earth';
favorite_color: 'blue' | 'green' | 'orange' | 'violet' | 'red' | 'yellow', // Type: string, optional - 'blue' | 'green' | 'orange' | 'violet' | 'red' | 'yellow'; favorite_color: 'blue' | 'green' | 'orange' | 'violet' | 'red' | 'yellow' | 'turquoise', // Type: string, optional - 'blue' | 'green' | 'orange' | 'violet' | 'red' | 'yellow';
head_or_heart: 'head' | 'heart' | 'both', // Type: string, optional - 'head' | 'heart' | 'both'; head_or_heart: 'head' | 'heart' | 'both' | 'depends', // Type: string, optional - 'head' | 'heart' | 'both';
time_alone: 1 | 2 | 3 | 4 | 5, // Type: number, optional - 1 | 2 | 3 | 4 | 5; time_alone: 1 | 2 | 3 | 4 | 5, // Type: number, optional - 1 | 2 | 3 | 4 | 5;
own_company: 1 | 2 | 3 | 4 | 5, // Type: number, optional - 1 | 2 | 3 | 4 | 5; own_company: 1 | 2 | 3 | 4 | 5, // Type: number, optional - 1 | 2 | 3 | 4 | 5;
socializing_in_groups: 1 | 2 | 3 | 4 | 5, // Type: number, optional - 1 | 2 | 3 | 4 | 5; socializing_in_groups: 1 | 2 | 3 | 4 | 5, // Type: number, optional - 1 | 2 | 3 | 4 | 5;

View File

@ -317,13 +317,11 @@ function App(): JSX.Element {
<CookieYesController isDelete={subscriptionStatus === "subscribed"} /> <CookieYesController isDelete={subscriptionStatus === "subscribed"} />
} }
> >
<Route path={routes.client.auth()} element={<Auth redirectUrl={routes.client.trialPaymentV1()} />} />
<Route path="*" element={<ABDesignV1Routes />} />
<Route path={`${chatsPrefix}/*`} element={<ChatsRoutes />} />
<Route <Route
path={`${palmistryV1Prefix}/*`} path={`${palmistryV1Prefix}/*`}
element={<PalmistryV1Routes />} element={<PalmistryV1Routes />}
/> />
<Route path={routes.client.auth()} element={<Auth redirectUrl={routes.client.trialPaymentV1()} />} />
<Route <Route
path={`${palmistryV2Prefix}/*`} path={`${palmistryV2Prefix}/*`}
element={<PalmistryV2Routes />} element={<PalmistryV2Routes />}
@ -332,6 +330,159 @@ function App(): JSX.Element {
path={`${emailMarketingV1Prefix}/*`} path={`${emailMarketingV1Prefix}/*`}
element={<MarketingLandingV1Routes />} element={<MarketingLandingV1Routes />}
/> />
{/* Additional Purchases Palmistry */}
<Route element={<PrivateOutlet />}>
<Route element={<AdditionalPurchasesPalmistry />}>
<Route path={routes.client.skipTrial()} element={<SkipTrial />} />
<Route
path={routes.client.addConsultant()}
element={<AddConsultant />}
/>
<Route path={routes.client.addGuides()} element={<AddGuides />} />
</Route>
</Route>
{/* Additional Purchases Palmistry End */}
<Route
path={routes.client.getInformationPartner()}
element={<GetInformationPartnerPage />}
/>
<Route
path={routes.client.paymentResult()}
element={<PaymentResultPage />}
>
<Route path=":id" element={<PaymentResultPage />} />
</Route>
<Route
path={routes.client.paymentSuccess()}
element={<PaymentSuccessPage />}
/>
<Route
path={routes.client.paymentFail()}
element={<PaymentFailPage />}
/>
<Route element={<AuthorizedUserOutlet />}>
<Route path={routes.client.root()} element={<MainPage />} />
<Route path={routes.client.birthday()} element={<BirthdayPage />} />
<Route
path={routes.client.didYouKnow()}
element={<DidYouKnowPage />}
/>
<Route
path={routes.client.freePeriodInfo()}
element={<FreePeriodInfoPage />}
/>
<Route path={routes.client.feedback()} element={<FeedbackPage />} />
<Route
path={routes.client.birthtime()}
element={<BirthtimePage />}
/>
<Route
path={routes.client.createProfile()}
element={<SkipStep />}
/>
<Route
path={routes.client.emailEnter()}
element={<EmailEnterPage />}
/>
{/* <Route
path={routes.client.auth()}
element={<AuthPage padLockApng={padLockApng} />}
/> */}
<Route
path={routes.client.authResult()}
element={<AuthResultPage />}
/>
{/* <Route path={routes.client.static()} element={<StaticPage />} /> */}
<Route
path={routes.client.priceList()}
element={<PriceListPage />}
/>
</Route>
{/* <Route element={<AuthorizedUserOutlet />}>
<Route
path={routes.client.subscription()}
element={<SubscriptionPage />}
>
<Route path=":subPlan" element={<SubscriptionPage />} />
</Route>
</Route> */}
<Route element={<PrivateOutlet />}>
<Route element={<AuthorizedUserOutlet />}>
<Route
path={routes.client.paymentMethod()}
element={<PaymentPage />}
/>
</Route>
<Route element={<PrivateSubscriptionOutlet />}>
<Route path={routes.client.home()} element={<HomePage />} />
<Route
path={routes.client.compatibility()}
element={<CompatibilityPage />}
/>
<Route
path={routes.client.compatibilityResult()}
element={<CompatResultPage />}
/>
<Route
path={routes.client.breath()}
element={<BreathPage leoApng={leoApng} />}
/>
<Route
path={routes.client.breathResult()}
element={<UserCallbacksPage />}
/>
<Route
path={routes.client.wallpaper()}
element={<WallpaperPage />}
/>
<Route path={routes.client.advisors()} element={<Advisors />} />
<Route path={routes.client.advisors()}>
<Route path=":id" element={<AdvisorChatPage />} />
</Route>
<Route
path={routes.client.magicBall()}
element={<MagicBallPage />}
/>
<Route
path={routes.client.horoscopeBestiesResult()}
element={<BestiesHoroscopeResult />}
/>
<Route
path={routes.client.predictionMoonResult()}
element={<PredictionMoonResult />}
/>
<Route
path={routes.client.myHoroscopeResult()}
element={<MyHoroscopeResult />}
/>
<Route
path={routes.client.thermalResult()}
element={<ThermalResult />}
/>
<Route
path={routes.client.moonPhaseTracker()}
element={<MoonPhaseTrackerResult />}
/>
<Route
path={routes.client.energyVampirismResult()}
element={<EnergyVampirismResult />}
/>
<Route
path={routes.client.nameHoroscopeResult()}
element={<NameHoroscopeResult />}
/>
</Route>
</Route>
<Route path="*" element={<Navigate to={getRouteBy(subscriptionStatus)} />} />
{/* ROUTES OFF */}
<Route path="*" element={<ABDesignV1Routes />} />
<Route path={`${chatsPrefix}/*`} element={<ChatsRoutes />} />
<Route <Route
path={`${routes.client.mikeV1()}/*`} path={`${routes.client.mikeV1()}/*`}
element={<MikeV1Routes />} element={<MikeV1Routes />}
@ -801,151 +952,7 @@ function App(): JSX.Element {
</Route> </Route>
{/* Additional Purchases End */} {/* Additional Purchases End */}
{/* Additional Purchases Palmistry */}
<Route element={<PrivateOutlet />}>
<Route element={<AdditionalPurchasesPalmistry />}>
<Route path={routes.client.skipTrial()} element={<SkipTrial />} />
<Route
path={routes.client.addConsultant()}
element={<AddConsultant />}
/>
<Route path={routes.client.addGuides()} element={<AddGuides />} />
</Route>
</Route>
{/* Additional Purchases Palmistry End */}
<Route
path={routes.client.getInformationPartner()}
element={<GetInformationPartnerPage />}
/>
<Route
path={routes.client.paymentResult()}
element={<PaymentResultPage />}
>
<Route path=":id" element={<PaymentResultPage />} />
</Route>
<Route
path={routes.client.paymentSuccess()}
element={<PaymentSuccessPage />}
/>
<Route
path={routes.client.paymentFail()}
element={<PaymentFailPage />}
/>
<Route element={<AuthorizedUserOutlet />}>
<Route path={routes.client.root()} element={<MainPage />} />
<Route path={routes.client.birthday()} element={<BirthdayPage />} />
<Route
path={routes.client.didYouKnow()}
element={<DidYouKnowPage />}
/>
<Route
path={routes.client.freePeriodInfo()}
element={<FreePeriodInfoPage />}
/>
<Route path={routes.client.feedback()} element={<FeedbackPage />} />
<Route
path={routes.client.birthtime()}
element={<BirthtimePage />}
/>
<Route
path={routes.client.createProfile()}
element={<SkipStep />}
/>
<Route
path={routes.client.emailEnter()}
element={<EmailEnterPage />}
/>
{/* <Route
path={routes.client.auth()}
element={<AuthPage padLockApng={padLockApng} />}
/> */}
<Route
path={routes.client.authResult()}
element={<AuthResultPage />}
/>
{/* <Route path={routes.client.static()} element={<StaticPage />} /> */}
<Route
path={routes.client.priceList()}
element={<PriceListPage />}
/>
</Route>
{/* <Route element={<AuthorizedUserOutlet />}>
<Route
path={routes.client.subscription()}
element={<SubscriptionPage />}
>
<Route path=":subPlan" element={<SubscriptionPage />} />
</Route>
</Route> */}
<Route element={<PrivateOutlet />}>
<Route element={<AuthorizedUserOutlet />}>
<Route
path={routes.client.paymentMethod()}
element={<PaymentPage />}
/>
</Route>
<Route element={<PrivateSubscriptionOutlet />}>
<Route path={routes.client.home()} element={<HomePage />} />
<Route
path={routes.client.compatibility()}
element={<CompatibilityPage />}
/>
<Route
path={routes.client.compatibilityResult()}
element={<CompatResultPage />}
/>
<Route
path={routes.client.breath()}
element={<BreathPage leoApng={leoApng} />}
/>
<Route
path={routes.client.breathResult()}
element={<UserCallbacksPage />}
/>
<Route
path={routes.client.wallpaper()}
element={<WallpaperPage />}
/>
<Route path={routes.client.advisors()} element={<Advisors />} />
<Route path={routes.client.advisors()}>
<Route path=":id" element={<AdvisorChatPage />} />
</Route>
<Route
path={routes.client.magicBall()}
element={<MagicBallPage />}
/>
<Route
path={routes.client.horoscopeBestiesResult()}
element={<BestiesHoroscopeResult />}
/>
<Route
path={routes.client.predictionMoonResult()}
element={<PredictionMoonResult />}
/>
<Route
path={routes.client.myHoroscopeResult()}
element={<MyHoroscopeResult />}
/>
<Route
path={routes.client.thermalResult()}
element={<ThermalResult />}
/>
<Route
path={routes.client.moonPhaseTracker()}
element={<MoonPhaseTrackerResult />}
/>
<Route
path={routes.client.energyVampirismResult()}
element={<EnergyVampirismResult />}
/>
<Route
path={routes.client.nameHoroscopeResult()}
element={<NameHoroscopeResult />}
/>
</Route>
</Route>
<Route path="/palmistry" element={<StepsManager />} /> <Route path="/palmistry" element={<StepsManager />} />

View File

@ -20,14 +20,10 @@ import { usePaywall } from "@/hooks/paywall/usePaywall";
import { EPlacementKeys, IPaywallProduct } from "@/api/resources/Paywall"; import { EPlacementKeys, IPaywallProduct } from "@/api/resources/Paywall";
import { useAuth } from "@/auth"; import { useAuth } from "@/auth";
import { createSinglePayment } from "@/services/singlePayment"; import { createSinglePayment } from "@/services/singlePayment";
import Modal from "@/components/Modal";
import Title from "@/components/Title";
// import PaymentForm from "@/components/pages/SinglePaymentPage/PaymentForm";
import { getPriceCentsToDollars } from "@/services/price";
import { IMessage } from "@/api/resources/ChatMessages"; import { IMessage } from "@/api/resources/ChatMessages";
import { useTranslations } from "@/hooks/translations"; import { useTranslations } from "@/hooks/translations";
import { ELocalesPlacement } from "@/locales"; import { ELocalesPlacement } from "@/locales";
import PaymentForm from "@/components/Payment/nmi/PaymentForm"; import { usePayment } from "@/hooks/payment/nmi/usePayment";
const returnUrl = `${window.location.protocol}//${window.location.host const returnUrl = `${window.location.protocol}//${window.location.host
}${routes.client.chatsExpert()}`; }${routes.client.chatsExpert()}`;
@ -76,7 +72,18 @@ function ExpertChat() {
const setCurrentProduct = (product: IPaywallProduct) => { const setCurrentProduct = (product: IPaywallProduct) => {
dispatch(actions.payment.update({ activeProduct: product })); dispatch(actions.payment.update({ activeProduct: product }));
}; };
const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false); // const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false);
const {
error,
isPaymentSuccess,
showCreditCardForm,
} = usePayment({
placementKey,
activeProduct: currentProduct!,
paymentFormType: "lightbox"
});
const isPayedFirstPurchase = useSelector( const isPayedFirstPurchase = useSelector(
selectors.selectIsPayedFirstPurchase selectors.selectIsPayedFirstPurchase
@ -189,7 +196,8 @@ function ExpertChat() {
setIsLoadingPayment(true); setIsLoadingPayment(true);
const isPaymentMethodExist = await api.getPaymentMethods({ token: tokenFromStore }); const isPaymentMethodExist = await api.getPaymentMethods({ token: tokenFromStore });
if (isPaymentMethodExist.status === "error") { if (isPaymentMethodExist.status === "error") {
return setIsPaymentModalOpen(true); // return setIsPaymentModalOpen(true);
return showCreditCardForm();
} }
// if (!isPayedFirstPurchase) { // if (!isPayedFirstPurchase) {
// return setIsPaymentModalOpen(true); // return setIsPaymentModalOpen(true);
@ -262,19 +270,31 @@ function ExpertChat() {
}; };
const onPaymentError = () => { const onPaymentError = () => {
setIsPaymentModalOpen(false); // setIsPaymentModalOpen(false);
return setIsError(true); return setIsError(true);
} }
const onPaymentSuccess = () => { const onPaymentSuccess = () => {
setIsPaymentModalOpen(false); // setIsPaymentModalOpen(false);
setIsLoadingPayment(false); setIsLoadingPayment(false);
return closeModals(); return closeModals();
} }
useEffect(() => {
if (error) {
onPaymentError();
}
}, [error])
useEffect(() => {
if (isPaymentSuccess) {
onPaymentSuccess();
}
}, [isPaymentSuccess])
return ( return (
<section className={`${styles.page} page`}> <section className={`${styles.page} page`}>
{!isLoading && {/* {!isLoading &&
!!tokenFromStore.length && !!tokenFromStore.length &&
currentProduct && ( currentProduct && (
<> <>
@ -286,12 +306,6 @@ function ExpertChat() {
<Title variant="h1" className={styles["modal-title"]}> <Title variant="h1" className={styles["modal-title"]}>
{getPriceCentsToDollars(currentProduct.price || 0)}$ {getPriceCentsToDollars(currentProduct.price || 0)}$
</Title> </Title>
{/* <PaymentForm
isLoadingPayment={isLoadingPayment}
stripePublicKey={paymentIntent.paymentIntent.data.public_key}
clientSecret={paymentIntent.paymentIntent.data.client_secret}
returnUrl={returnUrl}
/> */}
<PaymentForm <PaymentForm
placementKey={placementKey} placementKey={placementKey}
onPaymentError={onPaymentError} onPaymentError={onPaymentError}
@ -300,7 +314,7 @@ function ExpertChat() {
/> />
</Modal> </Modal>
</> </>
)} )} */}
{isLoading && ( {isLoading && (
<Loader color={LoaderColor.Red} className={styles.loader} /> <Loader color={LoaderColor.Red} className={styles.loader} />
)} )}

View File

@ -7,9 +7,7 @@ import Button from "../../components/Button";
import { usePaywall } from "@/hooks/paywall/usePaywall"; import { usePaywall } from "@/hooks/paywall/usePaywall";
import { EPlacementKeys } from "@/api/resources/Paywall"; import { EPlacementKeys } from "@/api/resources/Paywall";
import { addCurrency, ELocalesPlacement } from "@/locales"; import { addCurrency, ELocalesPlacement } from "@/locales";
import Modal from "@/components/Modal"; import { useEffect } from "react";
import { useEffect, useState } from "react";
import PaymentForm from "@/components/Payment/nmi/PaymentForm";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import routes from "@/routes"; import routes from "@/routes";
import { useDispatch } from "react-redux"; import { useDispatch } from "react-redux";
@ -17,6 +15,7 @@ import { actions } from "@/store";
import { useTranslations } from "@/hooks/translations"; import { useTranslations } from "@/hooks/translations";
import Header from "@/components/pages/ABDesign/v1/components/Header"; import Header from "@/components/pages/ABDesign/v1/components/Header";
import { useDynamicSize } from "@/hooks/useDynamicSize"; import { useDynamicSize } from "@/hooks/useDynamicSize";
import { usePayment } from "@/hooks/payment/nmi/usePayment";
const placementKey = EPlacementKeys["aura.placement.email.compatibility.discount"] const placementKey = EPlacementKeys["aura.placement.email.compatibility.discount"]
@ -42,27 +41,50 @@ function SecretDiscount() {
})) }))
}, [activeProduct]) }, [activeProduct])
const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false); // const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false);
const {
error,
isPaymentSuccess,
showCreditCardForm,
} = usePayment({
placementKey,
activeProduct,
paymentFormType: "lightbox"
});
useEffect(() => {
if (error) {
onPaymentError();
}
}, [error])
useEffect(() => {
if (isPaymentSuccess) {
onPaymentSuccess();
}
}, [isPaymentSuccess])
const onPaymentSuccess = () => { const onPaymentSuccess = () => {
return navigate(routes.client.paymentSuccess()) return navigate(routes.client.paymentSuccess())
} }
const onModalClosed = () => { // const onModalClosed = () => {
setIsPaymentModalOpen(false); // setIsPaymentModalOpen(false);
} // }
const onPaymentError = () => { const onPaymentError = () => {
return navigate(routes.client.paymentFail()) return navigate(routes.client.paymentFail())
} }
const openPaymentModal = () => { // const openPaymentModal = () => {
setIsPaymentModalOpen(true); // setIsPaymentModalOpen(true);
}; // };
return ( return (
<section className={styles.container} ref={elementRef} style={{ <section className={styles.container} ref={elementRef} style={{
paddingBottom: `${height + 42}px` paddingBottom: `${height + 42}px`
}}> }}>
<Header <Header
@ -70,7 +92,7 @@ function SecretDiscount() {
classNameTitle={styles["header-title"]} classNameTitle={styles["header-title"]}
isBackButtonVisible={true} isBackButtonVisible={true}
/> />
{activeProduct && ( {/* {activeProduct && (
<Modal <Modal
containerClassName={styles.modal} containerClassName={styles.modal}
open={isPaymentModalOpen} open={isPaymentModalOpen}
@ -83,13 +105,13 @@ function SecretDiscount() {
onPaymentSuccess={onPaymentSuccess} onPaymentSuccess={onPaymentSuccess}
/> />
</Modal> </Modal>
)} )} */}
<Blob3 className={styles.blob3} /> <Blob3 className={styles.blob3} />
<Title className={styles.title} variant="h1"> <Title className={styles.title} variant="h1">
{translate("secret-discount.title")} {translate("secret-discount.title")}
</Title> </Title>
<SecretDiscountTable /> <SecretDiscountTable />
<Button className={styles.button} onClick={openPaymentModal}> <Button className={styles.button} onClick={showCreditCardForm}>
{translate("secret-discount.button-trial", { days: trialDuration })} {translate("secret-discount.button-trial", { days: trialDuration })}
</Button> </Button>

View File

@ -3,24 +3,23 @@ import styles from "./styles.module.scss";
import PricingSummary from "../../components/PricingSummary"; import PricingSummary from "../../components/PricingSummary";
import Button from "../../components/Button"; import Button from "../../components/Button";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { useEffect, useState } from "react"; import { useEffect } from "react";
import { actions, selectors } from "@/store"; import { actions, selectors } from "@/store";
import { usePaywall } from "@/hooks/paywall/usePaywall"; import { usePaywall } from "@/hooks/paywall/usePaywall";
import { EPlacementKeys } from "@/api/resources/Paywall"; import { EPlacementKeys } from "@/api/resources/Paywall";
import Modal from "@/components/Modal";
import PaymentForm from "@/components/Payment/nmi/PaymentForm";
import routes from "@/routes"; import routes from "@/routes";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import BlurComponent from "@/components/BlurComponent"; import BlurComponent from "@/components/BlurComponent";
import { useTranslations } from "@/hooks/translations"; import { useTranslations } from "@/hooks/translations";
import { addCurrency, ELocalesPlacement } from "@/locales"; import { addCurrency, ELocalesPlacement } from "@/locales";
import { usePayment } from "@/hooks/payment/nmi/usePayment";
const placementKey = EPlacementKeys["aura.placement.email.marketing"]; const placementKey = EPlacementKeys["aura.placement.email.marketing"];
function SpecialOffer() { function SpecialOffer() {
const dispatch = useDispatch(); const dispatch = useDispatch();
const navigate = useNavigate(); const navigate = useNavigate();
const [isOpenPaymentModal, setIsOpenPaymentModal] = useState<boolean>(false); // const [isOpenPaymentModal, setIsOpenPaymentModal] = useState<boolean>(false);
const activeProduct = useSelector(selectors.selectActiveProduct); const activeProduct = useSelector(selectors.selectActiveProduct);
const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1); const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1);
@ -36,12 +35,42 @@ function SpecialOffer() {
dispatch(actions.payment.update({ activeProduct: products[0] })); dispatch(actions.payment.update({ activeProduct: products[0] }));
}, [dispatch, products]); }, [dispatch, products]);
const {
error,
isPaymentSuccess,
isModalClosed,
showCreditCardForm,
} = usePayment({
placementKey,
activeProduct: products[0],
paymentFormType: "lightbox"
});
const openPaymentModal = () => { const openPaymentModal = () => {
setIsOpenPaymentModal(true); // setIsOpenPaymentModal(true);
showCreditCardForm();
}; };
useEffect(() => {
if (error) {
onPaymentError();
}
}, [error])
useEffect(() => {
if (isPaymentSuccess) {
onPaymentSuccess();
}
}, [isPaymentSuccess])
useEffect(() => {
if (isModalClosed) {
handleCloseModal()
}
}, [isModalClosed])
const handleCloseModal = () => { const handleCloseModal = () => {
setIsOpenPaymentModal(false); // setIsOpenPaymentModal(false);
return navigate(routes.client.emailMarketingV1SaveOff()) return navigate(routes.client.emailMarketingV1SaveOff())
}; };
@ -55,7 +84,7 @@ function SpecialOffer() {
return ( return (
<> <>
{products[0] && ( {/* {products[0] && (
<Modal <Modal
containerClassName={styles.modal} containerClassName={styles.modal}
open={isOpenPaymentModal} open={isOpenPaymentModal}
@ -68,7 +97,7 @@ function SpecialOffer() {
onPaymentSuccess={onPaymentSuccess} onPaymentSuccess={onPaymentSuccess}
/> />
</Modal> </Modal>
)} )} */}
<div className={styles.container}> <div className={styles.container}>
<Title className={styles.title} variant="h1"> <Title className={styles.title} variant="h1">
{translate("special-offer.title")} {translate("special-offer.title")}

View File

@ -1,7 +1,7 @@
import { useTranslations } from '@/hooks/translations'; import { useTranslations } from '@/hooks/translations';
import { addCurrency, ELocalesPlacement } from '@/locales'; import { addCurrency, ELocalesPlacement } from '@/locales';
import styles from "./styles.module.scss"; import styles from "./styles.module.scss";
import { LegacyRef, useRef, useState } from 'react'; import { LegacyRef, useEffect, useRef, useState } from 'react';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { selectors } from '@/store'; import { selectors } from '@/store';
import { EPlacementKeys, IPaywallProduct } from '@/api/resources/Paywall'; import { EPlacementKeys, IPaywallProduct } from '@/api/resources/Paywall';
@ -13,9 +13,9 @@ import metricService, { EGoals, EMetrics } from '@/services/metric/metricService
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import routes from '@/routes'; import routes from '@/routes';
import CreditCardIcon from '@/components/PaymentModalNew/PaymentCardModal/CreditCardIcon'; import CreditCardIcon from '@/components/PaymentModalNew/PaymentCardModal/CreditCardIcon';
import Modal from '@/components/Modal'; import { usePayment } from '@/hooks/payment/nmi/usePayment';
import NMIPaymentForm from '@/components/Payment/nmi/PaymentForm';
const placementKey = EPlacementKeys['aura.placement.palmistry.redesign'];
interface IPaymentFormProps { interface IPaymentFormProps {
activeProduct: IPaywallProduct; activeProduct: IPaywallProduct;
@ -28,16 +28,39 @@ function PaymentForm({
const { translate } = useTranslations(ELocalesPlacement.PalmistryV1); const { translate } = useTranslations(ELocalesPlacement.PalmistryV1);
const ref = useRef<HTMLDivElement>(); const ref = useRef<HTMLDivElement>();
const currency = useSelector(selectors.selectCurrency); const currency = useSelector(selectors.selectCurrency);
const [isPaymentSuccess, setIsPaymentSuccess] = useState(false); // const [isPaymentSuccess, setIsPaymentSuccess] = useState(false);
const [isPaymentError, setIsPaymentError] = useState(false); const [isPaymentError, setIsPaymentError] = useState(false);
const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false); // const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false);
const {
error,
isPaymentSuccess,
showCreditCardForm,
} = usePayment({
placementKey,
activeProduct,
paymentFormType: "lightbox"
});
useEffect(() => {
if (error) {
onPaymentError();
}
}, [error])
useEffect(() => {
if (isPaymentSuccess) {
onPaymentSuccess();
}
}, [isPaymentSuccess])
const onPaymentError = () => { const onPaymentError = () => {
setIsPaymentError(true); setIsPaymentError(true);
} }
const onPaymentSuccess = () => { const onPaymentSuccess = () => {
setIsPaymentSuccess(true); // setIsPaymentSuccess(true);
metricService.reachGoal(EGoals.PAYMENT_SUCCESS); metricService.reachGoal(EGoals.PAYMENT_SUCCESS);
metricService.reachGoal(EGoals.PAYMENT_SUCCESS_PALMISTRY, [ metricService.reachGoal(EGoals.PAYMENT_SUCCESS_PALMISTRY, [
EMetrics.YANDEX, EMetrics.YANDEX,
@ -100,9 +123,9 @@ function PaymentForm({
)} )}
> >
<Modal containerClassName={styles["modal-content"]} open={isPaymentModalOpen} onClose={() => setIsPaymentModalOpen(false)}> {/* <Modal containerClassName={styles["modal-content"]} open={isPaymentModalOpen} onClose={() => setIsPaymentModalOpen(false)}>
<NMIPaymentForm onPaymentError={onPaymentError} onPaymentSuccess={onPaymentSuccess} placementKey={EPlacementKeys['aura.placement.palmistry.redesign']} /> <NMIPaymentForm onPaymentError={onPaymentError} onPaymentSuccess={onPaymentSuccess} placementKey={placementKey} />
</Modal> </Modal> */}
<div className={styles.paymentModalPrice}> <div className={styles.paymentModalPrice}>
{translate( {translate(
@ -118,7 +141,8 @@ function PaymentForm({
</div> </div>
<div <div
className={styles.paymentCreditCard} className={styles.paymentCreditCard}
onClick={() => setIsPaymentModalOpen(true)} // onClick={() => setIsPaymentModalOpen(true)}
onClick={() => showCreditCardForm()}
> >
<CreditCardIcon /> <CreditCardIcon />
<div>Credit / Debit Card</div> <div>Credit / Debit Card</div>

View File

@ -0,0 +1,17 @@
function DarknessSVG() {
return (
<svg width="48" height="49" viewBox="0 0 48 49" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M28.1969 0.865479C33.5795 1.81436 38.3436 4.5571 41.8496 8.45422C40.4797 10.7123 37.9981 12.221 35.1641 12.221C30.8485 12.221 27.3501 8.72258 27.3501 4.40705C27.3501 3.13218 27.6554 1.92861 28.1969 0.865479Z" fill="#62C3ED" />
<circle cx="24" cy="24.5" r="24" fill="#62C3ED" />
<circle cx="13.1163" cy="16.9651" r="4.74419" fill="#82DAFF" />
<circle cx="40.4652" cy="32.0348" r="2.51163" fill="#82DAFF" />
<circle cx="20.3714" cy="39.2906" r="1.39535" fill="#8BDCFF" />
<path fillRule="evenodd" clipRule="evenodd" d="M28.1969 0.865479C33.5795 1.81436 38.3436 4.5571 41.8496 8.45422C40.4797 10.7123 37.9981 12.221 35.1641 12.221C30.8485 12.221 27.3501 8.72258 27.3501 4.40705C27.3501 3.13218 27.6554 1.92861 28.1969 0.865479Z" fill="#9AE1FF" />
<circle cx="35.1636" cy="11.1048" r="0.55814" fill="#71D3FD" />
<circle cx="30.4188" cy="2.45342" r="0.837209" fill="#71D3FD" />
</svg>
);
}
export default DarknessSVG;

File diff suppressed because one or more lines are too long

View File

@ -18,6 +18,8 @@ import { ELottieKeys, useLottie } from "@/hooks/lottie/useLottie";
import { IAnswersSessionPalmistry } from "@/api/resources/Session"; import { IAnswersSessionPalmistry } from "@/api/resources/Session";
import { useSession } from "@/hooks/session/useSession"; import { useSession } from "@/hooks/session/useSession";
import { ESourceAuthorization } from "@/api/resources/User"; import { ESourceAuthorization } from "@/api/resources/User";
import DarknessSVG from "../../images/SVG/Darkness";
import LightSVG from "../../images/SVG/Light";
function ElementResonates() { function ElementResonates() {
const { translate } = useTranslations(ELocalesPlacement.PalmistryV1); const { translate } = useTranslations(ELocalesPlacement.PalmistryV1);
@ -35,6 +37,11 @@ function ElementResonates() {
Icon: JSX.Element; Icon: JSX.Element;
}[] = useMemo( }[] = useMemo(
() => [ () => [
{
id: "air",
title: translate("/element-resonates.answer3"),
Icon: <AirSVG />,
},
{ {
id: "water", id: "water",
title: translate("/element-resonates.answer1"), title: translate("/element-resonates.answer1"),
@ -45,16 +52,21 @@ function ElementResonates() {
title: translate("/element-resonates.answer2"), title: translate("/element-resonates.answer2"),
Icon: <FireSVG />, Icon: <FireSVG />,
}, },
{
id: "air",
title: translate("/element-resonates.answer3"),
Icon: <AirSVG />,
},
{ {
id: "earth", id: "earth",
title: translate("/element-resonates.answer4"), title: translate("/element-resonates.answer4"),
Icon: <EarthSVG />, Icon: <EarthSVG />,
}, },
{
id: "light",
title: translate("/element-resonates.answer5"),
Icon: <LightSVG />,
},
{
id: "darkness",
title: translate("/element-resonates.answer6"),
Icon: <DarknessSVG />,
},
], ],
[translate] [translate]
); );

View File

@ -46,16 +46,6 @@ function FavoriteColor() {
title: translate("/favorite-color.answer2"), title: translate("/favorite-color.answer2"),
color: "#20C63B", color: "#20C63B",
}, },
{
id: "orange",
title: translate("/favorite-color.answer3"),
color: "#EFA006",
},
{
id: "violet",
title: translate("/favorite-color.answer4"),
color: "#7B29E4",
},
{ {
id: "red", id: "red",
title: translate("/favorite-color.answer5"), title: translate("/favorite-color.answer5"),
@ -66,6 +56,21 @@ function FavoriteColor() {
title: translate("/favorite-color.answer6"), title: translate("/favorite-color.answer6"),
color: "#E4DD29", color: "#E4DD29",
}, },
{
id: "violet",
title: translate("/favorite-color.answer4"),
color: "#7B29E4",
},
// {
// id: "orange",
// title: translate("/favorite-color.answer3"),
// color: "#EFA006",
// },
{
id: "turquoise",
title: translate("/favorite-color.answer7"),
color: "#00C6C6",
},
], ],
[translate] [translate]
); );

View File

@ -8,7 +8,7 @@ import { ELocalesPlacement } from "@/locales";
import { useDispatch } from "react-redux"; import { useDispatch } from "react-redux";
import { useEffect } from "react"; import { useEffect } from "react";
import { actions } from "@/store"; import { actions } from "@/store";
import StarSVG from "../../images/SVG/Star"; // import StarSVG from "../../images/SVG/Star";
import { usePreloadImages } from "@/hooks/preload/images"; import { usePreloadImages } from "@/hooks/preload/images";
function FindHappiness() { function FindHappiness() {
@ -32,7 +32,7 @@ function FindHappiness() {
return ( return (
<> <>
<div className={styles["blocks-container"]}> {/* <div className={styles["blocks-container"]}>
<div className={styles.block}> <div className={styles.block}>
<img src={`${palmistryV1Prefix}/darts.png`} alt="darts" /> <img src={`${palmistryV1Prefix}/darts.png`} alt="darts" />
<ol> <ol>
@ -49,7 +49,7 @@ function FindHappiness() {
<li>{translate("/find-your-happiness.point4")}</li> <li>{translate("/find-your-happiness.point4")}</li>
</ol> </ol>
</div> </div>
</div> </div> */}
<img <img
className={styles.image} className={styles.image}
src={`${palmistryV1Prefix}/hand-with-lines.png`} src={`${palmistryV1Prefix}/hand-with-lines.png`}
@ -58,12 +58,25 @@ function FindHappiness() {
<Title variant="h2" className={styles.title}> <Title variant="h2" className={styles.title}>
{translate("/find-your-happiness.title")} {translate("/find-your-happiness.title")}
</Title> </Title>
<div className={styles["button-container"]}> <div className={styles.advantages}>
<Button onClick={() => navigate(`${palmistryV1Prefix}/gender`)}> <ul className={styles.list}>
{translate("next")} <li>
</Button> {translate("/find-your-happiness.advantage1")}
</li>
<li>
{translate("/find-your-happiness.advantage2")}
</li>
<li>
{translate("/find-your-happiness.advantage3")}
</li>
</ul>
</div> </div>
<p className={styles.description}> <div className={styles["button-container"]}>
<Button onClick={() => navigate(`${palmistryV1Prefix}/gender`)}>
{translate("next")}
</Button>
</div>
<p className={styles.description}>
{translate("/find-your-happiness.text")} {translate("/find-your-happiness.text")}
</p> </p>
</> </>

View File

@ -55,3 +55,23 @@
-webkit-backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
backdrop-filter: blur(2px); backdrop-filter: blur(2px);
} }
.advantages {
width: 100%;
text-align: center;
margin: 16px 0;
display: flex;
flex-direction: column;
gap: 8px;
}
.list {
list-style: disc;
padding-left: 20px;
margin: 0;
text-align: left;
}
.list li {
margin-bottom: 8px;
}

View File

@ -4,7 +4,7 @@ import { useDispatch, useSelector } from "react-redux";
import { actions, selectors } from "@/store"; import { actions, selectors } from "@/store";
import { Gender } from "@/data"; import { Gender } from "@/data";
import PrivacyPolicy from "@/components/pages/ABDesign/v1/components/PrivacyPolicy"; import PrivacyPolicy from "@/components/pages/ABDesign/v1/components/PrivacyPolicy";
import Toast from "@/components/pages/ABDesign/v1/components/Toast"; // import Toast from "@/components/pages/ABDesign/v1/components/Toast";
import { useTranslations } from "@/hooks/translations"; import { useTranslations } from "@/hooks/translations";
import { ELocalesPlacement } from "@/locales"; import { ELocalesPlacement } from "@/locales";
import { useCallback, useEffect, useState } from "react"; import { useCallback, useEffect, useState } from "react";
@ -28,7 +28,6 @@ function GenderPalmistry() {
const { checked: privacyPolicyChecked } = useSelector( const { checked: privacyPolicyChecked } = useSelector(
selectors.selectPrivacyPolicy selectors.selectPrivacyPolicy
); );
console.log(privacyPolicyChecked);
const { gender } = useSelector(selectors.selectQuestionnaire); const { gender } = useSelector(selectors.selectQuestionnaire);
const [isSelected, setIsSelected] = useState(false); const [isSelected, setIsSelected] = useState(false);
@ -84,7 +83,9 @@ function GenderPalmistry() {
<Title variant="h2" className={styles.title}> <Title variant="h2" className={styles.title}>
{translate("/gender.title")} {translate("/gender.title")}
</Title> </Title>
<p className={styles.description}>{translate("/gender.description")}</p> <p className={styles.description}>{translate("/gender.description", {
br: <br />,
})}</p>
{/* <ChooseGender onSelectGender={selectGender} /> */} {/* <ChooseGender onSelectGender={selectGender} /> */}
<PrivacyPolicy containerClassName={styles["privacy-policy"]} haveCheckbox={false} /> <PrivacyPolicy containerClassName={styles["privacy-policy"]} haveCheckbox={false} />
<div className={styles["genders-container"]}> <div className={styles["genders-container"]}>
@ -98,11 +99,11 @@ function GenderPalmistry() {
))} ))}
</div> </div>
<AlreadyHaveAccount text={translate("/gender.already_have_account")} /> <AlreadyHaveAccount text={translate("/gender.already_have_account")} />
{gender && !privacyPolicyChecked && ( {/* {gender && !privacyPolicyChecked && (
<Toast classNameContainer={styles["toast-container"]} variant="error"> <Toast classNameContainer={styles["toast-container"]} variant="error">
{translate("/gender.toast", undefined, ELocalesPlacement.V1)} {translate("/gender.toast", undefined, ELocalesPlacement.V1)}
</Toast> </Toast>
)} )} */}
</> </>
); );
} }

View File

@ -14,6 +14,10 @@
max-width: 302px; max-width: 302px;
} }
.leftAlign {
text-align: left;
}
.privacy-policy { .privacy-policy {
max-width: 316px; max-width: 316px;
margin-top: 26px; margin-top: 26px;

View File

@ -49,6 +49,10 @@ function HeadOrHeart() {
id: "both", id: "both",
title: translate("/head-or-heart.answer3"), title: translate("/head-or-heart.answer3"),
}, },
{
id: "depends",
title: translate("/head-or-heart.answer4"),
},
], ],
[translate] [translate]
); );

View File

@ -1,6 +1,6 @@
import { ELottieKeys, useLottie } from "@/hooks/lottie/useLottie"; // import { ELottieKeys, useLottie } from "@/hooks/lottie/useLottie";
import styles from "./styles.module.scss"; import styles from "./styles.module.scss";
import { DotLottieReact } from "@lottiefiles/dotlottie-react"; // import { DotLottieReact } from "@lottiefiles/dotlottie-react";
import Title from "@/components/Title"; import Title from "@/components/Title";
import { useTranslations } from "@/hooks/translations"; import { useTranslations } from "@/hooks/translations";
import { ELocalesPlacement } from "@/locales"; import { ELocalesPlacement } from "@/locales";
@ -11,20 +11,22 @@ import Button from "../../components/Button";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import routes from "@/routes"; import routes from "@/routes";
const animations = { // const animations = {
both: ELottieKeys.scalesNeutralPalmistry, // both: ELottieKeys.scalesNeutralPalmistry,
heart: ELottieKeys.scalesHeartPalmistry, // heart: ELottieKeys.scalesHeartPalmistry,
head: ELottieKeys.scalesHeadPalmistry, // head: ELottieKeys.scalesHeadPalmistry,
}; // depends: ELottieKeys.scalesNeutralPalmistry,
// };
function HeadOrHeartResult() { function HeadOrHeartResult() {
const navigate = useNavigate(); const navigate = useNavigate();
const { translate } = useTranslations(ELocalesPlacement.V1); const { translate } = useTranslations(ELocalesPlacement.V1);
const { headOrHeart } = useSelector(selectors.selectPalmistryV1Answers); const { headOrHeart } = useSelector(selectors.selectPalmistryV1Answers);
const { gender } = useSelector(selectors.selectQuestionnaire);
const { animationData } = useLottie({ // const { animationData } = useLottie({
loadKey: animations[headOrHeart as keyof typeof animations], // loadKey: animations[headOrHeart as keyof typeof animations],
}); // });
const birthdate = useSelector(selectors.selectBirthdate); const birthdate = useSelector(selectors.selectBirthdate);
const zodiacSign = getZodiacSignByDate(birthdate); const zodiacSign = getZodiacSignByDate(birthdate);
@ -40,7 +42,7 @@ function HeadOrHeartResult() {
return ( return (
<section className={styles.container}> <section className={styles.container}>
<div className={styles["animation-container"]}> {/* <div className={styles["animation-container"]}>
{animationData && ( {animationData && (
<DotLottieReact <DotLottieReact
className={`${styles["lottie-animation"]} ym-hide-content`} className={`${styles["lottie-animation"]} ym-hide-content`}
@ -49,7 +51,7 @@ function HeadOrHeartResult() {
loop={false} loop={false}
/> />
)} )}
</div> </div> */}
<Title variant="h1" className={styles.title}> <Title variant="h1" className={styles.title}>
{headOrHeart === "both" && {headOrHeart === "both" &&
translate("/both.title", { translate("/both.title", {
@ -61,6 +63,7 @@ function HeadOrHeartResult() {
{translate(`zodiac_signs.${zodiacSign?.toLowerCase()}`)} {translate(`zodiac_signs.${zodiacSign?.toLowerCase()}`)}
</b> </b>
), ),
gender: translate(gender?.toLowerCase()).toLowerCase()
})} })}
{headOrHeart === "head" && {headOrHeart === "head" &&
translate("/with-head.title", { translate("/with-head.title", {
@ -69,6 +72,7 @@ function HeadOrHeartResult() {
{translate(`zodiac_signs.${zodiacSign?.toLowerCase()}`)} {translate(`zodiac_signs.${zodiacSign?.toLowerCase()}`)}
</b> </b>
), ),
gender: translate(gender?.toLowerCase()).toLowerCase()
})} })}
{headOrHeart === "heart" && {headOrHeart === "heart" &&
translate("/with-heart.title", { translate("/with-heart.title", {
@ -77,7 +81,18 @@ function HeadOrHeartResult() {
{translate(`zodiac_signs.${zodiacSign?.toLowerCase()}`)} {translate(`zodiac_signs.${zodiacSign?.toLowerCase()}`)}
</b> </b>
), ),
gender: translate(gender?.toLowerCase()).toLowerCase()
})} })}
{headOrHeart === "depends" &&
translate("/depends.title", {
zodiacSign: (
<b style={{ color: "#224e90" }}>
{translate(`zodiac_signs.${zodiacSign?.toLowerCase()}`)}
</b>
),
gender: translate(gender?.toLowerCase()).toLowerCase()
})
}
</Title> </Title>
<div className={styles["buttons-container"]}> <div className={styles["buttons-container"]}>
<Button <Button

View File

@ -40,6 +40,18 @@ function RelationshipStatus() {
id: "in_relationship", id: "in_relationship",
title: translate("/relationship-status.answer2"), title: translate("/relationship-status.answer2"),
}, },
{
id: "engaged",
title: translate("/relationship-status.answer3"),
},
{
id: "divorced",
title: translate("/relationship-status.answer4"),
},
{
id: "complicated",
title: translate("/relationship-status.answer5"),
},
], ],
[translate] [translate]
); );

View File

@ -40,6 +40,10 @@ function WhatAspects() {
id: "career_destiny", id: "career_destiny",
title: translate("/what-aspects.answer3"), title: translate("/what-aspects.answer3"),
}, },
{
id: "life_transitions",
title: translate("/what-aspects.answer4"),
},
], ],
[translate] [translate]
); );

View File

@ -7,9 +7,7 @@ import Button from "../../components/Button";
import { usePaywall } from "@/hooks/paywall/usePaywall"; import { usePaywall } from "@/hooks/paywall/usePaywall";
import { EPlacementKeys } from "@/api/resources/Paywall"; import { EPlacementKeys } from "@/api/resources/Paywall";
import { addCurrency, ELocalesPlacement } from "@/locales"; import { addCurrency, ELocalesPlacement } from "@/locales";
import Modal from "@/components/Modal"; import { useEffect } from "react";
import { useEffect, useState } from "react";
import PaymentForm from "@/components/Payment/nmi/PaymentForm";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import routes from "@/routes"; import routes from "@/routes";
import { useDispatch } from "react-redux"; import { useDispatch } from "react-redux";
@ -17,6 +15,7 @@ import { actions } from "@/store";
import { useTranslations } from "@/hooks/translations"; import { useTranslations } from "@/hooks/translations";
import { useDynamicSize } from "@/hooks/useDynamicSize"; import { useDynamicSize } from "@/hooks/useDynamicSize";
import Header from "@/components/pages/ABDesign/v1/components/Header"; import Header from "@/components/pages/ABDesign/v1/components/Header";
import { usePayment } from "@/hooks/payment/nmi/usePayment";
const placementKey = EPlacementKeys["aura.placement.email.palmistry.discount"] const placementKey = EPlacementKeys["aura.placement.email.palmistry.discount"]
@ -42,25 +41,47 @@ function SecretDiscount() {
})) }))
}, [activeProduct]) }, [activeProduct])
const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false); // const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false);
const {
error,
isPaymentSuccess,
showCreditCardForm,
} = usePayment({
placementKey,
activeProduct,
paymentFormType: "lightbox"
});
const onPaymentSuccess = () => { const onPaymentSuccess = () => {
return navigate(routes.client.paymentSuccess()) return navigate(routes.client.paymentSuccess())
} }
const onModalClosed = () => { // const onModalClosed = () => {
setIsPaymentModalOpen(false); // // setIsPaymentModalOpen(false);
} // }
const onPaymentError = () => { const onPaymentError = () => {
return navigate(routes.client.paymentFail()) return navigate(routes.client.paymentFail())
} }
const openPaymentModal = () => { const openPaymentModal = () => {
setIsPaymentModalOpen(true); // setIsPaymentModalOpen(true);
showCreditCardForm();
}; };
useEffect(() => {
if (error) {
onPaymentError();
}
}, [error])
useEffect(() => {
if (isPaymentSuccess) {
onPaymentSuccess();
}
}, [isPaymentSuccess])
return ( return (
<section className={styles.container} ref={elementRef} style={{ <section className={styles.container} ref={elementRef} style={{
paddingBottom: `${height + 42}px` paddingBottom: `${height + 42}px`
@ -70,7 +91,7 @@ function SecretDiscount() {
classNameTitle={styles["header-title"]} classNameTitle={styles["header-title"]}
isBackButtonVisible={true} isBackButtonVisible={true}
/> />
{activeProduct && ( {/* {activeProduct && (
<Modal <Modal
containerClassName={styles.modal} containerClassName={styles.modal}
open={isPaymentModalOpen} open={isPaymentModalOpen}
@ -83,7 +104,7 @@ function SecretDiscount() {
onPaymentSuccess={onPaymentSuccess} onPaymentSuccess={onPaymentSuccess}
/> />
</Modal> </Modal>
)} )} */}
<Blob3 className={styles.blob3} /> <Blob3 className={styles.blob3} />
<Title className={styles.title} variant="h1"> <Title className={styles.title} variant="h1">
{translate("secret-discount.title")} {translate("secret-discount.title")}

View File

@ -14,15 +14,14 @@ import { EPlacementKeys } from "@/api/resources/Paywall";
import { usePaywall } from "@/hooks/paywall/usePaywall"; import { usePaywall } from "@/hooks/paywall/usePaywall";
import MoneyBackGuarantee from "../../components/MoneyBackGuarantee"; import MoneyBackGuarantee from "../../components/MoneyBackGuarantee";
import PalmsSayAbout from "../../components/PalmsSayAbout"; import PalmsSayAbout from "../../components/PalmsSayAbout";
import { useCallback, useEffect, useMemo, useState } from "react"; import { useCallback, useEffect, useMemo } from "react";
import { getZodiacSignByDate } from "@/services/zodiac-sign"; import { getZodiacSignByDate } from "@/services/zodiac-sign";
import WithPartnerInformation from "../../components/WithPartnerInformation"; import WithPartnerInformation from "../../components/WithPartnerInformation";
import PersonalInformation from "../../components/PersonalInformation"; import PersonalInformation from "../../components/PersonalInformation";
import Reviews from "../../components/Reviews"; import Reviews from "../../components/Reviews";
import Address from "../../components/Address"; import Address from "../../components/Address";
import Modal from "@/components/Modal";
import PaymentForm from "@/components/Payment/nmi/PaymentForm";
import { useApi, useApiCall, User } from "@/api"; import { useApi, useApiCall, User } from "@/api";
import { usePayment } from "@/hooks/payment/nmi/usePayment";
const placementKey = EPlacementKeys["aura.placement.email.palmistry"]; const placementKey = EPlacementKeys["aura.placement.email.palmistry"];
@ -51,14 +50,43 @@ function TrialPayment() {
const partnerZodiacSign = getZodiacSignByDate(partnerBirthdate); const partnerZodiacSign = getZodiacSignByDate(partnerBirthdate);
const navigate = useNavigate(); const navigate = useNavigate();
const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false); // const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false);
const {
error,
isPaymentSuccess,
isModalClosed,
showCreditCardForm,
} = usePayment({
placementKey,
activeProduct,
paymentFormType: "lightbox"
});
useEffect(() => {
if (error) {
onPaymentError();
}
}, [error])
useEffect(() => {
if (isPaymentSuccess) {
onPaymentSuccess();
}
}, [isPaymentSuccess])
useEffect(() => {
if (isModalClosed) {
onModalClosed();
}
}, [isModalClosed])
const onPaymentSuccess = () => { const onPaymentSuccess = () => {
return navigate(routes.client.paymentSuccess()) return navigate(routes.client.paymentSuccess())
} }
const onModalClosed = () => { const onModalClosed = () => {
setIsPaymentModalOpen(false); // setIsPaymentModalOpen(false);
return handleDiscount() return handleDiscount()
} }
@ -71,7 +99,8 @@ function TrialPayment() {
} }
const openPaymentModal = () => { const openPaymentModal = () => {
setIsPaymentModalOpen(true); // setIsPaymentModalOpen(true);
showCreditCardForm();
}; };
const userData = useCallback(async () => { const userData = useCallback(async () => {
@ -97,13 +126,13 @@ function TrialPayment() {
return ( return (
<> <>
<Modal containerClassName={styles.modal} open={isPaymentModalOpen} onClose={onModalClosed}> {/* <Modal containerClassName={styles.modal} open={isPaymentModalOpen} onClose={onModalClosed}>
<PaymentForm <PaymentForm
placementKey={placementKey} placementKey={placementKey}
onPaymentError={onPaymentError} onPaymentError={onPaymentError}
onPaymentSuccess={onPaymentSuccess} onPaymentSuccess={onPaymentSuccess}
/> />
</Modal> </Modal> */}
<div className={styles.background} /> <div className={styles.background} />
<div className={styles.header}> <div className={styles.header}>
<Title className={styles.title}> <Title className={styles.title}>

View File

@ -26,7 +26,7 @@ function PrivacyPolicy({ containerClassName = "", haveCheckbox = true }: IPrivac
{translate("policy", { {translate("policy", {
privacyPolicy: ( privacyPolicy: (
<a <a
href="https://aura.wit.life/privacy" href="https://witapps.us/en/privacy"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >
@ -35,7 +35,7 @@ function PrivacyPolicy({ containerClassName = "", haveCheckbox = true }: IPrivac
), ),
termsOfUse: ( termsOfUse: (
<a <a
href="https://aura.wit.life/terms" href="https://witapps.us/en/terms"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >

View File

@ -28,8 +28,7 @@ import metricService, {
} from "@/services/metric/metricService"; } from "@/services/metric/metricService";
import { useTranslations } from "@/hooks/translations"; import { useTranslations } from "@/hooks/translations";
import { ELocalesPlacement } from "@/locales"; import { ELocalesPlacement } from "@/locales";
import Modal from "@/components/Modal"; import { usePayment } from "@/hooks/payment/nmi/usePayment";
import PaymentForm from "@/components/Payment/nmi/PaymentForm";
const placementKey = EPlacementKeys["aura.placement.redesign.main"] const placementKey = EPlacementKeys["aura.placement.redesign.main"]
@ -60,14 +59,44 @@ function TrialPaymentPage() {
>("single"); >("single");
const { subPlan } = useParams(); const { subPlan } = useParams();
const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false);
const {
error,
isPaymentSuccess,
showCreditCardForm,
isModalClosed
} = usePayment({
placementKey,
activeProduct: activeProduct || products[0],
paymentFormType: "lightbox"
});
// const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false);
useEffect(() => {
if (error) {
onPaymentError();
}
}, [error])
useEffect(() => {
if (isPaymentSuccess) {
onPaymentSuccess();
}
}, [isPaymentSuccess])
useEffect(() => {
if (isModalClosed) {
onModalClosed()
}
}, [isModalClosed])
const onPaymentSuccess = () => { const onPaymentSuccess = () => {
return navigate(routes.client.paymentSuccess()) return navigate(routes.client.paymentSuccess())
} }
const onModalClosed = () => { const onModalClosed = () => {
setIsPaymentModalOpen(false); // setIsPaymentModalOpen(false);
return handleDiscount() return handleDiscount()
} }
@ -129,7 +158,8 @@ function TrialPaymentPage() {
const openPaymentModal = () => { const openPaymentModal = () => {
metricService.reachGoal(EGoals.AURA_PAYMENT_METHODS_OPENED); metricService.reachGoal(EGoals.AURA_PAYMENT_METHODS_OPENED);
setIsPaymentModalOpen(true); // setIsPaymentModalOpen(true);
showCreditCardForm();
}; };
return ( return (
@ -140,13 +170,13 @@ function TrialPaymentPage() {
backgroundColor: gender === "male" ? "#C1E5FF" : "#F7EBFF", backgroundColor: gender === "male" ? "#C1E5FF" : "#F7EBFF",
}} }}
> >
<Modal containerClassName={styles.modal} open={isPaymentModalOpen} onClose={onModalClosed}> {/* <Modal containerClassName={styles.modal} open={isPaymentModalOpen} onClose={onModalClosed}>
<PaymentForm <PaymentForm
placementKey={placementKey} placementKey={placementKey}
onPaymentError={onPaymentError} onPaymentError={onPaymentError}
onPaymentSuccess={onPaymentSuccess} onPaymentSuccess={onPaymentSuccess}
/> />
</Modal> </Modal> */}
<div className={styles["background-top-blob-container"]}> <div className={styles["background-top-blob-container"]}>
<BackgroundTopBlob <BackgroundTopBlob
width={pageWidth} width={pageWidth}

View File

@ -1,6 +1,6 @@
import styles from "./styles.module.css"; import styles from "./styles.module.css";
import PaymentDiscountTable from "./PaymentDiscountTable"; import PaymentDiscountTable from "./PaymentDiscountTable";
import { useState } from "react"; import { useEffect } from "react";
import { selectors } from "@/store"; import { selectors } from "@/store";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { EPlacementKeys } from "@/api/resources/Paywall"; import { EPlacementKeys } from "@/api/resources/Paywall";
@ -10,8 +10,7 @@ import DiscountLayout from "../../layouts/Discount/DiscountLayout";
import QuestionnaireGreenButton from "../../ui/GreenButton"; import QuestionnaireGreenButton from "../../ui/GreenButton";
import { Navigate, useNavigate } from "react-router-dom"; import { Navigate, useNavigate } from "react-router-dom";
import routes from "@/routes"; import routes from "@/routes";
import PaymentForm from "@/components/Payment/nmi/PaymentForm"; import { usePayment } from "@/hooks/payment/nmi/usePayment";
import Modal from "@/components/Modal";
const placementKey = EPlacementKeys["aura.placement.secret.discount"]; const placementKey = EPlacementKeys["aura.placement.secret.discount"];
@ -20,37 +19,60 @@ function TrialPaymentWithDiscount() {
const { translate } = useTranslations(ELocalesPlacement.V1); const { translate } = useTranslations(ELocalesPlacement.V1);
const activeProduct = useSelector(selectors.selectActiveProduct); const activeProduct = useSelector(selectors.selectActiveProduct);
const currency = useSelector(selectors.selectCurrency); const currency = useSelector(selectors.selectCurrency);
const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false); // const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false);
if (!activeProduct) { if (!activeProduct) {
return <Navigate to={routes.client.additionalDiscountV1()} /> return <Navigate to={routes.client.additionalDiscountV1()} />
} }
const {
error,
isPaymentSuccess,
showCreditCardForm,
} = usePayment({
placementKey,
activeProduct,
paymentFormType: "lightbox"
});
const onPaymentSuccess = () => { const onPaymentSuccess = () => {
return navigate(routes.client.paymentSuccess()) return navigate(routes.client.paymentSuccess())
} }
const onModalClosed = () => { // const onModalClosed = () => {
setIsPaymentModalOpen(false); // // setIsPaymentModalOpen(false);
} // }
const onPaymentError = () => { const onPaymentError = () => {
return navigate(routes.client.paymentFail()) return navigate(routes.client.paymentFail())
} }
const openPaymentModal = () => { const openPaymentModal = () => {
setIsPaymentModalOpen(true); // setIsPaymentModalOpen(true);
showCreditCardForm();
}; };
useEffect(() => {
if (error) {
onPaymentError();
}
}, [error])
useEffect(() => {
if (isPaymentSuccess) {
onPaymentSuccess();
}
}, [isPaymentSuccess])
return ( return (
<DiscountLayout title={translate("/trial-payment-with-discount.title")}> <DiscountLayout title={translate("/trial-payment-with-discount.title")}>
<Modal containerClassName={styles.modal} open={isPaymentModalOpen} onClose={onModalClosed}> {/* <Modal containerClassName={styles.modal} open={isPaymentModalOpen} onClose={onModalClosed}>
<PaymentForm <PaymentForm
placementKey={placementKey} placementKey={placementKey}
onPaymentError={onPaymentError} onPaymentError={onPaymentError}
onPaymentSuccess={onPaymentSuccess} onPaymentSuccess={onPaymentSuccess}
/> />
</Modal> </Modal> */}
<PaymentDiscountTable /> <PaymentDiscountTable />
<div className={styles['button-wrapper']}> <div className={styles['button-wrapper']}>

View File

@ -14,7 +14,8 @@ function GetInformationPartnerPage() {
const handleBack = () => { const handleBack = () => {
if (path === "palmistry") { if (path === "palmistry") {
return navigate(routes.client.addGuides()); return navigate(routes.client.skipTrial());
// return navigate(routes.client.addGuides());
} }
navigate(routes.client.addConsultationV1()); navigate(routes.client.addConsultationV1());
}; };

View File

@ -1,19 +1,19 @@
import { Outlet } from "react-router-dom"; import { Outlet } from "react-router-dom";
import styles from "./styles.module.scss"; import styles from "./styles.module.scss";
import { palmistrySteps } from "@/data/additionalPurchases"; // import { palmistrySteps } from "@/data/additionalPurchases";
import AdditionalPurchasesSteps from "./components/AdditionalPurchasesSteps"; // import AdditionalPurchasesSteps from "./components/AdditionalPurchasesSteps";
function AdditionalPurchasesPalmistry() { function AdditionalPurchasesPalmistry() {
const activeStep = palmistrySteps.findIndex((value) => // const activeStep = palmistrySteps.findIndex((value) =>
window.location.href.includes(value.link) // window.location.href.includes(value.link)
); // );
return ( return (
<section className={`${styles.page} page`}> <section className={`${styles.page} page`}>
<AdditionalPurchasesSteps {/* <AdditionalPurchasesSteps
steps={palmistrySteps} steps={palmistrySteps}
activeStep={activeStep} activeStep={activeStep}
/> /> */}
<Outlet /> <Outlet />
</section> </section>
); );

View File

@ -49,11 +49,15 @@ function SkipTrial() {
token token
); );
if (isPurchasedSkipTrial || isPurchasedPremiumBundle) { if (isPurchasedSkipTrial || isPurchasedPremiumBundle) {
return navigate(routes.client.addConsultant()); return handleNext();
} }
})(); })();
}, [checkProductPurchased, navigate, token]); }, [checkProductPurchased, navigate, token]);
const handleNext = () => {
navigate(`${routes.client.getInformationPartner()}?path=palmistry`);
}
useEffect(() => { useEffect(() => {
(async () => { (async () => {
const products = await api.getSinglePaymentProducts({ token }); const products = await api.getSinglePaymentProducts({ token });
@ -77,7 +81,7 @@ function SkipTrial() {
}, [stripePublicKey]); }, [stripePublicKey]);
const goPremiumBundle = () => { const goPremiumBundle = () => {
navigate(routes.client.addConsultant()); handleNext();
}; };
const buy = async () => { const buy = async () => {

View File

@ -166,9 +166,10 @@ export const useAuthentication = () => {
setIsLoading(true); setIsLoading(true);
setError(null) setError(null)
const payload = getAuthorizationPayload(email, source); const payload = getAuthorizationPayload(email, source);
const { token, userId, generatingVideo, videoId, authCode } = await api.authorization(payload); const { token, userId: userIdFromApi, generatingVideo, videoId, authCode } = await api.authorization(payload);
const { user } = await api.getUser({ token }); const { user } = await api.getUser({ token });
const { user: userMe } = await api.getMe({ token }); const { user: userMe } = await api.getMe({ token });
const userId = userIdFromApi || userMe?._id;
if (userId?.length) { if (userId?.length) {
dispatch(actions.userId.update({ userId })); dispatch(actions.userId.update({ userId }));
metricService.userParams({ metricService.userParams({

View File

@ -639,10 +639,10 @@ export const hasFullDataModal = (path: string) => {
export const getRouteBy = (status: UserStatus): string => { export const getRouteBy = (status: UserStatus): string => {
switch (status) { switch (status) {
case "lead": case "lead":
return routes.client.genderV1(); return routes.client.palmistryV1Welcome();
case "registred": case "registred":
case "unsubscribed": case "unsubscribed":
return routes.client.trialPaymentV1(); return routes.client.palmistryV1TrialPayment();
case "subscribed": case "subscribed":
return routes.client.home(); return routes.client.home();
default: default: