Merge branch 'develop' into 'main'

AW-429-comp-v1-ios-ab

See merge request witapp/aura-webapp!752
This commit is contained in:
Daniil Chemerkin 2025-04-22 23:30:21 +00:00
commit 37b12a69af
20 changed files with 489 additions and 431 deletions

File diff suppressed because one or more lines are too long

View File

@ -13,11 +13,16 @@ import Loader, { LoaderColor } from "@/components/Loader";
import { images } from "../../data"; import { images } from "../../data";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { selectors } from "@/store"; import { selectors } from "@/store";
import {EUnleashFlags, useUnleash} from "@/hooks/ab/unleash/useUnleash.ts";
function ScanInstruction() { function ScanInstruction() {
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2); const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
const navigate = useNavigate(); const navigate = useNavigate();
const { isReady, variant: v2CompatibilityScanInstructionImage } = useUnleash({
flag: EUnleashFlags.v2CompatibilityScanInstructionImage
});
const gender = useSelector(selectors.selectQuestionnaire)?.gender || "female"; const gender = useSelector(selectors.selectQuestionnaire)?.gender || "female";
usePreloadImages([ usePreloadImages([
@ -45,12 +50,18 @@ function ScanInstruction() {
navigate(routes.client.compatibilityV2Camera()); navigate(routes.client.compatibilityV2Camera());
}; };
if (!isReady) {return <Loader color={LoaderColor.Black} />;}
const imageVariant = v2CompatibilityScanInstructionImage === 'v1' ? 'v1' : 'v0';
return ( return (
<div className={styles.page}> <div className={styles.page}>
<Title variant="h2" className={styles.title}> <Title variant="h2" className={styles.title}>
{translate("/scan-instruction.title")} {translate("/scan-instruction.title")}
</Title> </Title>
<ScanInstructionSVG /> <ScanInstructionSVG
variant={imageVariant}
/>
<Button className={styles.button} onClick={handleClick}> <Button className={styles.button} onClick={handleClick}>
{translate("/scan-instruction.button")} {translate("/scan-instruction.button")}
</Button> </Button>

View File

@ -17,6 +17,8 @@ import { ESourceAuthorization } from "@/api/resources/User";
import { getRandomArbitrary } from "@/services/random-value"; import { getRandomArbitrary } from "@/services/random-value";
import { usePreloadImages } from "@/hooks/preload/images"; import { usePreloadImages } from "@/hooks/preload/images";
import metricService, { EGoals, EMetrics } from "@/services/metric/metricService"; import metricService, { EGoals, EMetrics } from "@/services/metric/metricService";
import {EUnleashFlags, useUnleash} from "@/hooks/ab/unleash/useUnleash.ts";
import Loader, {LoaderColor} from "@/components/Loader";
const drawElementChangeDelay = 1500; const drawElementChangeDelay = 1500;
const startDelay = 500; const startDelay = 500;
@ -39,6 +41,10 @@ function ScannedPhoto() {
const fingers = useSelector(selectors.selectCompatibilityV2Fingers); const fingers = useSelector(selectors.selectCompatibilityV2Fingers);
const lines = useSelector(selectors.selectCompatibilityV2Lines); const lines = useSelector(selectors.selectCompatibilityV2Lines);
const { isReady, variant: v2CompatibilityScanResultNumbers } = useUnleash({
flag: EUnleashFlags.v2CompatibilityScanResultNumbers
});
const changeTitleTimeOut = useRef<NodeJS.Timeout>(); const changeTitleTimeOut = useRef<NodeJS.Timeout>();
const [currentElementIndex, setCurrentElementIndex] = useState(0); const [currentElementIndex, setCurrentElementIndex] = useState(0);
@ -271,6 +277,10 @@ function ScannedPhoto() {
return Math.floor(progress / 100); return Math.floor(progress / 100);
}; };
if (!isReady) return <Loader color={LoaderColor.Black} />;
const isShowLineScale = isReady && v2CompatibilityScanResultNumbers === "on";
return ( return (
<section className={`${styles.page} palmistry-container_type_scan-photo`}> <section className={`${styles.page} palmistry-container_type_scan-photo`}>
<Title variant="h2" className={styles.title}> <Title variant="h2" className={styles.title}>
@ -287,7 +297,7 @@ function ScannedPhoto() {
drawElements={drawElements} drawElements={drawElements}
className={classNameScannedPhoto} className={classNameScannedPhoto}
isDecorationShown={isDecorationShown} isDecorationShown={isDecorationShown}
isShowLineScale={true} isShowLineScale={isShowLineScale}
/> />
<h2 <h2
className={`palmistry-container__waiting-title ${styles.waitingTitle} ${!isDecorationShown ? styles.hidden : ""}`} className={`palmistry-container__waiting-title ${styles.waitingTitle} ${!isDecorationShown ? styles.hidden : ""}`}

View File

@ -1,80 +0,0 @@
export const getLongText = (locale: string) => {
if (locale === "es") {
return (
<>
AURA es la única aplicación precisa con un análisis fiable de la línea
del destino, verificado por profesionales y garantizado para
proporcionar predicciones precisas.
<br />
<br />
AURA ya ha ayudado a millones de personas a encontrar la felicidad y
descubrir toda la verdad sobre sus relaciones.
<br />
<br />
Tu análisis del destino, que cambiará tu vida por completo, ¡está casi
listo! Antes de proporcionártelo, nos gustaría ofrecerte la oportunidad
de elegir la cantidad que consideres razonable para probar AURA durante
7 días y que creas justa para los cambios que te sucederán:
<br />
<br />
Descubrirás todos los secretos más íntimos que las estrellas tienen
preparados para ti y resolverás problemas de relación en solo un mes;
<br />
<br />
Pondrás fin, de una vez por todas, a asuntos pendientes y olvidarás
los problemas que te han estado atormentando durante años (si no
décadas);
<br />
<br />
Ahorrarás cientos de dólares en predicciones astrológicas falsas y
adivinos no profesionales;
<br />
<br />
Recibirás no solo un análisis personal, sino también horóscopos
diarios personalizados, aprenderás quién y cómo está drenando tu energía
y obtendrás otras lecturas personalizadas.
<br />
<br />
El período de prueba de 7 días nos cuesta $13.76, pero por favor elige
la cantidad que más te convenga:
</>
);
}
return (
<>
AURA is the only accurate app with reliable fate line analysis, verified
by professionals and guaranteed to provide precise predictions.
<br />
<br />
AURA has already helped millions of people find happiness and discover the
whole truth about their relationships.
<br />
<br />
Your fate analysis, which will completely change your life, is almost
ready! Before we provide it to you, we would like to offer you the
opportunity to choose the amount you consider reasonable to try AURA for 7
days and which you think is fair for the changes that will happen to you:
<br />
<br />
You will discover all the most intimate secrets that the stars have
prepared for you and solve relationship issues within just one month;
<br />
<br />
You will once and for all put the finishing touches on unresolved issues
and forget about problems that have been haunting you for years (if not
decades);
<br />
<br />
You will save hundreds of dollars on fake and unprofessional astrological
predictions and fortune tellers;
<br />
<br />
You will receive not only a personal analysis but also personalized daily
horoscopes, learn who and how is draining your energy, and get other
personalized readings.
<br />
<br />A 7-day trial period costs us $13.76, but please choose the amount
that suits you best:
</>
);
};

View File

@ -6,32 +6,30 @@ import { actions, selectors } from "@/store";
import PriceList from "@/components/pages/ABDesign/v1/components/PriceList"; import PriceList from "@/components/pages/ABDesign/v1/components/PriceList";
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 { import {addCurrency, ELocalesPlacement} from "@/locales";
ELocalesPlacement, import {useEffect, useMemo, useState} from "react";
getDefaultLocaleByLanguage,
language,
} from "@/locales";
import { useEffect, useState } from "react";
import Button from "../../components/Button"; import Button from "../../components/Button";
import routes from "@/routes"; import routes from "@/routes";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import Loader from "@/components/Loader"; import Loader from "@/components/Loader";
import { useTranslations } from "@/hooks/translations"; import { useTranslations } from "@/hooks/translations";
// import { useMetricABFlags } from "@/services/metric/metricService"; // import { useMetricABFlags } from "@/services/metric/metricService";
import { getLongText } from "./abText";
import metricService, { EGoals, EMetrics, useMetricABFlags } from "@/services/metric/metricService"; import metricService, { EGoals, EMetrics, useMetricABFlags } from "@/services/metric/metricService";
import TrialChoiceV1 from "./v1"; import TrialChoiceV1 from "./v1";
import { usePreloadImages } from "@/hooks/preload/images"; import { usePreloadImages } from "@/hooks/preload/images";
import { getZodiacSignByDate } from "@/services/zodiac-sign"; import { getZodiacSignByDate } from "@/services/zodiac-sign";
import { EUnleashFlags, useUnleash } from "@/hooks/ab/unleash/useUnleash";
import {getFormattedPrice} from "@/utils/price.utils.tsx";
function TrialChoice() { function TrialChoice() {
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2); const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
const navigate = useNavigate(); const navigate = useNavigate();
const dispatch = useDispatch(); const dispatch = useDispatch();
const { products, isLoading, currency, getText } = usePaywall({ const { products, isLoading, currency } = usePaywall({
placementKey: EPlacementKeys["aura.placement.compatibility.v2"], placementKey: EPlacementKeys["aura.placement.compatibility.v2"],
localesPlacement: ELocalesPlacement.CompatibilityV2, localesPlacement: ELocalesPlacement.CompatibilityV2,
}); });
const { gender, partnerGender, birthdate, partnerBirthdate } = useSelector(selectors.selectQuestionnaire) const { gender, partnerGender, birthdate, partnerBirthdate } = useSelector(selectors.selectQuestionnaire)
const zodiacSign = getZodiacSignByDate(birthdate); const zodiacSign = getZodiacSignByDate(birthdate);
const zodiacSignPartner = getZodiacSignByDate(partnerBirthdate); const zodiacSignPartner = getZodiacSignByDate(partnerBirthdate);
@ -53,8 +51,6 @@ function TrialChoice() {
"/v2/compatibility/partners.png" "/v2/compatibility/partners.png"
]) ])
const locale = getDefaultLocaleByLanguage(language);
const { flags, ready } = useMetricABFlags(); const { flags, ready } = useMetricABFlags();
const trialChoicePageType = flags?.trialChoicePageType?.[0]; const trialChoicePageType = flags?.trialChoicePageType?.[0];
// const trialChoicePageType = "v1"; // const trialChoicePageType = "v1";
@ -68,6 +64,28 @@ function TrialChoice() {
const email = useSelector(selectors.selectEmail); const email = useSelector(selectors.selectEmail);
const homeConfig = useSelector(selectors.selectHome); const homeConfig = useSelector(selectors.selectHome);
const { variant: trialPriceVariant = 'v0', isReady: isReadyTrialPrice } = useUnleash({
flag: EUnleashFlags.compatibilityV2TrialTextPrice,
});
const maxProduct = useMemo(() => {
if (!products?.length) return null;
return products.reduce(
(max, product) => {
return Number(product.trialPrice || 0) > Number(max.trialPrice || 0) ? product : max
},
products[0]
);
}, [products]);
const maxTrialPrice = useMemo(() => {
if (!maxProduct) return "";
return addCurrency(
getFormattedPrice(maxProduct.trialPrice || 0),
currency
);
}, [maxProduct, currency]);
const handlePriceItem = () => { const handlePriceItem = () => {
metricService.reachGoal(EGoals.SELECT_TRIAL, [EMetrics.YANDEX, EMetrics.KLAVIYO]); metricService.reachGoal(EGoals.SELECT_TRIAL, [EMetrics.YANDEX, EMetrics.KLAVIYO]);
metricService.reachGoal(EGoals.AURA_SELECT_TRIAL, [EMetrics.KLAVIYO]); metricService.reachGoal(EGoals.AURA_SELECT_TRIAL, [EMetrics.KLAVIYO]);
@ -91,7 +109,7 @@ function TrialChoice() {
metricService.reachGoal(EGoals.AURA_TRIAL_CHOICE_PAGE_VISIT, [EMetrics.KLAVIYO]); metricService.reachGoal(EGoals.AURA_TRIAL_CHOICE_PAGE_VISIT, [EMetrics.KLAVIYO]);
}, []); }, []);
if (!ready) { if (!ready || !isReadyTrialPrice) {
return ( return (
<div className={styles.container}> <div className={styles.container}>
<Loader className={styles.loader} /> <Loader className={styles.loader} />
@ -102,10 +120,29 @@ function TrialChoice() {
if (trialChoicePageType === "v1") { if (trialChoicePageType === "v1") {
return <TrialChoiceV1 />; return <TrialChoiceV1 />;
} }
let trialPriceTextVariant = 'v0';
switch (trialPriceVariant) {
case "v0":
trialPriceTextVariant = "v0";
break;
case "v1":
trialPriceTextVariant = "v1";
break;
case "v2":
trialPriceTextVariant = "v2";
break;
case "v3":
trialPriceTextVariant = "v3";
break;
default:
trialPriceTextVariant = "v0";
break;
}
return ( return (
<div className={styles.container}> <div className={styles.container}>
{!isLoading && ( {!(isLoading || !isReadyTrialPrice || !maxProduct) && (
<> <>
<EmailSubstrate className={styles["email-substrate"]} email={email} /> <EmailSubstrate className={styles["email-substrate"]} email={email} />
{/* {!isLongText && ( {/* {!isLongText && (
@ -113,7 +150,13 @@ function TrialChoice() {
{getText("text.0")} {getText("text.0")}
</Title> </Title>
)} */} )} */}
<p className={styles.text}>{getLongText(locale)}</p> <p className={styles.text}>{
translate('/trial-choice.description', {
maxTrialPrice,
trialDuration: maxProduct.trialDuration,
br: <br />
})
}</p>
<div className={styles["price-container"]}> <div className={styles["price-container"]}>
<PriceList <PriceList
@ -125,7 +168,12 @@ function TrialChoice() {
currency={currency} currency={currency}
click={handlePriceItem} click={handlePriceItem}
/> />
<p className={styles["auxiliary-text"]}>{getText("text.1")}</p> <p className={styles["auxiliary-text"]}>
{translate(`/trial-choice.trial-text.${trialPriceTextVariant}`, {
price: maxTrialPrice,
br: <br />
})}
</p>
</div> </div>
<Button <Button
@ -137,7 +185,7 @@ function TrialChoice() {
</Button> </Button>
</> </>
)} )}
{isLoading && <Loader className={styles.loader} />} {(isLoading || !isReadyTrialPrice) && <Loader className={styles.loader} />}
</div> </div>
); );
} }

View File

@ -1,80 +0,0 @@
export const getLongText = (locale: string) => {
if (locale === "es") {
return (
<>
AURA es la única aplicación precisa con un análisis fiable de la línea
del destino, verificado por profesionales y garantizado para
proporcionar predicciones precisas.
<br />
<br />
AURA ya ha ayudado a millones de personas a encontrar la felicidad y
descubrir toda la verdad sobre sus relaciones.
<br />
<br />
Tu análisis del destino, que cambiará tu vida por completo, ¡está casi
listo! Antes de proporcionártelo, nos gustaría ofrecerte la oportunidad
de elegir la cantidad que consideres razonable para probar AURA durante
7 días y que creas justa para los cambios que te sucederán:
<br />
<br />
Descubrirás todos los secretos más íntimos que las estrellas tienen
preparados para ti y resolverás problemas de relación en solo un mes;
<br />
<br />
Pondrás fin, de una vez por todas, a asuntos pendientes y olvidarás
los problemas que te han estado atormentando durante años (si no
décadas);
<br />
<br />
Ahorrarás cientos de dólares en predicciones astrológicas falsas y
adivinos no profesionales;
<br />
<br />
Recibirás no solo un análisis personal, sino también horóscopos
diarios personalizados, aprenderás quién y cómo está drenando tu energía
y obtendrás otras lecturas personalizadas.
<br />
<br />
El período de prueba de 7 días nos cuesta $13.76, pero por favor elige
la cantidad que más te convenga:
</>
);
}
return (
<>
AURA is the only accurate app with reliable fate line analysis, verified
by professionals and guaranteed to provide precise predictions.
<br />
<br />
AURA has already helped millions of people find happiness and discover the
whole truth about their relationships.
<br />
<br />
Your fate analysis, which will completely change your life, is almost
ready! Before we provide it to you, we would like to offer you the
opportunity to choose the amount you consider reasonable to try AURA for 7
days and which you think is fair for the changes that will happen to you:
<br />
<br />
You will discover all the most intimate secrets that the stars have
prepared for you and solve relationship issues within just one month;
<br />
<br />
You will once and for all put the finishing touches on unresolved issues
and forget about problems that have been haunting you for years (if not
decades);
<br />
<br />
You will save hundreds of dollars on fake and unprofessional astrological
predictions and fortune tellers;
<br />
<br />
You will receive not only a personal analysis but also personalized daily
horoscopes, learn who and how is draining your energy, and get other
personalized readings.
<br />
<br />A 7-day trial period costs us $13.76, but please choose the amount
that suits you best:
</>
);
};

View File

@ -6,29 +6,26 @@ import { actions, selectors } from "@/store";
import PriceList from "@/components/pages/ABDesign/v1/components/PriceList"; import PriceList from "@/components/pages/ABDesign/v1/components/PriceList";
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 { import {addCurrency, ELocalesPlacement} from "@/locales";
ELocalesPlacement, import {useEffect, useMemo, useState} from "react";
getDefaultLocaleByLanguage,
language,
} from "@/locales";
import { useEffect, useState } from "react";
import Button from "../../components/Button"; import Button from "../../components/Button";
import routes from "@/routes"; import routes from "@/routes";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import Loader from "@/components/Loader"; import Loader from "@/components/Loader";
import { useTranslations } from "@/hooks/translations"; import { useTranslations } from "@/hooks/translations";
// import { useMetricABFlags } from "@/services/metric/metricService"; // import { useMetricABFlags } from "@/services/metric/metricService";
import { getLongText } from "./abText";
import metricService, { EGoals, EMetrics } from "@/services/metric/metricService"; import metricService, { EGoals, EMetrics } from "@/services/metric/metricService";
import { usePreloadImages } from "@/hooks/preload/images"; import { usePreloadImages } from "@/hooks/preload/images";
import { getZodiacSignByDate } from "@/services/zodiac-sign"; import { getZodiacSignByDate } from "@/services/zodiac-sign";
import { images } from "../../data"; import { images } from "../../data";
import { EUnleashFlags, useUnleash } from "@/hooks/ab/unleash/useUnleash";
import {getFormattedPrice} from "@/utils/price.utils.tsx";
function TrialChoice() { function TrialChoice() {
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV3); const { translate } = useTranslations(ELocalesPlacement.CompatibilityV3);
const navigate = useNavigate(); const navigate = useNavigate();
const dispatch = useDispatch(); const dispatch = useDispatch();
const { products, isLoading, currency, getText } = usePaywall({ const { products, isLoading, currency } = usePaywall({
placementKey: EPlacementKeys["aura.placement.compatibility.v3"], placementKey: EPlacementKeys["aura.placement.compatibility.v3"],
localesPlacement: ELocalesPlacement.CompatibilityV3, localesPlacement: ELocalesPlacement.CompatibilityV3,
}); });
@ -52,8 +49,6 @@ function TrialChoice() {
"/v3/compatibility/partners.png" "/v3/compatibility/partners.png"
]) ])
const locale = getDefaultLocaleByLanguage(language);
// const { flags } = useMetricABFlags(); // const { flags } = useMetricABFlags();
// const isLongText = flags?.text?.[0] === "on"; // const isLongText = flags?.text?.[0] === "on";
@ -63,6 +58,28 @@ function TrialChoice() {
const email = useSelector(selectors.selectEmail); const email = useSelector(selectors.selectEmail);
const homeConfig = useSelector(selectors.selectHome); const homeConfig = useSelector(selectors.selectHome);
const maxProduct = useMemo(() => {
if (!products?.length) return null;
return products.reduce(
(max, product) => {
return Number(product.trialPrice || 0) > Number(max.trialPrice || 0) ? product : max
},
products[0]
);
}, [products]);
const maxTrialPrice = useMemo(() => {
if (!maxProduct) return "";
return addCurrency(
getFormattedPrice(maxProduct.trialPrice || 0),
currency
);
}, [maxProduct, currency]);
const { variant: trialPriceVariant = 'v0', isReady: isReadyTrialPrice } = useUnleash({
flag: EUnleashFlags.compatibilityV3TrialTextPrice,
});
const handlePriceItem = () => { const handlePriceItem = () => {
metricService.reachGoal(EGoals.SELECT_TRIAL, [EMetrics.YANDEX, EMetrics.KLAVIYO]); metricService.reachGoal(EGoals.SELECT_TRIAL, [EMetrics.YANDEX, EMetrics.KLAVIYO]);
metricService.reachGoal(EGoals.AURA_SELECT_TRIAL, [EMetrics.KLAVIYO]); metricService.reachGoal(EGoals.AURA_SELECT_TRIAL, [EMetrics.KLAVIYO]);
@ -86,9 +103,28 @@ function TrialChoice() {
metricService.reachGoal(EGoals.AURA_TRIAL_CHOICE_PAGE_VISIT, [EMetrics.KLAVIYO]); metricService.reachGoal(EGoals.AURA_TRIAL_CHOICE_PAGE_VISIT, [EMetrics.KLAVIYO]);
}, []); }, []);
let trialPriceTextVariant = 'v0';
switch (trialPriceVariant) {
case "v0":
trialPriceTextVariant = "v0";
break;
case "v1":
trialPriceTextVariant = "v1";
break;
case "v2":
trialPriceTextVariant = "v2";
break;
case "v3":
trialPriceTextVariant = "v3";
break;
default:
trialPriceTextVariant = "v0";
break;
}
return ( return (
<div className={styles.container}> <div className={styles.container}>
{!isLoading && ( {!(isLoading || !isReadyTrialPrice || !maxProduct) && (
<> <>
<EmailSubstrate className={styles["email-substrate"]} email={email} /> <EmailSubstrate className={styles["email-substrate"]} email={email} />
{/* {!isLongText && ( {/* {!isLongText && (
@ -96,7 +132,13 @@ function TrialChoice() {
{getText("text.0")} {getText("text.0")}
</Title> </Title>
)} */} )} */}
<p className={styles.text}>{getLongText(locale)}</p> <p className={styles.text}>{
translate('/trial-choice.description', {
maxTrialPrice,
trialDuration: maxProduct.trialDuration,
br: <br />
})
}</p>
<div className={styles["price-container"]}> <div className={styles["price-container"]}>
<PriceList <PriceList
@ -108,7 +150,12 @@ function TrialChoice() {
currency={currency} currency={currency}
click={handlePriceItem} click={handlePriceItem}
/> />
<p className={styles["auxiliary-text"]}>{getText("text.1")}</p> <p className={styles["auxiliary-text"]}>{
translate(`/trial-choice.trial-text.${trialPriceTextVariant}`, {
price: maxTrialPrice,
br: <br />
})
}</p>
</div> </div>
<Button <Button
@ -120,7 +167,7 @@ function TrialChoice() {
</Button> </Button>
</> </>
)} )}
{isLoading && <Loader className={styles.loader} />} {(isLoading || !isReadyTrialPrice) && <Loader className={styles.loader} />}
</div> </div>
); );
} }

View File

@ -4,6 +4,8 @@ import { compatibilityV4Prefix } from "@/routes";
import { useMemo, useRef } from "react"; import { useMemo, useRef } from "react";
import { useTranslations } from "@/hooks/translations"; import { useTranslations } from "@/hooks/translations";
import { ELocalesPlacement } from "@/locales"; import { ELocalesPlacement } from "@/locales";
import {useSelector} from "react-redux";
import { selectors } from "@/store";
interface IPoint { interface IPoint {
icon: string; icon: string;
@ -13,13 +15,19 @@ interface IPoint {
function HowWork() { function HowWork() {
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV4); const { translate } = useTranslations(ELocalesPlacement.CompatibilityV4);
const { relationshipStatus } = useSelector(selectors.selectCompatibilityV4Answers);
const textContainersRef = useRef([] as HTMLDivElement[]); const textContainersRef = useRef([] as HTMLDivElement[]);
const points: IPoint[] = useMemo( const points: IPoint[] = useMemo(
() => [ () => {
console.log(relationshipStatus)
console.log(relationshipStatus === "single" ? translate("/trial-payment.how_work.single.point1_title") : translate("/trial-payment.how_work.point1_title"))
console.log(translate("/trial-payment.how_work.single.point1_title"))
console.log(translate("/trial-payment.how_work.point1_title"))
return [
{ {
icon: `${compatibilityV4Prefix}/check-mark.svg`, icon: `${compatibilityV4Prefix}/check-mark.svg`,
title: translate("/trial-payment.how_work.point1_title"), title: relationshipStatus === "single" ? translate("/trial-payment.how_work.single.point1_title") : translate("/trial-payment.how_work.point1_title"),
text: translate("/trial-payment.how_work.point1_text"), text: translate("/trial-payment.how_work.point1_text"),
}, },
{ {
@ -37,7 +45,7 @@ function HowWork() {
title: translate("/trial-payment.how_work.point4_title"), title: translate("/trial-payment.how_work.point4_title"),
text: translate("/trial-payment.how_work.point4_text"), text: translate("/trial-payment.how_work.point4_text"),
}, },
], ]},
[translate] [translate]
); );

View File

@ -3,34 +3,40 @@ import styles from "./styles.module.scss";
import { useMemo } from "react"; import { useMemo } from "react";
import { useTranslations } from "@/hooks/translations"; import { useTranslations } from "@/hooks/translations";
import { ELocalesPlacement } from "@/locales"; import { ELocalesPlacement } from "@/locales";
import { selectors } from "@/store";
import { useSelector } from "react-redux";
function Reviews() { function Reviews() {
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV4); const { translate } = useTranslations(ELocalesPlacement.CompatibilityV4);
const { relationshipStatus } = useSelector(
selectors.selectCompatibilityV4Answers
);
const isSingle = relationshipStatus === "single";
const reviews: IReviewProps[] = useMemo( const reviews: IReviewProps[] = useMemo(
() => [ () => {
if (isSingle) {
return [
{
username: translate("/trial-payment.reviews.username1"),
text: translate("/trial-payment.reviews.text1"),
date: translate("/trial-payment.reviews.date1")
}
]
}
return [
{ {
// avatar: `${compatibilityV4Prefix}/reviews/mika.png`,
username: translate("/trial-payment.reviews.username2"), username: translate("/trial-payment.reviews.username2"),
// tagline: translate("/trial-payment.reviews.tagline2"),
text: translate("/trial-payment.reviews.text2"), text: translate("/trial-payment.reviews.text2"),
date: translate("/trial-payment.reviews.date2") date: translate("/trial-payment.reviews.date2")
}, },
{ {
// avatar: `${compatibilityV4Prefix}/reviews/rebecca.png`,
username: translate("/trial-payment.reviews.username1"), username: translate("/trial-payment.reviews.username1"),
// tagline: translate("/trial-payment.reviews.tagline1"),
text: translate("/trial-payment.reviews.text1"), text: translate("/trial-payment.reviews.text1"),
date: translate("/trial-payment.reviews.date1") date: translate("/trial-payment.reviews.date1")
}
]
}, },
// { [translate, isSingle]
// avatar: `${compatibilityV4Prefix}/reviews/amanda.png`,
// username: translate("/trial-payment.reviews.username3"),
// // tagline: translate("/trial-payment.reviews.tagline3"),
// text: translate("/trial-payment.reviews.text3"),
// date: translate("/trial-payment.reviews.date3")
// },
],
[translate]
); );
return ( return (

View File

@ -38,6 +38,21 @@
gap: 15px; gap: 15px;
} }
@media (max-width: 400px) {
.genders-container {
flex-direction: column;
gap: 10px;
align-items: stretch;
}
.answer {
max-width: 100%;
}
.genderIcon {
font-size: 36px;
}
}
.genderIcon { .genderIcon {
font-size: 50px; font-size: 50px;
line-height: 125%; line-height: 125%;

View File

@ -1,80 +0,0 @@
export const getLongText = (locale: string) => {
if (locale === "es") {
return (
<>
AURA es la única aplicación precisa con un análisis fiable de la línea
del destino, verificado por profesionales y garantizado para
proporcionar predicciones precisas.
<br />
<br />
AURA ya ha ayudado a millones de personas a encontrar la felicidad y
descubrir toda la verdad sobre sus relaciones.
<br />
<br />
Tu análisis del destino, que cambiará tu vida por completo, ¡está casi
listo! Antes de proporcionártelo, nos gustaría ofrecerte la oportunidad
de elegir la cantidad que consideres razonable para probar AURA durante
7 días y que creas justa para los cambios que te sucederán:
<br />
<br />
Descubrirás todos los secretos más íntimos que las estrellas tienen
preparados para ti y resolverás problemas de relación en solo un mes;
<br />
<br />
Pondrás fin, de una vez por todas, a asuntos pendientes y olvidarás
los problemas que te han estado atormentando durante años (si no
décadas);
<br />
<br />
Ahorrarás cientos de dólares en predicciones astrológicas falsas y
adivinos no profesionales;
<br />
<br />
Recibirás no solo un análisis personal, sino también horóscopos
diarios personalizados, aprenderás quién y cómo está drenando tu energía
y obtendrás otras lecturas personalizadas.
<br />
<br />
El período de prueba de 7 días nos cuesta $13.76, pero por favor elige
la cantidad que más te convenga:
</>
);
}
return (
<>
AURA is the only accurate app with reliable fate line analysis, verified
by professionals and guaranteed to provide precise predictions.
<br />
<br />
AURA has already helped millions of people find happiness and discover the
whole truth about their relationships.
<br />
<br />
Your fate analysis, which will completely change your life, is almost
ready! Before we provide it to you, we would like to offer you the
opportunity to choose the amount you consider reasonable to try AURA for 7
days and which you think is fair for the changes that will happen to you:
<br />
<br />
You will discover all the most intimate secrets that the stars have
prepared for you and solve relationship issues within just one month;
<br />
<br />
You will once and for all put the finishing touches on unresolved issues
and forget about problems that have been haunting you for years (if not
decades);
<br />
<br />
You will save hundreds of dollars on fake and unprofessional astrological
predictions and fortune tellers;
<br />
<br />
You will receive not only a personal analysis but also personalized daily
horoscopes, learn who and how is draining your energy, and get other
personalized readings.
<br />
<br />A 7-day trial period costs us $13.76, but please choose the amount
that suits you best:
</>
);
};

View File

@ -6,28 +6,25 @@ import { actions, selectors } from "@/store";
import PriceList from "@/components/pages/ABDesign/v1/components/PriceList"; import PriceList from "@/components/pages/ABDesign/v1/components/PriceList";
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 { import {addCurrency, ELocalesPlacement} from "@/locales";
ELocalesPlacement, import {useEffect, useMemo, useState} from "react";
getDefaultLocaleByLanguage,
language,
} from "@/locales";
import { useEffect, useState } from "react";
import Button from "../../components/Button"; import Button from "../../components/Button";
import routes from "@/routes"; import routes from "@/routes";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import Loader from "@/components/Loader"; import Loader from "@/components/Loader";
import { useTranslations } from "@/hooks/translations"; import { useTranslations } from "@/hooks/translations";
// import { useMetricABFlags } from "@/services/metric/metricService"; // import { useMetricABFlags } from "@/services/metric/metricService";
import { getLongText } from "./abText";
import metricService, { EGoals, EMetrics } from "@/services/metric/metricService"; import metricService, { EGoals, EMetrics } from "@/services/metric/metricService";
import { usePreloadImages } from "@/hooks/preload/images"; import { usePreloadImages } from "@/hooks/preload/images";
import { getZodiacSignByDate } from "@/services/zodiac-sign"; import { getZodiacSignByDate } from "@/services/zodiac-sign";
import { EUnleashFlags, useUnleash } from "@/hooks/ab/unleash/useUnleash";
import {getFormattedPrice} from "@/utils/price.utils.tsx";
function TrialChoice() { function TrialChoice() {
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV4); const { translate } = useTranslations(ELocalesPlacement.CompatibilityV4);
const navigate = useNavigate(); const navigate = useNavigate();
const dispatch = useDispatch(); const dispatch = useDispatch();
const { products, isLoading, currency, getText } = usePaywall({ const { products, isLoading, currency } = usePaywall({
placementKey: EPlacementKeys["aura.placement.compatibility.v4"], placementKey: EPlacementKeys["aura.placement.compatibility.v4"],
localesPlacement: ELocalesPlacement.CompatibilityV4, localesPlacement: ELocalesPlacement.CompatibilityV4,
}); });
@ -43,8 +40,6 @@ function TrialChoice() {
"/v4/compatibility/partners.png" "/v4/compatibility/partners.png"
]) ])
const locale = getDefaultLocaleByLanguage(language);
// const { flags } = useMetricABFlags(); // const { flags } = useMetricABFlags();
// const isLongText = flags?.text?.[0] === "on"; // const isLongText = flags?.text?.[0] === "on";
@ -53,6 +48,35 @@ function TrialChoice() {
const selectedPrice = useSelector(selectors.selectSelectedPrice); const selectedPrice = useSelector(selectors.selectSelectedPrice);
const email = useSelector(selectors.selectEmail); const email = useSelector(selectors.selectEmail);
const homeConfig = useSelector(selectors.selectHome); const homeConfig = useSelector(selectors.selectHome);
// const maxProduct = products.reduce((max, product) => {
// return Number(product.trialPrice) > Number(max.trialPrice) ? product : max
// }, products[0])
// const maxTrialPrice = addCurrency(
// getFormattedPrice(maxProduct?.trialPrice || 0),
// currency
// );
const maxProduct = useMemo(() => {
if (!products?.length) return null;
return products.reduce(
(max, product) => {
return Number(product.trialPrice || 0) > Number(max.trialPrice || 0) ? product : max
},
products[0]
);
}, [products]);
const maxTrialPrice = useMemo(() => {
if (!maxProduct) return "";
return addCurrency(
getFormattedPrice(maxProduct.trialPrice || 0),
currency
);
}, [maxProduct, currency]);
const { variant: trialPriceVariant = 'v0', isReady: isReadyTrialPrice } = useUnleash({
flag: EUnleashFlags.compatibilityV4TrialTextPrice,
});
const handlePriceItem = () => { const handlePriceItem = () => {
metricService.reachGoal(EGoals.SELECT_TRIAL, [EMetrics.YANDEX, EMetrics.KLAVIYO]); metricService.reachGoal(EGoals.SELECT_TRIAL, [EMetrics.YANDEX, EMetrics.KLAVIYO]);
@ -77,9 +101,28 @@ function TrialChoice() {
metricService.reachGoal(EGoals.AURA_TRIAL_CHOICE_PAGE_VISIT, [EMetrics.KLAVIYO]); metricService.reachGoal(EGoals.AURA_TRIAL_CHOICE_PAGE_VISIT, [EMetrics.KLAVIYO]);
}, []); }, []);
let trialPriceTextVariant = 'v0';
switch (trialPriceVariant) {
case "v0":
trialPriceTextVariant = "v0";
break;
case "v1":
trialPriceTextVariant = "v1";
break;
case "v2":
trialPriceTextVariant = "v2";
break;
case "v3":
trialPriceTextVariant = "v3";
break;
default:
trialPriceTextVariant = "v0";
break;
}
return ( return (
<div className={styles.container}> <div className={styles.container}>
{!isLoading && ( {!(isLoading || !isReadyTrialPrice || !maxProduct) && (
<> <>
<EmailSubstrate className={styles["email-substrate"]} email={email} /> <EmailSubstrate className={styles["email-substrate"]} email={email} />
{/* {!isLongText && ( {/* {!isLongText && (
@ -87,7 +130,13 @@ function TrialChoice() {
{getText("text.0")} {getText("text.0")}
</Title> </Title>
)} */} )} */}
<p className={styles.text}>{getLongText(locale)}</p> <p className={styles.text}>{
translate('/trial-choice.description', {
maxTrialPrice,
trialDuration: maxProduct.trialDuration,
br: <br />
})
}</p>
<div className={styles["price-container"]}> <div className={styles["price-container"]}>
<PriceList <PriceList
@ -99,7 +148,12 @@ function TrialChoice() {
currency={currency} currency={currency}
click={handlePriceItem} click={handlePriceItem}
/> />
<p className={styles["auxiliary-text"]}>{getText("text.1")}</p> <p className={styles["auxiliary-text"]}>{
translate(`/trial-choice.trial-text.${trialPriceTextVariant}`, {
price: maxTrialPrice,
br: <br />
})
}</p>
</div> </div>
<Button <Button
@ -111,7 +165,7 @@ function TrialChoice() {
</Button> </Button>
</> </>
)} )}
{isLoading && <Loader className={styles.loader} />} {(isLoading || !isReadyTrialPrice) && <Loader className={styles.loader} />}
</div> </div>
); );
} }

View File

@ -46,8 +46,16 @@ function YourReading({
</Title> </Title>
<ul className={styles.points}> <ul className={styles.points}>
{Array.from({ length: 7 }).map((_, index) => ( {Array.from({ length: 7 }).map((_, index) => (
<li key={index} className={`${index > 2 ? styles.point_blur : ""}`}> <li
{translate(`/trial-payment.your-reading.points.${version}.point${index + 1}`)} key={index}
className={`${index > 2 ? styles.point_blur : ""}`}
style={{ marginBottom: "1em" }}
>
{
relationshipStatus !== "single" ?
translate(`/trial-payment.your-reading.points.${version}.point${index + 1}`) :
translate(`/trial-payment.your-reading.points.single.${version}.point${index + 1}`)
}
</li> </li>
))} ))}
</ul> </ul>

View File

@ -82,6 +82,25 @@ function TrialPayment() {
{translate("/trial-payment.information-title")} {translate("/trial-payment.information-title")}
</Title> </Title>
<ZodiacImagesWithBook /> <ZodiacImagesWithBook />
{(relationshipStatus === "single" || !partnerBirthdate) &&
<p className={styles["information-description"]}>
{translate("/trial-payment.information-description-single", {
color: <span>
{translate("/trial-payment.information-description-single-color", {
zodiacSign: zodiacSign?.toLowerCase().charAt(0).toUpperCase() + zodiacSign?.toLowerCase().slice(1),
birthdate: formatDateToLocale(birthdate, language),
})}
</span>,
eventDescription: dateEvent ? <b>
{translate("/trial-payment.information-description-single-event-description", {
dateEvent: formatDateToLocale(dateEvent, language),
})}
</b> : "",
br: <br />
})}
</p>
}
{relationshipStatus !== "single" && partnerBirthdate && {relationshipStatus !== "single" && partnerBirthdate &&
<p className={styles["information-description"]}> <p className={styles["information-description"]}>
{translate("/trial-payment.information-description-with-partner", { {translate("/trial-payment.information-description-with-partner", {
@ -101,6 +120,27 @@ function TrialPayment() {
})} })}
</p> </p>
} }
{/*{relationshipStatus !== "single" && partnerBirthdate &&*/}
{/* <p className={styles["information-description"]}>*/}
{/* {translate("/trial-payment.information-description-with-partner", {*/}
{/* color: <span>*/}
{/* {translate("/trial-payment.information-description-with-partner-color", {*/}
{/* zodiacSign: zodiacSign?.toLowerCase().charAt(0).toUpperCase() + zodiacSign?.toLowerCase().slice(1),*/}
{/* partnerZodiacSign: partnerZodiacSign?.toLowerCase().charAt(0).toUpperCase() + partnerZodiacSign?.toLowerCase().slice(1),*/}
{/* birthdate: formatDateToLocale(birthdate, language),*/}
{/* partnerBirthdate: formatDateToLocale(partnerBirthdate, language),*/}
{/* })}*/}
{/* </span>,*/}
{/* eventDescription: dateEvent ? <b>*/}
{/* {translate("/trial-payment.information-description-with-partner-event-description", {*/}
{/* dateEvent: formatDateToLocale(dateEvent, language),*/}
{/* })}*/}
{/* </b> : "",*/}
{/* })}*/}
{/* </p>*/}
{/*}*/}
<div> <div>
<Title className={styles["reading-ready"]}> <Title className={styles["reading-ready"]}>
{translate("/trial-payment.reading_ready.title")} {translate("/trial-payment.reading_ready.title")}

View File

@ -1,80 +0,0 @@
export const getLongText = (locale: string) => {
if (locale === "es") {
return (
<>
AURA es la única aplicación precisa con un análisis fiable de la línea
del destino, verificado por profesionales y garantizado para
proporcionar predicciones precisas.
<br />
<br />
AURA ya ha ayudado a millones de personas a encontrar la felicidad y
descubrir toda la verdad sobre sus relaciones.
<br />
<br />
Tu análisis del destino, que cambiará tu vida por completo, ¡está casi
listo! Antes de proporcionártelo, nos gustaría ofrecerte la oportunidad
de elegir la cantidad que consideres razonable para probar AURA durante
7 días y que creas justa para los cambios que te sucederán:
<br />
<br />
Descubrirás todos los secretos más íntimos que las estrellas tienen
preparados para ti y resolverás problemas de relación en solo un mes;
<br />
<br />
Pondrás fin, de una vez por todas, a asuntos pendientes y olvidarás
los problemas que te han estado atormentando durante años (si no
décadas);
<br />
<br />
Ahorrarás cientos de dólares en predicciones astrológicas falsas y
adivinos no profesionales;
<br />
<br />
Recibirás no solo un análisis personal, sino también horóscopos
diarios personalizados, aprenderás quién y cómo está drenando tu energía
y obtendrás otras lecturas personalizadas.
<br />
<br />
El período de prueba de 7 días nos cuesta $13.76, pero por favor elige
la cantidad que más te convenga:
</>
);
}
return (
<>
AURA is the only accurate app with reliable fate line analysis, verified
by professionals and guaranteed to provide precise predictions.
<br />
<br />
AURA has already helped millions of people find happiness and discover the
whole truth about their relationships.
<br />
<br />
Your fate analysis, which will completely change your life, is almost
ready! Before we provide it to you, we would like to offer you the
opportunity to choose the amount you consider reasonable to try AURA for 7
days and which you think is fair for the changes that will happen to you:
<br />
<br />
You will discover all the most intimate secrets that the stars have
prepared for you and solve relationship issues within just one month;
<br />
<br />
You will once and for all put the finishing touches on unresolved issues
and forget about problems that have been haunting you for years (if not
decades);
<br />
<br />
You will save hundreds of dollars on fake and unprofessional astrological
predictions and fortune tellers;
<br />
<br />
You will receive not only a personal analysis but also personalized daily
horoscopes, learn who and how is draining your energy, and get other
personalized readings.
<br />
<br />A 7-day trial period costs us $13.76, but please choose the amount
that suits you best:
</>
);
};

View File

@ -6,28 +6,25 @@ import { actions, selectors } from "@/store";
import PriceList from "@/components/pages/ABDesign/v1/components/PriceList"; import PriceList from "@/components/pages/ABDesign/v1/components/PriceList";
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 { import {addCurrency, ELocalesPlacement} from "@/locales";
ELocalesPlacement, import {useEffect, useMemo, useState} from "react";
getDefaultLocaleByLanguage,
language,
} from "@/locales";
import { useEffect, useState } from "react";
import Button from "../../components/Button"; import Button from "../../components/Button";
import routes from "@/routes"; import routes from "@/routes";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import Loader from "@/components/Loader"; import Loader from "@/components/Loader";
import { useTranslations } from "@/hooks/translations"; import { useTranslations } from "@/hooks/translations";
// import { useMetricABFlags } from "@/services/metric/metricService"; // import { useMetricABFlags } from "@/services/metric/metricService";
import { getLongText } from "./abText";
import metricService, { EGoals, EMetrics, useMetricABFlags } from "@/services/metric/metricService"; import metricService, { EGoals, EMetrics, useMetricABFlags } from "@/services/metric/metricService";
import TrialChoiceV1 from "./v1"; import TrialChoiceV1 from "./v1";
import { usePreloadImages } from "@/hooks/preload/images"; import { usePreloadImages } from "@/hooks/preload/images";
import { EUnleashFlags, useUnleash } from "@/hooks/ab/unleash/useUnleash";
import {getFormattedPrice} from "@/utils/price.utils.tsx";
function TrialChoice() { function TrialChoice() {
const { translate } = useTranslations(ELocalesPlacement.PalmistryV1); const { translate } = useTranslations(ELocalesPlacement.PalmistryV1);
const navigate = useNavigate(); const navigate = useNavigate();
const dispatch = useDispatch(); const dispatch = useDispatch();
const { products, isLoading, currency, getText } = usePaywall({ const { products, isLoading, currency } = usePaywall({
placementKey: EPlacementKeys["aura.placement.palmistry.redesign"], placementKey: EPlacementKeys["aura.placement.palmistry.redesign"],
localesPlacement: ELocalesPlacement.PalmistryV1, localesPlacement: ELocalesPlacement.PalmistryV1,
}); });
@ -46,8 +43,6 @@ function TrialChoice() {
"/v1/palmistry/partners.png" "/v1/palmistry/partners.png"
]) ])
const locale = getDefaultLocaleByLanguage(language);
const { flags, ready } = useMetricABFlags(); const { flags, ready } = useMetricABFlags();
const trialChoicePageType = flags?.trialChoicePageType?.[0]; const trialChoicePageType = flags?.trialChoicePageType?.[0];
// const trialChoicePageType = "v1"; // const trialChoicePageType = "v1";
@ -58,6 +53,26 @@ function TrialChoice() {
const selectedPrice = useSelector(selectors.selectSelectedPrice); const selectedPrice = useSelector(selectors.selectSelectedPrice);
const email = useSelector(selectors.selectEmail); const email = useSelector(selectors.selectEmail);
const homeConfig = useSelector(selectors.selectHome); const homeConfig = useSelector(selectors.selectHome);
const maxProduct = useMemo(() => {
if (!products?.length) return null;
return products.reduce(
(max, product) => {
return Number(product.trialPrice || 0) > Number(max.trialPrice || 0) ? product : max
},
products[0]
);
}, [products]);
const maxTrialPrice = useMemo(() => {
if (!maxProduct) return "";
return addCurrency(
getFormattedPrice(maxProduct.trialPrice || 0),
currency
);
}, [maxProduct, currency]);
const { variant: trialPriceVariant = 'v0', isReady: isReadyTrialPrice } = useUnleash({
flag: EUnleashFlags.palmistryV1TrialTextPrice,
});
const handlePriceItem = () => { const handlePriceItem = () => {
metricService.reachGoal(EGoals.SELECT_TRIAL, [EMetrics.YANDEX, EMetrics.KLAVIYO]); metricService.reachGoal(EGoals.SELECT_TRIAL, [EMetrics.YANDEX, EMetrics.KLAVIYO]);
@ -82,7 +97,7 @@ function TrialChoice() {
metricService.reachGoal(EGoals.AURA_TRIAL_CHOICE_PAGE_VISIT, [EMetrics.KLAVIYO]); metricService.reachGoal(EGoals.AURA_TRIAL_CHOICE_PAGE_VISIT, [EMetrics.KLAVIYO]);
}, []); }, []);
if (!ready) { if (!ready || !isReadyTrialPrice) {
return ( return (
<div className={styles.container}> <div className={styles.container}>
<Loader className={styles.loader} /> <Loader className={styles.loader} />
@ -94,9 +109,28 @@ function TrialChoice() {
return <TrialChoiceV1 />; return <TrialChoiceV1 />;
} }
let trialPriceTextVariant = 'v0';
switch (trialPriceVariant) {
case "v0":
trialPriceTextVariant = "v0";
break;
case "v1":
trialPriceTextVariant = "v1";
break;
case "v2":
trialPriceTextVariant = "v2";
break;
case "v3":
trialPriceTextVariant = "v3";
break;
default:
trialPriceTextVariant = "v0";
break;
}
return ( return (
<div className={styles.container}> <div className={styles.container}>
{!isLoading && ( {!(isLoading || !isReadyTrialPrice || !maxProduct) && (
<> <>
<EmailSubstrate className={styles["email-substrate"]} email={email} /> <EmailSubstrate className={styles["email-substrate"]} email={email} />
{/* {!isLongText && ( {/* {!isLongText && (
@ -104,7 +138,13 @@ function TrialChoice() {
{getText("text.0")} {getText("text.0")}
</Title> </Title>
)} */} )} */}
<p className={styles.text}>{getLongText(locale)}</p> <p className={styles.text}>{
translate('/trial-choice.description', {
maxTrialPrice,
trialDuration: maxProduct.trialDuration,
br: <br />
})
}</p>
<div className={styles["price-container"]}> <div className={styles["price-container"]}>
<PriceList <PriceList
@ -116,7 +156,12 @@ function TrialChoice() {
currency={currency} currency={currency}
click={handlePriceItem} click={handlePriceItem}
/> />
<p className={styles["auxiliary-text"]}>{getText("text.1")}</p> <p className={styles["auxiliary-text"]}>
{translate(`/trial-choice.trial-text.${trialPriceTextVariant}`, {
price: maxTrialPrice,
br: <br />
})}
</p>
</div> </div>
<Button <Button
@ -128,7 +173,7 @@ function TrialChoice() {
</Button> </Button>
</> </>
)} )}
{isLoading && <Loader className={styles.loader} />} {(isLoading || !isReadyTrialPrice) && <Loader className={styles.loader} />}
</div> </div>
); );
} }

View File

@ -1,4 +1,5 @@
import styles from "./styles.module.scss"; import styles from "./styles.module.scss";
import "./../../../discount-screen/discount-screen.css";
import Title from "@/components/Title"; import Title from "@/components/Title";
import { addCurrency, ELocalesPlacement } from "@/locales"; import { addCurrency, ELocalesPlacement } from "@/locales";
import { getPriceCentsToDollars } from "@/services/price"; import { getPriceCentsToDollars } from "@/services/price";

View File

@ -26,7 +26,13 @@ export enum EUnleashFlags {
"compatibilityV2ScanHand" = "compatibilityV2ScanHand", "compatibilityV2ScanHand" = "compatibilityV2ScanHand",
"preloadImages" = "preloadImages", "preloadImages" = "preloadImages",
"scanHandTimeCompatibilityV2" = "scanHandTimeCompatibilityV2", "scanHandTimeCompatibilityV2" = "scanHandTimeCompatibilityV2",
"compatibilityV2TimeForCameraInit" = "compatibilityV2TimeForCameraInit" "compatibilityV2TimeForCameraInit" = "compatibilityV2TimeForCameraInit",
"compatibilityV2TrialTextPrice" = "v2-compatibility-trial-text-price",
"compatibilityV3TrialTextPrice" = "v3-compatibility-trial-text-price",
"compatibilityV4TrialTextPrice" = "v4-compatibility-trial-text-price",
"palmistryV1TrialTextPrice" = "v1-palmistry-trial-text-price",
"v2CompatibilityScanResultNumbers" = "v2-compatibility-scan-result-numbers",
"v2CompatibilityScanInstructionImage" = "v2-compatibility-scan-instruction-image"
} }
interface IUseUnleashProps<T extends EUnleashFlags> { interface IUseUnleashProps<T extends EUnleashFlags> {
@ -58,6 +64,13 @@ interface IVariants {
[EUnleashFlags.preloadImages]: "yes" | "no"; [EUnleashFlags.preloadImages]: "yes" | "no";
[EUnleashFlags.scanHandTimeCompatibilityV2]: "v0" | "v1"; [EUnleashFlags.scanHandTimeCompatibilityV2]: "v0" | "v1";
[EUnleashFlags.compatibilityV2TimeForCameraInit]: string; [EUnleashFlags.compatibilityV2TimeForCameraInit]: string;
[EUnleashFlags.compatibilityV2TrialTextPrice]: "v0" | "v1" | "v2" | "v3";
[EUnleashFlags.compatibilityV3TrialTextPrice]: "v0" | "v1" | "v2" | "v3";
[EUnleashFlags.compatibilityV4TrialTextPrice]: "v0" | "v1" | "v2" | "v3";
[EUnleashFlags.palmistryV1TrialTextPrice]: "v0" | "v1" | "v2" | "v3";
[EUnleashFlags.v2CompatibilityScanResultNumbers]: 'off' | 'on';
[EUnleashFlags.v2CompatibilityScanInstructionImage]: 'v0' | 'v1';
} }
/** /**

View File

@ -45,8 +45,8 @@ export const lottieUrls = {
[ELottieKeys.scalesNeutralPalmistry]: "https://lottie.host/9027e5a7-d5e8-4e60-b097-ba4bf099b433/UsCKDjKVUr.lottie", [ELottieKeys.scalesNeutralPalmistry]: "https://lottie.host/9027e5a7-d5e8-4e60-b097-ba4bf099b433/UsCKDjKVUr.lottie",
[ELottieKeys.scalesHeadPalmistry]: "https://lottie.host/d16336c4-2622-48f8-b361-8d9d50b3c8a6/wWSM7JMCHu.lottie", [ELottieKeys.scalesHeadPalmistry]: "https://lottie.host/d16336c4-2622-48f8-b361-8d9d50b3c8a6/wWSM7JMCHu.lottie",
[ELottieKeys.scalesHeartPalmistry]: "https://lottie.host/fa931c2d-07f5-4c57-a4bb-8302b411ecca/zy9ag3MyMe.lottie", [ELottieKeys.scalesHeartPalmistry]: "https://lottie.host/fa931c2d-07f5-4c57-a4bb-8302b411ecca/zy9ag3MyMe.lottie",
[ELottieKeys.letScan]: "https://lottie.host/f87184ec-aa5e-4cf4-82a5-9ab5e60c22d5/qpgweCSCtn.lottie", [ELottieKeys.letScan]: 'https://lottie.host/77c3c34b-4c1e-4cab-87f4-40d7534fea3d/wMg1wqtSS6.lottie',//"https://lottie.host/f87184ec-aa5e-4cf4-82a5-9ab5e60c22d5/qpgweCSCtn.lottie",
[ELottieKeys.letScanDark]: "https://lottie.host/c890243e-c61a-4e76-8b93-e8d24b25dd97/leetT4srXt.lottie", [ELottieKeys.letScanDark]: 'https://lottie.host/71623941-9182-4d58-8a1d-cb05cc5732ad/fEXKgPZQYq.lottie',//"https://lottie.host/c890243e-c61a-4e76-8b93-e8d24b25dd97/leetT4srXt.lottie",
[ELottieKeys.scannedPhoto]: "https://lottie.host/0570b1a3-2441-486e-909b-bc2a6ceb692b/KAHTUVUb8C.lottie", [ELottieKeys.scannedPhoto]: "https://lottie.host/0570b1a3-2441-486e-909b-bc2a6ceb692b/KAHTUVUb8C.lottie",
} }

View File

@ -106,7 +106,7 @@ export type TTranslationPlacements = Partial<
export const getTranslationsJSON = async (language: string): Promise<TTranslationPlacements> => { export const getTranslationsJSON = async (language: string): Promise<TTranslationPlacements> => {
const api = createApi(); const api = createApi();
const isDev = window.location.hostname === "localhost" const isDev = false//window.location.hostname === "localhost"
let defaultLanguage = getDefaultLocaleByLanguage(language).toLowerCase(); let defaultLanguage = getDefaultLocaleByLanguage(language).toLowerCase();
if (defaultLanguage === "pt") { if (defaultLanguage === "pt") {
defaultLanguage = "pt-pt" defaultLanguage = "pt-pt"