From c4759f35a5a052a5ff50f2e813ef17a57fadd749 Mon Sep 17 00:00:00 2001 From: Daniil Chemerkin Date: Thu, 26 Sep 2024 14:24:20 +0000 Subject: [PATCH] Develop --- .../PalmistryV1/pages/Email/index.tsx | 2 +- .../pages/FindHappiness/styles.module.scss | 4 +- .../PalmistryV1/pages/Payment/index.tsx | 32 ++-- .../ABDesign/v1/pages/Onboarding/index.tsx | 29 +++- .../{styles.module.css => styles.module.scss} | 29 +++- .../v1/pages/TrialChoiceVideo/index.tsx | 38 ++--- .../pages/TrialChoiceVideo/styles.module.scss | 3 + .../components/PersonalVideo/index.tsx | 37 +++-- .../pages/SkipTrial/index.tsx | 12 -- .../palmistry/step-email/step-email.tsx | 2 +- .../ABDesign/v1/LayoutABDesignV1/index.tsx | 50 +++++- .../v1/LayoutABDesignV1/styles.module.css | 4 + .../v1/CheckSubscriptionOutlet/index.tsx | 28 ++++ .../Palmistry/v1/LayoutPalmistryV1/index.tsx | 18 ++- src/routerComponents/Palmistry/v1/index.tsx | 151 ++++++++++-------- src/services/metric/metricService.ts | 37 +++-- src/store/index.ts | 2 + src/store/palmistry.ts | 11 +- src/store/personalVideo.ts | 9 +- 19 files changed, 337 insertions(+), 161 deletions(-) rename src/components/pages/ABDesign/v1/pages/Onboarding/{styles.module.css => styles.module.scss} (77%) create mode 100644 src/routerComponents/Palmistry/v1/CheckSubscriptionOutlet/index.tsx diff --git a/src/components/PalmistryV1/pages/Email/index.tsx b/src/components/PalmistryV1/pages/Email/index.tsx index de1ab5b..bf96b1f 100644 --- a/src/components/PalmistryV1/pages/Email/index.tsx +++ b/src/components/PalmistryV1/pages/Email/index.tsx @@ -59,7 +59,7 @@ function Email() { EMetrics.YANDEX, EMetrics.FACEBOOK, ]); - metricService.reachGoal(EGoals.ENTER_EMAIL_PALMISTRY, [EMetrics.YANDEX]); + metricService.reachGoal(EGoals.ENTERED_EMAIL_PALMISTRY, [EMetrics.YANDEX]); await authorization(email, ESourceAuthorization["aura.palmistry.new"]); }; diff --git a/src/components/PalmistryV1/pages/FindHappiness/styles.module.scss b/src/components/PalmistryV1/pages/FindHappiness/styles.module.scss index a94b339..557a4e5 100644 --- a/src/components/PalmistryV1/pages/FindHappiness/styles.module.scss +++ b/src/components/PalmistryV1/pages/FindHappiness/styles.module.scss @@ -2,7 +2,7 @@ width: 100%; display: flex; flex-direction: row; - justify-content: space-between; + justify-content: center; align-items: center; gap: 10px; @@ -10,7 +10,7 @@ display: flex; flex-direction: row; align-items: center; - height: 52px; + max-height: 80px; padding: 12px 9px; border: solid 2px #3871c1; border-radius: 10px; diff --git a/src/components/PalmistryV1/pages/Payment/index.tsx b/src/components/PalmistryV1/pages/Payment/index.tsx index 9558458..da9c9f8 100644 --- a/src/components/PalmistryV1/pages/Payment/index.tsx +++ b/src/components/PalmistryV1/pages/Payment/index.tsx @@ -1,16 +1,12 @@ -import { useSelector } from "react-redux"; +import { useDispatch, useSelector } from "react-redux"; import PaymentInformation from "../../components/PaymentInformation"; import styles from "./styles.module.scss"; -import { selectors } from "@/store"; +import { actions, selectors } from "@/store"; import { getFormattedPrice } from "@/utils/price.utils"; import Guarantees from "../../components/Guarantees"; import Button from "../../components/Button"; import { useEffect } from "react"; -import { - useNavigate, - useOutletContext, - useSearchParams, -} from "react-router-dom"; +import { useNavigate, useSearchParams } from "react-router-dom"; import routes from "@/routes"; import { addCurrency, ELocalesPlacement } from "@/locales"; import { useTranslations } from "@/hooks/translations"; @@ -20,27 +16,23 @@ import metricService, { EMetrics, } from "@/services/metric/metricService"; -interface IPaymentContext { - isShowPaymentModal: boolean; - setIsShowPaymentModal: React.Dispatch>; -} - function Payment() { + const dispatch = useDispatch(); const { translate } = useTranslations(ELocalesPlacement.PalmistryV1); const navigate = useNavigate(); const activeProductFromStore = useSelector(selectors.selectActiveProduct); const currency = useSelector(selectors.selectCurrency); const trialPrice = activeProductFromStore?.trialPrice || 0; const fullPrice = activeProductFromStore?.price || 0; - const { isShowPaymentModal, setIsShowPaymentModal } = - useOutletContext(); - + const isShowPaymentModal = useSelector( + selectors.selectPalmistryIsShowPaymentModalV1 + ); const [searchParams] = useSearchParams(); const subscriptionStatus = searchParams.get("redirect_status") === "succeeded" ? "subscribed" : "lead"; const showModal = () => { - setIsShowPaymentModal(true); + dispatch(actions.palmistry.setIsShowPaymentModalV1(true)); }; useEffect(() => { @@ -49,11 +41,17 @@ function Payment() { metricService.reachGoal(EGoals.PAYMENT_SUCCESS_PALMISTRY, [ EMetrics.YANDEX, ]); + if (activeProductFromStore) { + metricService.reachGoal(EGoals.PURCHASE, [EMetrics.FACEBOOK], { + currency: "USD", + value: ((activeProductFromStore.trialPrice || 100) / 100).toFixed(2), + }); + } const timer = setTimeout(() => { navigate(routes.client.skipTrial()); }, 1500); return () => clearTimeout(timer); - }, [navigate, subscriptionStatus]); + }, [activeProductFromStore, navigate, subscriptionStatus]); return ( <> diff --git a/src/components/pages/ABDesign/v1/pages/Onboarding/index.tsx b/src/components/pages/ABDesign/v1/pages/Onboarding/index.tsx index da5c613..e8caebb 100644 --- a/src/components/pages/ABDesign/v1/pages/Onboarding/index.tsx +++ b/src/components/pages/ABDesign/v1/pages/Onboarding/index.tsx @@ -1,5 +1,5 @@ import Title from "@/components/Title"; -import styles from "./styles.module.css"; +import styles from "./styles.module.scss"; import { useCallback, useEffect, useRef, useState } from "react"; import routes from "@/routes"; import { useNavigate } from "react-router-dom"; @@ -16,6 +16,7 @@ import metricService, { } from "@/services/metric/metricService"; import { useTranslations } from "@/hooks/translations"; import { ELocalesPlacement } from "@/locales"; +import QuestionnaireGreenButton from "../../ui/GreenButton"; function OnboardingPage() { const { translate } = useTranslations(ELocalesPlacement.V1); @@ -25,6 +26,7 @@ function OnboardingPage() { const titleInterval = useRef(); const classNameTimeOut = useRef(); const [progress, setProgress] = useState(0); + const [isLoadingEnd, setIsLoadingEnd] = useState(false); const progressInterval = useRef(); usePaywall({ placementKey: EPlacementKeys["aura.placement.redesign.main"], @@ -50,9 +52,12 @@ function OnboardingPage() { useEffect(() => { if (isVideoReady && progress >= 100) { - handleNext(); + if (auraVideoTrial === "on") { + return setIsLoadingEnd(true); + } + return handleNext(); } - }, [activeIndexTitle, handleNext, isVideoReady, progress]); + }, [activeIndexTitle, auraVideoTrial, handleNext, isVideoReady, progress]); useEffect(() => { setPeriodClassName("to-nontransparent"); @@ -115,19 +120,33 @@ function OnboardingPage() { )}
-
+
{translate("/onboarding.loader_title")}

{progress}%

+ {isLoadingEnd && ( + + Next + + )}
); diff --git a/src/components/pages/ABDesign/v1/pages/Onboarding/styles.module.css b/src/components/pages/ABDesign/v1/pages/Onboarding/styles.module.scss similarity index 77% rename from src/components/pages/ABDesign/v1/pages/Onboarding/styles.module.css rename to src/components/pages/ABDesign/v1/pages/Onboarding/styles.module.scss index 2219e09..7baf525 100644 --- a/src/components/pages/ABDesign/v1/pages/Onboarding/styles.module.css +++ b/src/components/pages/ABDesign/v1/pages/Onboarding/styles.module.scss @@ -6,7 +6,7 @@ height: fit-content; min-height: 100vh; min-height: 100dvh; - background: #0F1323; + background: #0f1323; width: 100%; max-width: 460px; padding: 15px 40px calc(0dvh + 63px); @@ -20,7 +20,7 @@ } .title { - color: #BDEBFF; + color: #bdebff; text-align: center; max-width: 300px; font-size: 32px; @@ -40,8 +40,13 @@ } .progress-bar__container { - background-color: #ACDCFF; + background-color: #acdcff; height: 9px; + transition: opacity 1s; +} + +.hide { + opacity: 0; } .progress-bar__text-container { @@ -51,6 +56,7 @@ justify-content: space-between; align-items: center; padding: 0 12px; + transition: opacity 1s; } .progress-bar__text-container * { @@ -63,6 +69,7 @@ } .footer { + position: relative; width: 100%; display: flex; flex-direction: column; @@ -84,3 +91,19 @@ opacity: 0; } } + +.button { + position: absolute; + top: 0; + animation: appearance 1s forwards 1s; + opacity: 0; +} + +@keyframes appearance { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} diff --git a/src/components/pages/ABDesign/v1/pages/TrialChoiceVideo/index.tsx b/src/components/pages/ABDesign/v1/pages/TrialChoiceVideo/index.tsx index d6fa563..19370e0 100644 --- a/src/components/pages/ABDesign/v1/pages/TrialChoiceVideo/index.tsx +++ b/src/components/pages/ABDesign/v1/pages/TrialChoiceVideo/index.tsx @@ -2,7 +2,7 @@ import styles from "./styles.module.scss"; import { useEffect, useRef, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { actions, selectors } from "@/store"; -import { useNavigate } from "react-router-dom"; +import { useNavigate, useOutletContext } from "react-router-dom"; import routes from "@/routes"; import EmailsList from "@/components/EmailsList"; import Header from "../../components/Header"; @@ -19,12 +19,12 @@ import metricService, { EMetrics, useMetricABFlags, } from "@/services/metric/metricService"; -import PersonalVideo from "../TrialPayment/components/PersonalVideo"; import Toast from "../../components/Toast"; import BlurComponent from "@/components/BlurComponent"; import { useTranslations } from "@/hooks/translations"; import { ELocalesPlacement } from "@/locales"; import DiscountExpires from "../TrialPayment/components/DiscountExpires"; +import { IOutletContext } from "@/routerComponents/ABDesign/v1/LayoutABDesignV1"; enum EDisplayOptionButton { "alwaysVisible" = "alwaysVisible", @@ -44,7 +44,6 @@ function TrialChoiceVideoPage() { const [isDisabled, setIsDisabled] = useState(true); const [visibleToast, setVisibleToast] = useState(false); const [countUsers, setCountUsers] = useState(752); - const [isVisibleElements, setIsVisibleElements] = useState(false); const { width: pageWidth, elementRef: pageRef } = useDynamicSize({}); const { gender } = useSelector(selectors.selectQuestionnaire); const { products, isLoading, currency, getText } = usePaywall({ @@ -52,31 +51,26 @@ function TrialChoiceVideoPage() { localesPlacement: ELocalesPlacement.V1, }); const arrowLeft = useSelector(selectors.selectTrialChoiceArrowOptions)?.left; - const showElementsTimer = useRef(); + const containerVideoRef = useRef(null); + + const { containerVideoRef: videoRef, isVisibleElements } = + useOutletContext(); const { flags } = useMetricABFlags(); const isShowTimer = flags?.showTimerTrial?.[0] === "show"; const { videoUrl } = useSelector(selectors.selectPersonalVideo); + useEffect(() => { + dispatch(actions.personalVideo.updateIsVideoPlaying(true)); + }, [dispatch]); + useEffect(() => { metricService.reachGoal(EGoals.AURA_TRIAL_CHOICE_PAGE_VISIT, [ EMetrics.KLAVIYO, ]); }, []); - useEffect(() => { - return () => { - if (showElementsTimer.current) clearTimeout(showElementsTimer.current); - }; - }, []); - - const showElements = () => { - showElementsTimer.current = setTimeout(() => { - setIsVisibleElements(true); - }, 33_000); - }; - useEffect(() => { const randomDelay = getRandomArbitrary(3000, 5000); const countUsersTimeOut = setTimeout(() => { @@ -111,6 +105,12 @@ function TrialChoiceVideoPage() { return () => clearTimeout(timeOut); }, [visibleToast]); + useEffect(() => { + if (!containerVideoRef.current || !videoRef.current) return; + containerVideoRef.current?.appendChild(videoRef.current); + videoRef.current.classList.add(styles["personal-video"]); + }, [videoRef]); + return (
- + {/* + /> */} + {/* {containerVideoRef.current?.ELEMENT_NODE} */} {!isLoading && isVisibleElements && ( <> {isShowTimer && ( diff --git a/src/components/pages/ABDesign/v1/pages/TrialChoiceVideo/styles.module.scss b/src/components/pages/ABDesign/v1/pages/TrialChoiceVideo/styles.module.scss index 677b889..04387b7 100644 --- a/src/components/pages/ABDesign/v1/pages/TrialChoiceVideo/styles.module.scss +++ b/src/components/pages/ABDesign/v1/pages/TrialChoiceVideo/styles.module.scss @@ -156,6 +156,7 @@ bottom: calc(0dvh + 16px); width: calc(100% - 84px) !important; max-width: 396px; + z-index: 999; } .gradient-blur { @@ -195,6 +196,8 @@ // position: fixed !important; // top: 0dvh; // z-index: 30; + + display: block; margin-top: 32px !important; border-radius: 0 !important; background-image: url("/trial-choice-preview.png") !important; diff --git a/src/components/pages/ABDesign/v1/pages/TrialPayment/components/PersonalVideo/index.tsx b/src/components/pages/ABDesign/v1/pages/TrialPayment/components/PersonalVideo/index.tsx index f852e9f..cc68ce9 100644 --- a/src/components/pages/ABDesign/v1/pages/TrialPayment/components/PersonalVideo/index.tsx +++ b/src/components/pages/ABDesign/v1/pages/TrialPayment/components/PersonalVideo/index.tsx @@ -5,12 +5,16 @@ import Loader from "@/components/Loader"; import PlayButton from "../../../../ui/PlayButton"; import metricService, { EGoals } from "@/services/metric/metricService"; import PlayPauseButton from "../../../../ui/PlayPauseButton"; +import { useDispatch, useSelector } from "react-redux"; +import { actions, selectors } from "@/store"; interface IPersonalVideoProps { gender: string; url: string; classNameContainer?: string; isVisibleControllers?: boolean; + containerRef?: React.RefObject; + isAutoPlay?: boolean; onVideoStart?: () => void; } @@ -20,12 +24,19 @@ const PersonalVideo = React.memo( gender, classNameContainer = "", isVisibleControllers = true, + containerRef, + isAutoPlay = true, onVideoStart, }) => { - const [isPlaying, setIsPlaying] = useState(false); + const dispatch = useDispatch(); + const { isVideoPlaying } = useSelector(selectors.selectPersonalVideo); const [isStarted, setIsStarted] = useState(false); const [isError, setIsError] = useState(false); + const setIsPlaying = (isPlaying: boolean) => { + dispatch(actions.personalVideo.updateIsVideoPlaying(isPlaying)); + }; + const onError = (error: unknown) => { if (!error) return; setIsError(true); @@ -34,6 +45,7 @@ const PersonalVideo = React.memo( const onStart = () => { setIsStarted(true); + setIsError(false); if (onVideoStart) onVideoStart(); metricService.reachGoal(EGoals.ROSE_VIDEO_PLAY_START); }; @@ -43,14 +55,19 @@ const PersonalVideo = React.memo( }; const handlePlayPause = () => { - setIsPlaying((prev) => !prev); - if (isPlaying) metricService.reachGoal(EGoals.ROSE_VIDEO_PLAY_USER_PLAY); - if (!isPlaying) metricService.reachGoal(EGoals.ROSE_VIDEO_PLAY_USER_STOP); + setIsPlaying(!isVideoPlaying); + if (isVideoPlaying) + metricService.reachGoal(EGoals.ROSE_VIDEO_PLAY_USER_PLAY); + if (!isVideoPlaying) + metricService.reachGoal(EGoals.ROSE_VIDEO_PLAY_USER_STOP); }; return ( -
- {!isPlaying && !isError && !isStarted && ( +
+ {!isVideoPlaying && !isError && !isStarted && ( )} {isError && ( @@ -68,22 +85,24 @@ const PersonalVideo = React.memo( controls={false} light={false} muted={false} - playing={isPlaying} + playing={isVideoPlaying} stopOnUnmount={true} width="100%" onStart={onStart} - onReady={() => setIsPlaying(true)} + onReady={() => setIsPlaying(isAutoPlay)} onEnded={onEnded} onError={onError} playsinline={true} height={"auto"} style={{ aspectRatio: "16 / 9", + position: "relative", + zIndex: 1, }} /> {!isError && isStarted && isVisibleControllers && ( diff --git a/src/components/palmistry/AdditionalPurchases/pages/SkipTrial/index.tsx b/src/components/palmistry/AdditionalPurchases/pages/SkipTrial/index.tsx index 7f324c3..2f67664 100644 --- a/src/components/palmistry/AdditionalPurchases/pages/SkipTrial/index.tsx +++ b/src/components/palmistry/AdditionalPurchases/pages/SkipTrial/index.tsx @@ -17,10 +17,6 @@ import { Elements } from "@stripe/react-stripe-js"; import CheckoutForm from "@/components/PaymentPage/methods/CheckoutForm"; import { useSinglePayment } from "@/hooks/payment/useSinglePayment"; import { useTranslations } from "@/hooks/translations"; -import metricService, { - EGoals, - EMetrics, -} from "@/services/metric/metricService"; const currentProductKey = "skip.trial.subscription.aura"; const returnUrl = `${window.location.host}${routes.client.addConsultant()}`; @@ -42,14 +38,6 @@ function SkipTrial() { const activeProductFromStore = useSelector(selectors.selectActiveProduct); - useEffect(() => { - if (!activeProductFromStore?.trialPrice) return; - metricService.reachGoal(EGoals.PURCHASE, [EMetrics.FACEBOOK], { - currency: "USD", - value: ((activeProductFromStore.trialPrice || 100) / 100).toFixed(2), - }); - }, [activeProductFromStore?.trialPrice]); - useEffect(() => { (async () => { const isPurchasedSkipTrial = await checkProductPurchased( diff --git a/src/components/palmistry/step-email/step-email.tsx b/src/components/palmistry/step-email/step-email.tsx index f425607..82c3a92 100644 --- a/src/components/palmistry/step-email/step-email.tsx +++ b/src/components/palmistry/step-email/step-email.tsx @@ -47,12 +47,12 @@ export default function StepEmail() { const authorize = async () => { await authorization(email, ESourceAuthorization["aura.palmistry"]); + metricService.reachGoal(EGoals.ENTERED_EMAIL_PALMISTRY, [EMetrics.YANDEX]); metricService.reachGoal(EGoals.ENTERED_EMAIL, [ EMetrics.KLAVIYO, EMetrics.YANDEX, EMetrics.FACEBOOK, ]); - metricService.reachGoal(EGoals.ENTER_EMAIL_PALMISTRY, [EMetrics.YANDEX]); metricService.reachGoal(EGoals.LEAD, [EMetrics.FACEBOOK]); setIsAuth(true); }; diff --git a/src/routerComponents/ABDesign/v1/LayoutABDesignV1/index.tsx b/src/routerComponents/ABDesign/v1/LayoutABDesignV1/index.tsx index 9de497c..248a987 100644 --- a/src/routerComponents/ABDesign/v1/LayoutABDesignV1/index.tsx +++ b/src/routerComponents/ABDesign/v1/LayoutABDesignV1/index.tsx @@ -1,20 +1,66 @@ +import PersonalVideo from "@/components/pages/ABDesign/v1/pages/TrialPayment/components/PersonalVideo"; import styles from "./styles.module.css"; import { useSchemeColorByElement } from "@/hooks/useSchemeColorByElement"; -import { useRef } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import { Outlet, useLocation } from "react-router-dom"; +import { useDispatch, useSelector } from "react-redux"; +import { actions, selectors } from "@/store"; +import routes from "@/routes"; + +export interface IOutletContext { + containerVideoRef: React.RefObject; + isVisibleElements: boolean; + setIsVisibleElements: (value: boolean) => void; + setShowElements: (value: () => void) => void; +} function LayoutABDesignV1() { + const dispatch = useDispatch(); const location = useLocation(); const mainRef = useRef(null); useSchemeColorByElement(mainRef.current, "section.page, .page, section", [ location, ]); + const [isVisibleElements, setIsVisibleElements] = useState(false); + const { gender } = useSelector(selectors.selectQuestionnaire); + const containerVideoRef = useRef(null); + const showElementsTimer = useRef(); + + const showElements = useCallback(() => { + showElementsTimer.current = setTimeout(() => { + setIsVisibleElements(true); + }, 33_000); + }, [setIsVisibleElements]); + + useEffect(() => { + if (location.pathname !== routes.client.trialChoiceVideoV1()) { + dispatch(actions.personalVideo.updateIsVideoPlaying(false)); + } + }, [dispatch, location.pathname]); return ( <>
{/* }> */} - + + {/* */}
diff --git a/src/routerComponents/ABDesign/v1/LayoutABDesignV1/styles.module.css b/src/routerComponents/ABDesign/v1/LayoutABDesignV1/styles.module.css index aa032d7..69d6bc0 100644 --- a/src/routerComponents/ABDesign/v1/LayoutABDesignV1/styles.module.css +++ b/src/routerComponents/ABDesign/v1/LayoutABDesignV1/styles.module.css @@ -1,3 +1,7 @@ .main { align-items: center; +} + +.personal-video, .personal-video > * { + display: none; } \ No newline at end of file diff --git a/src/routerComponents/Palmistry/v1/CheckSubscriptionOutlet/index.tsx b/src/routerComponents/Palmistry/v1/CheckSubscriptionOutlet/index.tsx new file mode 100644 index 0000000..8fdcd5c --- /dev/null +++ b/src/routerComponents/Palmistry/v1/CheckSubscriptionOutlet/index.tsx @@ -0,0 +1,28 @@ +import { useAuth } from "@/auth"; +import routes from "@/routes"; +import { selectors } from "@/store"; +import { useSelector } from "react-redux"; +import { Navigate, Outlet } from "react-router-dom"; + +interface ICheckSubscriptionOutletProps { + subscribedReturnUrl?: string; + unsubscribedReturnUrl?: string; +} + +function CheckSubscriptionOutlet({ + subscribedReturnUrl = routes.client.home(), + unsubscribedReturnUrl, +}: ICheckSubscriptionOutletProps) { + const status = useSelector(selectors.selectStatus); + const { user } = useAuth(); + + if (user && status === "subscribed") { + return ; + } + if (unsubscribedReturnUrl?.length) { + return ; + } + return ; +} + +export default CheckSubscriptionOutlet; diff --git a/src/routerComponents/Palmistry/v1/LayoutPalmistryV1/index.tsx b/src/routerComponents/Palmistry/v1/LayoutPalmistryV1/index.tsx index 7b4e529..5610a7f 100644 --- a/src/routerComponents/Palmistry/v1/LayoutPalmistryV1/index.tsx +++ b/src/routerComponents/Palmistry/v1/LayoutPalmistryV1/index.tsx @@ -1,12 +1,12 @@ import Header from "@/components/pages/ABDesign/v1/components/Header"; import styles from "./styles.module.css"; import { useSchemeColorByElement } from "@/hooks/useSchemeColorByElement"; -import { useRef, useState } from "react"; +import { useEffect, useRef } from "react"; import { Outlet, useLocation, useSearchParams } from "react-router-dom"; import routes from "@/routes"; import PaymentModal from "@/components/PalmistryV1/components/PaymentModal"; -import { useSelector } from "react-redux"; -import { selectors } from "@/store"; +import { useDispatch, useSelector } from "react-redux"; +import { actions, selectors } from "@/store"; const isBackButtonVisibleRoutes = [ routes.client.palmistryV1Birthdate(), @@ -27,6 +27,7 @@ const isBackButtonVisibleRoutes = [ ]; function LayoutPalmistryV1() { + const dispatch = useDispatch(); const token = useSelector(selectors.selectToken); const activeProductFromStore = useSelector(selectors.selectActiveProduct); const location = useLocation(); @@ -34,7 +35,9 @@ function LayoutPalmistryV1() { useSchemeColorByElement(mainRef.current, "section.page, .page, section", [ location, ]); - const [isShowPaymentModal, setIsShowPaymentModal] = useState(false); + const isShowPaymentModal = useSelector( + selectors.selectPalmistryIsShowPaymentModalV1 + ); const [searchParams] = useSearchParams(); const subscriptionStatus = searchParams.get("redirect_status") === "succeeded" ? "subscribed" : "lead"; @@ -46,6 +49,11 @@ function LayoutPalmistryV1() { return false; }; + useEffect(() => { + dispatch(actions.palmistry.setIsShowPaymentModalV1(false)); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [location]); + return ( <>
@@ -56,7 +64,7 @@ function LayoutPalmistryV1() { /> {/* }> */}
- + {!!token.length && !!activeProductFromStore && ( path.replace(palmistryV1Prefix, ""); @@ -39,89 +40,97 @@ function PalmistryV1Routes() { }> } - /> - } + element={ + + } > - } /> - - }> } + path={removePrefix(routes.client.palmistryV1Gender())} + element={} /> } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } + path={removePrefix(routes.client.palmistryV1Welcome())} + element={} > - } /> + } /> + + }> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + > + } /> + + } + /> } + path={removePrefix(routes.client.palmistryV1LetScan())} + element={} + /> + } + /> + } + /> + } + /> + } + /> + } /> } - /> - } - /> - } - /> - } - /> - } - /> - } + path={removePrefix(routes.client.palmistryV1ScannedPhoto())} + element={} /> + } /> - } - /> - } /> ); } diff --git a/src/services/metric/metricService.ts b/src/services/metric/metricService.ts index 47f903f..9f37446 100644 --- a/src/services/metric/metricService.ts +++ b/src/services/metric/metricService.ts @@ -18,7 +18,7 @@ export enum EGoals { AURA_TRIAL_CHOICE_PAGE_VISIT = "AuraTrialChoicePageVisit", AURA_TRIAL_PAYMENT_PAGE_VISIT = "AuraTrialPaymentPageVisit", PAYMENT_SUCCESS_PALMISTRY = "PaymentSuccessPalmistry", - ENTER_EMAIL_PALMISTRY = "EnterEmailPalmistry" + ENTERED_EMAIL_PALMISTRY = "EnteredEmailPalmistry" } export enum EFlags { @@ -77,21 +77,34 @@ const userParams = (parameters: Partial) => { } const reachGoal = (goal: EGoals, usingMetrics = [EMetrics.KLAVIYO, EMetrics.YANDEX], options?: unknown) => { - if (!checkIsAvailableYandexMetric()) return; - - if (usingMetrics.includes(EMetrics.YANDEX)) window.ym(metricCounterNumber, "reachGoal", goal); console.log("goal: ", goal); - if (!window.klaviyo) return console.error("Klaviyo.Metric not found"); - if (usingMetrics.includes(EMetrics.KLAVIYO)) window.klaviyo.push(['track', goal]); - - if (!window.fbq) return console.error("Facebook.Metric not found"); - - if (goal === EGoals.ENTERED_EMAIL) { - if (usingMetrics.includes(EMetrics.FACEBOOK)) window.fbq('track', EGoals.LEAD, options); + if (usingMetrics.includes(EMetrics.YANDEX)) { + if (typeof window.ym !== "function") { + console.error("Yandex.Metric not found") + } else { + window.ym(metricCounterNumber, "reachGoal", goal) + console.log("goalYM: ", goal); + } } - if (usingMetrics.includes(EMetrics.FACEBOOK)) window.fbq('track', goal, options); + if (usingMetrics.includes(EMetrics.KLAVIYO)) { + if (!window.klaviyo) { + console.error("Klaviyo.Metric not found") + } else { + window.klaviyo.push(['track', goal]); + console.log("goalKLAVIYO: ", goal); + } + } + + if (usingMetrics.includes(EMetrics.FACEBOOK)) { + if (typeof window.fbq !== "function") { + console.error("Facebook.Metric not found") + } else { + window.fbq('track', goal === EGoals.ENTERED_EMAIL ? EGoals.LEAD : goal, options) + console.log("goalFB: ", goal); + } + } } type THitOptions = { diff --git a/src/store/index.ts b/src/store/index.ts index 533e19a..ee42a48 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -78,6 +78,7 @@ import palmistry, { actions as palmistryActions, selectPalmistryFingers, selectPalmistryFromRedesign, + selectPalmistryIsShowPaymentModalV1, selectPalmistryLines, selectPalmistryPhoto } from "./palmistry"; @@ -150,6 +151,7 @@ export const selectors = { selectPersonalVideo, selectCurrency, selectPalmistryFromRedesign, + selectPalmistryIsShowPaymentModalV1, ...formSelectors, }; diff --git a/src/store/palmistry.ts b/src/store/palmistry.ts index 2004d58..0e5509b 100644 --- a/src/store/palmistry.ts +++ b/src/store/palmistry.ts @@ -9,13 +9,15 @@ interface IPalmistry { fingers: IPalmistryFingerLocal[]; photo: string; fromRedesign: boolean; + isShowPaymentModalV1: boolean; } const initialState: IPalmistry = { lines: [], fingers: [], photo: "", - fromRedesign: false + fromRedesign: false, + isShowPaymentModalV1: false, }; const palmistrySlice = createSlice({ @@ -25,6 +27,9 @@ const palmistrySlice = createSlice({ update(state, action: PayloadAction>) { return { ...state, ...action.payload }; }, + setIsShowPaymentModalV1(state, action: PayloadAction) { + return { ...state, isShowPaymentModalV1: action.payload }; + } }, extraReducers: (builder) => builder.addCase("reset", () => initialState), }); @@ -46,4 +51,8 @@ export const selectPalmistryFromRedesign = createSelector( (state: { palmistry: IPalmistry }) => state.palmistry.fromRedesign, (palmistry) => palmistry ); +export const selectPalmistryIsShowPaymentModalV1 = createSelector( + (state: { palmistry: IPalmistry }) => state.palmistry.isShowPaymentModalV1, + (palmistry) => palmistry +); export default palmistrySlice.reducer; diff --git a/src/store/personalVideo.ts b/src/store/personalVideo.ts index 0da1402..fbcc627 100644 --- a/src/store/personalVideo.ts +++ b/src/store/personalVideo.ts @@ -6,24 +6,29 @@ interface IPersonalVideo { videoId: string videoUrl: string createdDate: number + isVideoPlaying: boolean } const initialState: IPersonalVideo = { generatingVideo: false, videoId: "", videoUrl: "", - createdDate: 0 + createdDate: 0, + isVideoPlaying: false } const personalVideoSlice = createSlice({ name: 'personalVideo', initialState, reducers: { - updateStatus(state, action: PayloadAction>) { + updateStatus(state, action: PayloadAction>) { return { ...state, ...action.payload, createdDate: new Date().getTime() } }, updateUrl(state, action: PayloadAction) { return { ...state, videoUrl: action.payload } + }, + updateIsVideoPlaying(state, action: PayloadAction) { + return { ...state, isVideoPlaying: action.payload } } }, extraReducers: (builder) => builder.addCase('reset', () => initialState),