Page mentioned in

This commit is contained in:
Daniil Chemerkin 2024-07-12 19:19:16 +00:00
parent af1a0723e6
commit 3f881857b6
21 changed files with 377 additions and 30 deletions

View File

@ -120,6 +120,7 @@
e[i]=e[i]||function(){(e[i].a=e[i].a||[]).push(arguments)}, e[i]=e[i]||function(){(e[i].a=e[i].a||[]).push(arguments)},
me=x.createElement(pe),me.async=1,me.src=r,nt=x.getElementsByTagName(pe)[0],nt.parentNode.insertBefore(me,nt)}) me=x.createElement(pe),me.async=1,me.src=r,nt=x.getElementsByTagName(pe)[0],nt.parentNode.insertBefore(me,nt)})
(window, document, 'script', 'https://abt.s3.yandex.net/expjs/latest/exp.js', 'ymab'); (window, document, 'script', 'https://abt.s3.yandex.net/expjs/latest/exp.js', 'ymab');
ymab('metrika.95799066', 'setConfig', { enableJS: true, enableWatch: true });
ymab('metrika.95799066', 'init'/*, {clientFeatures}, {callback}*/); ymab('metrika.95799066', 'init'/*, {clientFeatures}, {callback}*/);
</script> </script>
<!-- Varioqub experiments --> <!-- Varioqub experiments -->

18
package-lock.json generated
View File

@ -36,7 +36,8 @@
"react-slick": "^0.30.2", "react-slick": "^0.30.2",
"sass": "^1.77.6", "sass": "^1.77.6",
"slick-carousel": "^1.8.1", "slick-carousel": "^1.8.1",
"unique-names-generator": "^4.7.1" "unique-names-generator": "^4.7.1",
"yandex-metrica-ab-react": "^1.6.1"
}, },
"devDependencies": { "devDependencies": {
"@types/core-js": "^2.5.8", "@types/core-js": "^2.5.8",
@ -4964,6 +4965,15 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/yandex-metrica-ab-react": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/yandex-metrica-ab-react/-/yandex-metrica-ab-react-1.6.1.tgz",
"integrity": "sha512-PES0h8lxE/4MgGkGjvaVyyf3axqiJ6/J857jI9N3GCK8+CA0QBLSwtWw4s7DKDUqYgJBPI0sBlhuplCFHWJRgQ==",
"peerDependencies": {
"react": ">=16",
"react-dom": ">16"
}
},
"node_modules/yocto-queue": { "node_modules/yocto-queue": {
"version": "0.1.0", "version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
@ -8336,6 +8346,12 @@
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="
}, },
"yandex-metrica-ab-react": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/yandex-metrica-ab-react/-/yandex-metrica-ab-react-1.6.1.tgz",
"integrity": "sha512-PES0h8lxE/4MgGkGjvaVyyf3axqiJ6/J857jI9N3GCK8+CA0QBLSwtWw4s7DKDUqYgJBPI0sBlhuplCFHWJRgQ==",
"requires": {}
},
"yocto-queue": { "yocto-queue": {
"version": "0.1.0", "version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",

View File

@ -42,7 +42,8 @@
"react-slick": "^0.30.2", "react-slick": "^0.30.2",
"sass": "^1.77.6", "sass": "^1.77.6",
"slick-carousel": "^1.8.1", "slick-carousel": "^1.8.1",
"unique-names-generator": "^4.7.1" "unique-names-generator": "^4.7.1",
"yandex-metrica-ab-react": "^1.6.1"
}, },
"devDependencies": { "devDependencies": {
"@types/core-js": "^2.5.8", "@types/core-js": "^2.5.8",

BIN
public/new-york-times.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@ -169,6 +169,7 @@ function App(): JSX.Element {
} else if (location.pathname.includes("v1/trial-payment")) { } else if (location.pathname.includes("v1/trial-payment")) {
metricService.reachGoal(EGoals.AURA_TRIAL_PAYMENT_PAGE_VISIT, true) metricService.reachGoal(EGoals.AURA_TRIAL_PAYMENT_PAGE_VISIT, true)
} }
// metricService.initMetricAB()
metricService.hit() metricService.hit()
}, [location]); }, [location]);

View File

@ -14,6 +14,7 @@ import { stepsQuestionary } from "../../data/stepsQuestionary";
import Answer from "../../ui/Answer"; import Answer from "../../ui/Answer";
import Stepper from "../Stepper"; import Stepper from "../Stepper";
import { useLottie } from "@/hooks/lottie/useLottie"; import { useLottie } from "@/hooks/lottie/useLottie";
import {useMetricABFlags} from "@/services/metric/metricService.ts";
function QuestionnairePage(): JSX.Element { function QuestionnairePage(): JSX.Element {
const { question, stepId } = useParams(); const { question, stepId } = useParams();
@ -29,10 +30,13 @@ function QuestionnairePage(): JSX.Element {
}); });
const { gender } = useSelector(selectors.selectQuestionnaire); const { gender } = useSelector(selectors.selectQuestionnaire);
const clickAnswerTimeOutRef = useRef<NodeJS.Timeout>(); const clickAnswerTimeOutRef = useRef<NodeJS.Timeout>();
const { flags } = useMetricABFlags();
const aboutUsAnswersKey = flags?.aboutUsAnswers?.[0]
useLottie({ useLottie({
preloadKey: currentQuestion?.lottie?.preloadKey, preloadKey: currentQuestion?.lottie?.preloadKey,
}); });
useEffect(() => { useEffect(() => {
const currentStepIndex = steps.findIndex((item) => item.id === stepId); const currentStepIndex = steps.findIndex((item) => item.id === stepId);
if (currentStepIndex === -1) return navigate(routes.client.notFound()); if (currentStepIndex === -1) return navigate(routes.client.notFound());
@ -83,7 +87,7 @@ function QuestionnairePage(): JSX.Element {
currentStepIndex >= steps.length - 1 && currentStepIndex >= steps.length - 1 &&
questionIndex >= questionsLength - 1 questionIndex >= questionsLength - 1
) { ) {
return navigate(routes.client.aboutUsV1()); return navigate(routes.client.aboutUsV1(aboutUsAnswersKey));
} }
if (questionIndex < questionsLength - 1) { if (questionIndex < questionsLength - 1) {

View File

@ -3,7 +3,7 @@ import styles from "./styles.module.css";
import Title from "@/components/Title"; import Title from "@/components/Title";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { actions, selectors } from "@/store"; import { actions, selectors } from "@/store";
import { useNavigate } from "react-router-dom"; import {useNavigate, useSearchParams} from "react-router-dom";
import routes from "@/routes"; import routes from "@/routes";
import Header from "../../components/Header"; import Header from "../../components/Header";
import Answer from "../../ui/Answer"; import Answer from "../../ui/Answer";
@ -15,6 +15,8 @@ function AboutUsPage() {
const { gender } = useSelector(selectors.selectQuestionnaire); const { gender } = useSelector(selectors.selectQuestionnaire);
const [selectedAnswer, setSelectedAnswer] = useState<IAnswer | null>(null); const [selectedAnswer, setSelectedAnswer] = useState<IAnswer | null>(null);
const clickAnswerTimeOutRef = useRef<NodeJS.Timeout>(); const clickAnswerTimeOutRef = useRef<NodeJS.Timeout>();
const [searchParams] = useSearchParams()
const aboutUsAnswersKey = searchParams.get('key') ?? "aboutUsAnswersNormal"
const handleClick = async (answer: IAnswer) => { const handleClick = async (answer: IAnswer) => {
setSelectedAnswer(answer); setSelectedAnswer(answer);
@ -43,7 +45,7 @@ function AboutUsPage() {
</Title> </Title>
<div className={styles["answers-container"]}> <div className={styles["answers-container"]}>
{aboutUsAnswers.map((answer, index) => ( {aboutUsAnswers[aboutUsAnswersKey].map((answer, index) => (
<Answer <Answer
classNameContainer={`${styles["answer-container"]} ${ classNameContainer={`${styles["answer-container"]} ${
selectedAnswer?.id === answer.id ? styles["answer-active"] : "" selectedAnswer?.id === answer.id ? styles["answer-active"] : ""

View File

@ -11,23 +11,27 @@ import Header from "../../components/Header";
import BackgroundTopBlob from "../../ui/BackgroundTopBlob"; import BackgroundTopBlob from "../../ui/BackgroundTopBlob";
import { DotLottieReact } from "@lottiefiles/dotlottie-react"; import { DotLottieReact } from "@lottiefiles/dotlottie-react";
import { ELottieKeys, useLottie } from "@/hooks/lottie/useLottie"; import { ELottieKeys, useLottie } from "@/hooks/lottie/useLottie";
import {useMetricABFlags} from "@/services/metric/metricService.ts";
function BothPage() { function BothPage() {
const navigate = useNavigate(); const navigate = useNavigate();
const birthdate = useSelector(selectors.selectBirthdate); const birthdate = useSelector(selectors.selectBirthdate);
const zodiacSign = getZodiacSignByDate(birthdate); const zodiacSign = getZodiacSignByDate(birthdate);
const { width: pageWidth, elementRef: pageRef } = useDynamicSize({}); const { width: pageWidth, elementRef: pageRef } = useDynamicSize({});
const { flags } = useMetricABFlags();
const aboutUsAnswersKey = flags?.aboutUsAnswers?.[0]
const { animationData } = useLottie({ const { animationData } = useLottie({
loadKey: ELottieKeys.scalesNeutral, loadKey: ELottieKeys.scalesNeutral,
}); });
const handleBack = () => { const handleBack = () => {
navigate(-1); navigate(-1);
}; };
const handleNext = () => { const handleNext = () => {
navigate(routes.client.aboutUsV1()); navigate(routes.client.aboutUsV1(aboutUsAnswersKey));
}; };
return ( return (

View File

@ -14,6 +14,7 @@ import { genders } from "../../data/genders";
import PrivacyPolicy from "../../components/PrivacyPolicy"; import PrivacyPolicy from "../../components/PrivacyPolicy";
import Toast from "../../components/Toast"; import Toast from "../../components/Toast";
import { DotLottieReact } from "@lottiefiles/dotlottie-react"; import { DotLottieReact } from "@lottiefiles/dotlottie-react";
import { useMetricABFlags } from "@/services/metric/metricService";
interface IGenderPageProps { interface IGenderPageProps {
productKey?: EProductKeys; productKey?: EProductKeys;
@ -29,12 +30,18 @@ function GenderPage({ productKey }: IGenderPageProps): JSX.Element {
const { checked: privacyPolicyChecked } = useSelector( const { checked: privacyPolicyChecked } = useSelector(
selectors.selectPrivacyPolicy selectors.selectPrivacyPolicy
); );
const { flags } = useMetricABFlags();
const isNextPageMentioned = flags?.isNextPageMentioned?.[0]
useEffect(() => { useEffect(() => {
const feature = location.pathname.replace("/v1/gender/", ""); const feature = location.pathname.replace("/v1/gender/", "");
const isShowTryApp = targetId === "i"; const isShowTryApp = targetId === "i";
dispatch(actions.userConfig.addIsShowTryApp(isShowTryApp)); dispatch(actions.userConfig.addIsShowTryApp(isShowTryApp));
dispatch(actions.userConfig.setFeature(feature.includes("/v1/gender") ? "" : feature)); dispatch(
actions.userConfig.setFeature(
feature.includes("/v1/gender") ? "" : feature
)
);
}, [dispatch, location.pathname, targetId]); }, [dispatch, location.pathname, targetId]);
useEffect(() => { useEffect(() => {
@ -54,7 +61,10 @@ function GenderPage({ productKey }: IGenderPageProps): JSX.Element {
if (productKey === EProductKeys["chat.aura"]) { if (productKey === EProductKeys["chat.aura"]) {
return navigate(routes.client.advisorChatBirthdate()); return navigate(routes.client.advisorChatBirthdate());
} }
navigate(`/v1/questionnaire/profile/flowChoice`); if (isNextPageMentioned === "true") {
return navigate(routes.client.mentionedInV1());
}
return navigate(`/v1/questionnaire/profile/flowChoice`);
}; };
const selectGender = async (gender: Gender) => { const selectGender = async (gender: Gender) => {

View File

@ -0,0 +1,100 @@
import Title from "@/components/Title";
import styles from "./styles.module.css";
import { useNavigate } from "react-router-dom";
import { useSelector } from "react-redux";
import { selectors } from "@/store";
import Header from "../../components/Header";
import { useDynamicSize } from "@/hooks/useDynamicSize";
import BackgroundTopBlob from "../../ui/BackgroundTopBlob";
import QuestionnaireGreenButton from "../../ui/GreenButton";
import { useTranslation } from "react-i18next";
function MentionedInPage() {
const navigate = useNavigate();
const { t } = useTranslation();
const { width: pageWidth, elementRef } = useDynamicSize({
defaultWidth: 393,
});
const { gender } = useSelector(selectors.selectQuestionnaire);
const handleNext = () => {
return navigate(`/v1/questionnaire/profile/flowChoice`);
};
const getBackgroundColor = () => {
return gender === "male" ? "#C1E5FF" : "#f7ebff";
};
return (
<section
className={`${styles.page} page`}
style={{
backgroundColor: getBackgroundColor(),
}}
ref={elementRef}
>
<BackgroundTopBlob
className={styles["background-top-blob"]}
width={pageWidth}
height={145}
cLeftStartX={65}
cLeft={`C 32 108 11 95 0 87`}
cRight={`C ${pageWidth - 23} 123 ${pageWidth - 36} 115 ${
pageWidth - 69
} 112`}
/>
<Header className={styles.header} />
<Title variant="h1" className={styles.title}>
42+ million people
</Title>
<Title variant="h2" className={styles["sub-title"]}>
already use AURA
</Title>
<div className={styles["quote-container"]}>
<svg
className={styles.quote}
role="img"
width="17"
height="17"
viewBox="0 0 17 17"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<title>quotes</title>
<path
d="M3.1665 7.31768C3.1665 6.30806 3.1665 5.91213 3.39121 5.57558C3.48849 5.42988 3.61349 5.30478 3.75908 5.20742C4.09538 4.98254 4.56353 4.98254 5.49984 4.98254C6.43614 4.98254 6.9043 4.98254 7.24061 5.20742C7.38621 5.30478 7.51121 5.42988 7.60848 5.57558C7.83314 5.91213 7.83314 6.38065 7.83314 7.31768L7.83321 9.65281C7.83314 10.9663 7.55194 11.6335 6.99984 12.2381C6.44775 12.8428 5.37484 13.6492 3.92749 13.6492C3.05192 13.6492 3.06234 12.4362 3.73893 12.3283C6.26595 11.925 6.99984 9.25334 5.49984 9.32968C5.35762 9.33688 5.18971 9.38508 5.00906 9.43694C4.60792 9.55214 4.14397 9.68534 3.75908 9.42794C3.61349 9.33061 3.48849 9.20548 3.39121 9.05981C3.1665 8.72321 3.1665 8.25474 3.1665 7.31768Z"
fill="currentColor"
/>
<path
d="M9.1665 7.31768C9.1665 6.30806 9.1665 5.91213 9.39124 5.57558C9.4885 5.42988 9.6135 5.30478 9.7591 5.20742C10.0954 4.98254 10.5636 4.98254 11.4998 4.98254C12.4362 4.98254 12.9043 4.98254 13.2406 5.20742C13.3862 5.30478 13.5112 5.42988 13.6085 5.57558C13.8332 5.91213 13.8332 6.38065 13.8332 7.31768L13.8332 9.65281C13.8332 10.9663 13.552 11.6335 12.9998 12.2381C12.4478 12.8428 11.3748 13.6492 9.9275 13.6492C9.05197 13.6492 9.06237 12.4362 9.73897 12.3283C12.266 11.925 12.9998 9.25334 11.4998 9.32968C11.3576 9.33688 11.1898 9.38508 11.0091 9.43694C10.608 9.55214 10.144 9.68534 9.7591 9.42794C9.6135 9.33061 9.4885 9.20548 9.39124 9.05981C9.1665 8.72321 9.1665 8.25468 9.1665 7.31768Z"
fill="currentColor"
/>
</svg>
<p>
AURA aims to illuminate interpersonal connections using astrological
signs
</p>
<img className={styles["quote-img"]} src="/new-york-times.png" />
</div>
<Title variant="h3" className={styles["text-h3"]}>
MENTIONED IN
</Title>
<img className={styles.full} src="/partnersWithoutNewYorkTime.png" />
<div
className={styles["buttons-container"]}
style={{ backgroundColor: getBackgroundColor() }}
>
<QuestionnaireGreenButton className={styles.full} onClick={handleNext}>
{t("next")}
</QuestionnaireGreenButton>
<p className={styles.address}>1123 Rimer Dr Moraga, California 94556</p>
</div>
</section>
);
}
export default MentionedInPage;

View File

@ -0,0 +1,100 @@
.page {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
min-height: 100dvh;
max-width: 460px;
padding: 20px 24px;
color: #2c2c2c;
overflow: initial;
}
.background-top-blob {
position: absolute;
top: -40px;
left: 0;
}
.header {
z-index: 1;
}
.title {
font-size: 28px;
font-weight: 600;
margin: 0;
margin-top: 40px;
z-index: 1;
line-height: 125%;
color: #0cc3ac;
}
.sub-title {
font-size: 16px;
font-weight: 400;
line-height: 24px;
color: rgb(32, 31, 31);
}
.quote-container {
display: flex;
flex-direction: column;
-webkit-box-align: center;
align-items: center;
background: rgb(251, 251, 255);
border-radius: 12px;
padding: 24px 21px 28px;
width: 100%;
margin-bottom: 24px;
}
.quote {
color: #0cc3ac;
}
.quote-container p {
width: 100%;
margin-top: 8px;
margin-bottom: 28px;
font-size: 16px;
font-weight: 600;
line-height: 24px;
text-align: center;
color: rgb(15, 15, 15);
}
.quote-img {
max-width: 134px;
width: 100%;
}
.text-h3 {
font-size: 12px;
font-weight: 600;
line-height: 18px;
color: rgb(32, 31, 31);
margin-bottom: 16px;
}
.full {
width: 100%;
}
.buttons-container {
position: sticky;
bottom: 0;
margin-top: 10px;
padding-top: 10px;
width: 100%;
}
.address {
margin-top: 12px;
margin-bottom: 8px;
text-align: center;
color: gray;
font-size: 12px;
margin-bottom: 16px;
text-transform: uppercase;
}

View File

@ -11,13 +11,15 @@ import BackgroundTopBlob from "../../ui/BackgroundTopBlob";
import Header from "../../components/Header"; import Header from "../../components/Header";
import { ELottieKeys, useLottie } from "@/hooks/lottie/useLottie"; import { ELottieKeys, useLottie } from "@/hooks/lottie/useLottie";
import { DotLottieReact } from "@lottiefiles/dotlottie-react"; import { DotLottieReact } from "@lottiefiles/dotlottie-react";
import {useMetricABFlags} from "@/services/metric/metricService.ts";
function WithHeadPage() { function WithHeadPage() {
const navigate = useNavigate(); const navigate = useNavigate();
const birthdate = useSelector(selectors.selectBirthdate); const birthdate = useSelector(selectors.selectBirthdate);
const zodiacSign = getZodiacSignByDate(birthdate); const zodiacSign = getZodiacSignByDate(birthdate);
const { width: pageWidth, elementRef: pageRef } = useDynamicSize({}); const { width: pageWidth, elementRef: pageRef } = useDynamicSize({});
const { flags } = useMetricABFlags();
const aboutUsAnswersKey = flags?.aboutUsAnswers?.[0]
const { animationData } = useLottie({ const { animationData } = useLottie({
loadKey: ELottieKeys.scalesHead, loadKey: ELottieKeys.scalesHead,
}); });
@ -27,7 +29,7 @@ function WithHeadPage() {
}; };
const handleNext = () => { const handleNext = () => {
navigate(routes.client.aboutUsV1()); navigate(routes.client.aboutUsV1(aboutUsAnswersKey));
}; };
return ( return (

View File

@ -11,13 +11,15 @@ import BackgroundTopBlob from "../../ui/BackgroundTopBlob";
import Header from "../../components/Header"; import Header from "../../components/Header";
import { ELottieKeys, useLottie } from "@/hooks/lottie/useLottie"; import { ELottieKeys, useLottie } from "@/hooks/lottie/useLottie";
import { DotLottieReact } from "@lottiefiles/dotlottie-react"; import { DotLottieReact } from "@lottiefiles/dotlottie-react";
import {useMetricABFlags} from "@/services/metric/metricService.ts";
function WithHeartPage() { function WithHeartPage() {
const navigate = useNavigate(); const navigate = useNavigate();
const birthdate = useSelector(selectors.selectBirthdate); const birthdate = useSelector(selectors.selectBirthdate);
const zodiacSign = getZodiacSignByDate(birthdate); const zodiacSign = getZodiacSignByDate(birthdate);
const { width: pageWidth, elementRef: pageRef } = useDynamicSize({}); const { width: pageWidth, elementRef: pageRef } = useDynamicSize({});
const { flags } = useMetricABFlags();
const aboutUsAnswersKey = flags?.aboutUsAnswers?.[0]
const { animationData } = useLottie({ const { animationData } = useLottie({
loadKey: ELottieKeys.scalesHeart, loadKey: ELottieKeys.scalesHeart,
}); });
@ -27,7 +29,7 @@ function WithHeartPage() {
}; };
const handleNext = () => { const handleNext = () => {
navigate(routes.client.aboutUsV1()); navigate(routes.client.aboutUsV1(aboutUsAnswersKey));
}; };
return ( return (

View File

@ -27,7 +27,7 @@ function AboutUsPage() {
</Title> </Title>
<div className={styles["answers-container"]}> <div className={styles["answers-container"]}>
{aboutUsAnswers.map((answer, index) => ( {aboutUsAnswers['aboutUsAnswersNormal'].map((answer, index) => (
<Answer <Answer
classNameContainer={styles["answer-container"]} classNameContainer={styles["answer-container"]}
key={index} key={index}

View File

@ -80,7 +80,57 @@ export interface IAnswer {
navigateToUrl?: string; navigateToUrl?: string;
} }
export const aboutUsAnswers: IAnswer[] = [ export const aboutUsAnswersA: IAnswer[] = [
{
id: "forbes",
answer: "Forbes",
icon: "",
},
{
id: "instagram",
answer: "Instagram",
icon: "",
},
{
id: "celebrity",
answer: "Celebrity",
icon: "",
},
{
id: "friends",
answer: "Friends",
icon: "",
},
{
id: "other",
answer: "Other",
icon: "",
}
]
export const aboutUsAnswersB: IAnswer[] = [
{
id: "forbes",
answer: "Forbes",
icon: "",
},
{
id: "instagram",
answer: "Instagram",
icon: "",
},
{
id: "celebrity",
answer: "Celebrity",
icon: "",
},
{
id: "other",
answer: "Other",
icon: "",
}
]
export const aboutUsAnswersNormal: IAnswer[] = [
{ {
id: "poster", id: "poster",
answer: "Poster or Billboard", answer: "Poster or Billboard",
@ -158,6 +208,14 @@ export const aboutUsAnswers: IAnswer[] = [
}, },
]; ];
export const aboutUsAnswers: {
[key: string]: IAnswer[]
} = {
'aboutUsAnswersA': aboutUsAnswersA,
'aboutUsAnswersB': aboutUsAnswersB,
'aboutUsAnswersNormal': aboutUsAnswersNormal
}
const currentlyAffectingAnswers: IAnswer[] = [ const currentlyAffectingAnswers: IAnswer[] = [
{ {
id: "infidelity", id: "infidelity",

View File

@ -53,6 +53,7 @@ const init = async () => {
}; };
metricService.initMetric(); metricService.initMetric();
// metricService.initMetricAB();
if (isProduction) { if (isProduction) {
smartLook(); smartLook();

View File

@ -32,6 +32,7 @@ import TrialChoicePage from "@/components/pages/ABDesign/v1/pages/TrialChoice";
import TrialPaymentPage from "@/components/pages/ABDesign/v1/pages/TrialPayment"; import TrialPaymentPage from "@/components/pages/ABDesign/v1/pages/TrialPayment";
import TrialPaymentWithDiscount from "@/components/pages/ABDesign/v1/pages/TrialPaymentWithDiscount"; import TrialPaymentWithDiscount from "@/components/pages/ABDesign/v1/pages/TrialPaymentWithDiscount";
import AdditionalDiscount from "@/components/pages/ABDesign/v1/pages/AdditionalDiscount"; import AdditionalDiscount from "@/components/pages/ABDesign/v1/pages/AdditionalDiscount";
import MentionedInPage from "@/components/pages/ABDesign/v1/pages/MentionedIn";
function ABDesignV1Routes() { function ABDesignV1Routes() {
return ( return (
@ -144,6 +145,10 @@ function ABDesignV1Routes() {
path={routes.client.additionalDiscountV1()} path={routes.client.additionalDiscountV1()}
element={<AdditionalDiscount />} element={<AdditionalDiscount />}
/> />
<Route
path={routes.client.mentionedInV1()}
element={<MentionedInPage />}
/>
</Route> </Route>
</Routes> </Routes>
); );

View File

@ -1,13 +1,13 @@
import { EPlacementKeys } from "./api/resources/Paywall"; import { EPlacementKeys } from "./api/resources/Paywall";
import type { UserStatus } from "./types"; import type { UserStatus } from "./types";
const environments = import.meta.env const environments = import.meta.env;
const host = ""; const host = "";
export const apiHost = environments.AURA_API_HOST; export const apiHost = environments.AURA_API_HOST;
const dApiHost = environments.AURA_DAPI_HOST const dApiHost = environments.AURA_DAPI_HOST;
const dApiPrefix = environments.AURA_DAPI_PREFIX const dApiPrefix = environments.AURA_DAPI_PREFIX;
const siteHost = environments.AURA_SITE_HOST const siteHost = environments.AURA_SITE_HOST;
const prefix = environments.AURA_PREFIX; const prefix = environments.AURA_PREFIX;
const openAIHost = environments.AURA_OPEN_AI_HOST; const openAIHost = environments.AURA_OPEN_AI_HOST;
const openAiPrefix = environments.AURA_OPEN_AI_PREFIX; const openAiPrefix = environments.AURA_OPEN_AI_PREFIX;
@ -155,15 +155,23 @@ const routes = {
genderV1: () => [host, "v1", "gender"].join("/"), genderV1: () => [host, "v1", "gender"].join("/"),
questionnaireV1: () => [host, "v1", "questionnaire"].join("/"), questionnaireV1: () => [host, "v1", "questionnaire"].join("/"),
goalSetupV1: () => [host, "v1", "goal-setup"].join("/"), goalSetupV1: () => [host, "v1", "goal-setup"].join("/"),
aboutUsV1: () => [host, "v1", "about-us"].join("/"), aboutUsV1: (key?: string) => {
if (key === undefined) {
return [host, "v1", "about-us"].join("/")
} else {
return [host, "v1", "about-us"].join("/") + `?key=${key}`
}
},
hyperPersonalizedAstrologyV1: () => hyperPersonalizedAstrologyV1: () =>
[host, "v1", "hyper-personalized-astrology"].join("/"), [host, "v1", "hyper-personalized-astrology"].join("/"),
singleZodiacInfoV1: () => [host, "v1", "single-zodiac-info"].join("/"), singleZodiacInfoV1: () => [host, "v1", "single-zodiac-info"].join("/"),
relationshipZodiacInfoV1: () => [host, "v1", "relationship-zodiac-info"].join("/"), relationshipZodiacInfoV1: () =>
[host, "v1", "relationship-zodiac-info"].join("/"),
noTimeV1: () => [host, "v1", "no-time"].join("/"), noTimeV1: () => [host, "v1", "no-time"].join("/"),
relationshipAlmostThereV1: () => relationshipAlmostThereV1: () =>
[host, "v1", "relationship-almost-there"].join("/"), [host, "v1", "relationship-almost-there"].join("/"),
loadingInRelationshipV1: () => [host, "v1", "loading-in-relationship"].join("/"), loadingInRelationshipV1: () =>
[host, "v1", "loading-in-relationship"].join("/"),
problemsV1: () => [host, "v1", "problems"].join("/"), problemsV1: () => [host, "v1", "problems"].join("/"),
worksRouterV1: () => [host, "v1", "works-router"].join("/"), worksRouterV1: () => [host, "v1", "works-router"].join("/"),
worksForUsV1: () => [host, "v1", "works-for-us"].join("/"), worksForUsV1: () => [host, "v1", "works-for-us"].join("/"),
@ -173,7 +181,8 @@ const routes = {
almostThereV1: () => [host, "v1", "almost-there"].join("/"), almostThereV1: () => [host, "v1", "almost-there"].join("/"),
partnerRightPlaceV1: () => [host, "v1", "partner-right-place"].join("/"), partnerRightPlaceV1: () => [host, "v1", "partner-right-place"].join("/"),
partnerThingV1: () => [host, "v1", "partner-thing"].join("/"), partnerThingV1: () => [host, "v1", "partner-thing"].join("/"),
partnerTotallyNormalV1: () => [host, "v1", "partner-totally-normal"].join("/"), partnerTotallyNormalV1: () =>
[host, "v1", "partner-totally-normal"].join("/"),
withHeartV1: () => [host, "v1", "with-heart"].join("/"), withHeartV1: () => [host, "v1", "with-heart"].join("/"),
withHeadV1: () => [host, "v1", "with-head"].join("/"), withHeadV1: () => [host, "v1", "with-head"].join("/"),
bothV1: () => [host, "v1", "both"].join("/"), bothV1: () => [host, "v1", "both"].join("/"),
@ -187,6 +196,7 @@ const routes = {
trialPaymentWithDiscountV1: () => trialPaymentWithDiscountV1: () =>
[host, "v1", "trial-payment-with-discount"].join("/"), [host, "v1", "trial-payment-with-discount"].join("/"),
additionalDiscountV1: () => [host, "v1", "additional-discount"].join("/"), additionalDiscountV1: () => [host, "v1", "additional-discount"].join("/"),
mentionedInV1: () => [host, "v1", "mentionedIn"].join("/"),
loadingPage: () => [host, "loading-page"].join("/"), loadingPage: () => [host, "loading-page"].join("/"),
notFound: () => [host, "404"].join("/"), notFound: () => [host, "404"].join("/"),
@ -271,17 +281,14 @@ const routes = {
[dApiHost, dApiPrefix, "placement", placementKey, "paywall"].join("/"), [dApiHost, dApiPrefix, "placement", placementKey, "paywall"].join("/"),
// Payment // Payment
makePayment: () => makePayment: () => [dApiHost, dApiPrefix, "payment", "checkout"].join("/"),
[dApiHost, dApiPrefix, "payment", "checkout"].join("/"),
// User videos // User videos
getUserVideos: () => getUserVideos: () => [dApiHost, "users", "videos", "combined"].join("/"),
[dApiHost, "users", "videos", "combined"].join("/"),
// User videos // User videos
getUserPDFCompatibility: () => getUserPDFCompatibility: () =>
[dApiHost, "users", "pdf", "compatibility"].join("/"), [dApiHost, "users", "pdf", "compatibility"].join("/"),
}, },
openAi: { openAi: {
createThread: () => [openAIHost, openAiPrefix, "threads"].join("/"), createThread: () => [openAIHost, openAiPrefix, "threads"].join("/"),
@ -517,4 +524,4 @@ export const getRouteBy = (status: UserStatus): string => {
} }
}; };
export default routes; export default routes;

View File

@ -1,3 +1,5 @@
import { useExperiments } from "yandex-metrica-ab-react";
export enum EGoals { export enum EGoals {
ENTERED_EMAIL = "EnteredEmail", ENTERED_EMAIL = "EnteredEmail",
PAYMENT_SUCCESS = "PaymentSuccess", PAYMENT_SUCCESS = "PaymentSuccess",
@ -15,6 +17,11 @@ export enum EGoals {
AURA_TRIAL_PAYMENT_PAGE_VISIT = "AuraTrialPaymentPageVisit" AURA_TRIAL_PAYMENT_PAGE_VISIT = "AuraTrialPaymentPageVisit"
} }
export enum EFlags {
isNextPageMentioned = 'Go to page mentionedIn',
aboutUsAnswers = 'Key for aboutUsAnswers'
}
interface IUserParams { interface IUserParams {
UserID: number | string; UserID: number | string;
genderFrom: string; genderFrom: string;
@ -33,6 +40,14 @@ const checkIsAvailableYandexMetric = () => {
return true return true
} }
const checkIsAvailableYandexMetricAB = () => {
if (typeof window.ymab !== "function") {
console.error("Yandex.Metric not found")
return false
}
return true
}
const setUserID = (userId: string) => { const setUserID = (userId: string) => {
if (!checkIsAvailableYandexMetric()) return; if (!checkIsAvailableYandexMetric()) return;
window.ym(metricCounterNumber, "setUserID", userId) window.ym(metricCounterNumber, "setUserID", userId)
@ -94,4 +109,21 @@ const initMetric = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
} }
export default { setUserID, userParams, reachGoal, hit, initMetric } const initMetricAB = () => {
if (!checkIsAvailableYandexMetricAB()) return;
window.ymab(`metrika.${metricCounterNumber}`, 'setConfig', { enableJS: true, enableWatch: true });
window.ymab(`metrika.${metricCounterNumber}`, 'init'/*, {clientFeatures}, {callback}*/);
console.log("Metric initialized");
// eslint-disable-next-line react-hooks/exhaustive-deps
}
export const useMetricABFlags = () => {
return useExperiments<typeof EFlags>({
clientId: `metrika.${metricCounterNumber}`
})
}
export default { setUserID, userParams, reachGoal, hit, initMetric, initMetricAB }

View File

@ -27,6 +27,7 @@ declare global {
interface Window { interface Window {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
ym: any; ym: any;
ymab: any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
klaviyo: any; klaviyo: any;
} }