Merge branch 'develop' into 'main'
hint-palm See merge request witapp/aura-webapp!673
This commit is contained in:
commit
51bfc8a029
@ -1,9 +1,7 @@
|
||||
import styles from "./styles.module.scss";
|
||||
import Title from "@/components/Title";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { actions, selectors } from "@/store";
|
||||
import { Gender } from "@/data";
|
||||
import PrivacyPolicy from "@/components/pages/ABDesign/v1/components/PrivacyPolicy";
|
||||
// import Toast from "@/components/pages/ABDesign/v1/components/Toast";
|
||||
import { useTranslations } from "@/hooks/translations";
|
||||
import { ELocalesPlacement } from "@/locales";
|
||||
@ -17,10 +15,11 @@ import { usePreloadImages } from "@/hooks/preload/images";
|
||||
import { ELottieKeys, useLottie } from "@/hooks/lottie/useLottie";
|
||||
import { useSession } from "@/hooks/session/useSession";
|
||||
import { EGender, ESourceAuthorization } from "@/api/resources/User";
|
||||
import AlreadyHaveAccount from "@/components/ui/AlreadyHaveAccount";
|
||||
import Answer from "../../components/Answer";
|
||||
import Loader, { LoaderColor } from "@/components/Loader";
|
||||
import { useUnleash } from "@/hooks/ab/unleash/useUnleash";
|
||||
import { EUnleashFlags, useUnleash } from "@/hooks/ab/unleash/useUnleash";
|
||||
import GenderV0 from "./variants/GenderV0";
|
||||
import GenderV1 from "./variants/GenderV1";
|
||||
import GenderV2 from "./variants/GenderV2";
|
||||
|
||||
function GenderPage() {
|
||||
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
|
||||
@ -41,7 +40,7 @@ function GenderPage() {
|
||||
const { flags, ready } = useMetricABFlags();
|
||||
|
||||
const { isReady, variant: genderPageType } = useUnleash({
|
||||
flag: "genderPageType"
|
||||
flag: EUnleashFlags.genderPageType
|
||||
});
|
||||
|
||||
const pageType = flags?.genderPageType?.[0] || genderPageType || "v2";
|
||||
@ -115,142 +114,19 @@ function GenderPage() {
|
||||
switch (pageType) {
|
||||
case "v0":
|
||||
return (
|
||||
<>
|
||||
<Title variant="h2" className={styles.title}>
|
||||
{translate("/gender.title")}
|
||||
</Title>
|
||||
<p className={styles.description}>{translate("/gender.description", {
|
||||
br: <br />,
|
||||
})}</p>
|
||||
{/* <ChooseGender onSelectGender={selectGender} /> */}
|
||||
<PrivacyPolicy containerClassName={styles["privacy-policy"]} haveCheckbox={false} />
|
||||
<div className={styles["genders-container"]}>
|
||||
{localGenders.map((_gender, index) => (
|
||||
<Answer
|
||||
key={index}
|
||||
answer={_gender}
|
||||
isSelected={gender === _gender.id}
|
||||
onClick={() => selectGender(genders.find((g) => g.id === _gender.id) ?? null)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<AlreadyHaveAccount text={translate("/gender.already_have_account")} />
|
||||
{/* {gender && !privacyPolicyChecked && (
|
||||
<Toast classNameContainer={styles["toast-container"]} variant="error">
|
||||
{translate("/gender.toast", undefined, ELocalesPlacement.V1)}
|
||||
</Toast>
|
||||
)} */}
|
||||
</>
|
||||
<GenderV0 localGenders={localGenders} gender={gender} selectGender={selectGender} />
|
||||
)
|
||||
case "v1":
|
||||
return (
|
||||
<>
|
||||
<Title variant="h2" className={styles.title}>
|
||||
{translate("/gender.v1.title", {
|
||||
br: <br />,
|
||||
})}
|
||||
</Title>
|
||||
<p className={styles.subtitle}>{translate("/gender.v1.subtitle", {
|
||||
br: <br />,
|
||||
})}</p>
|
||||
<ul className={styles.points}>
|
||||
{Array.from({ length: 4 }).map((_, index) => (
|
||||
<li key={index}>
|
||||
{translate(`/gender.v1.points.point${index + 1}`)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{/* <ChooseGender onSelectGender={selectGender} /> */}
|
||||
<div className={styles["genders-container"]}>
|
||||
{localGenders.map((_gender, index) => (
|
||||
<Answer
|
||||
key={index}
|
||||
answer={_gender}
|
||||
isSelected={gender === _gender.id}
|
||||
onClick={() => selectGender(genders.find((g) => g.id === _gender.id) ?? null)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<PrivacyPolicy containerClassName={styles["privacy-policy"]} haveCheckbox={false} />
|
||||
<AlreadyHaveAccount text={translate("/gender.already_have_account")} />
|
||||
{/* {gender && !privacyPolicyChecked && (
|
||||
<Toast classNameContainer={styles["toast-container"]} variant="error">
|
||||
{translate("/gender.toast", undefined, ELocalesPlacement.V1)}
|
||||
</Toast>
|
||||
)} */}
|
||||
</>
|
||||
<GenderV1 localGenders={localGenders} gender={gender} selectGender={selectGender} />
|
||||
)
|
||||
case "v2":
|
||||
return (
|
||||
<>
|
||||
<Title variant="h2" className={styles.title}>
|
||||
{translate("/gender.v2.title", {
|
||||
br: <br />,
|
||||
})}
|
||||
</Title>
|
||||
<ul className={styles.points}>
|
||||
{Array.from({ length: 5 }).map((_, index) => (
|
||||
<li key={index}>
|
||||
{translate(`/gender.v2.points.point${index + 1}`)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<p
|
||||
className={styles.subtitle}
|
||||
style={{
|
||||
marginTop: "28px",
|
||||
}}
|
||||
>{translate("/gender.v2.subtitle", {
|
||||
br: <br />,
|
||||
})}</p>
|
||||
{/* <ChooseGender onSelectGender={selectGender} /> */}
|
||||
<div className={styles["genders-container"]}>
|
||||
{localGenders.map((_gender, index) => (
|
||||
<Answer
|
||||
key={index}
|
||||
answer={_gender}
|
||||
isSelected={gender === _gender.id}
|
||||
onClick={() => selectGender(genders.find((g) => g.id === _gender.id) ?? null)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<PrivacyPolicy containerClassName={styles["privacy-policy"]} haveCheckbox={false} />
|
||||
<AlreadyHaveAccount text={translate("/gender.already_have_account")} />
|
||||
{/* {gender && !privacyPolicyChecked && (
|
||||
<Toast classNameContainer={styles["toast-container"]} variant="error">
|
||||
{translate("/gender.toast", undefined, ELocalesPlacement.V1)}
|
||||
</Toast>
|
||||
)} */}
|
||||
</>
|
||||
<GenderV2 localGenders={localGenders} gender={gender} selectGender={selectGender} />
|
||||
)
|
||||
default:
|
||||
return (
|
||||
<>
|
||||
<Title variant="h2" className={styles.title}>
|
||||
{translate("/gender.title")}
|
||||
</Title>
|
||||
<p className={styles.description}>{translate("/gender.description", {
|
||||
br: <br />,
|
||||
})}</p>
|
||||
{/* <ChooseGender onSelectGender={selectGender} /> */}
|
||||
<PrivacyPolicy containerClassName={styles["privacy-policy"]} haveCheckbox={false} />
|
||||
<div className={styles["genders-container"]}>
|
||||
{localGenders.map((_gender, index) => (
|
||||
<Answer
|
||||
key={index}
|
||||
answer={_gender}
|
||||
isSelected={gender === _gender.id}
|
||||
onClick={() => selectGender(genders.find((g) => g.id === _gender.id) ?? null)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<AlreadyHaveAccount text={translate("/gender.already_have_account")} />
|
||||
{/* {gender && !privacyPolicyChecked && (
|
||||
<Toast classNameContainer={styles["toast-container"]} variant="error">
|
||||
{translate("/gender.toast", undefined, ELocalesPlacement.V1)}
|
||||
</Toast>
|
||||
)} */}
|
||||
</>
|
||||
<GenderV0 localGenders={localGenders} gender={gender} selectGender={selectGender} />
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
import Title from "@/components/Title"
|
||||
import styles from "../../styles.module.scss"
|
||||
import { useTranslations } from "@/hooks/translations";
|
||||
import { ELocalesPlacement } from "@/locales";
|
||||
import PrivacyPolicy from "@/components/pages/ABDesign/v1/components/PrivacyPolicy";
|
||||
import { Gender } from "@/data";
|
||||
import { genders } from "@/components/pages/ABDesign/v1/data/genders";
|
||||
import Answer from "@/components/CompatibilityV2/components/Answer";
|
||||
import AlreadyHaveAccount from "@/components/ui/AlreadyHaveAccount";
|
||||
|
||||
interface IGenderV0Props {
|
||||
localGenders: Array<{
|
||||
id: string;
|
||||
title: React.ReactNode | string;
|
||||
}>;
|
||||
gender: string;
|
||||
selectGender: (gender: Gender | null) => void;
|
||||
}
|
||||
|
||||
function GenderV0({ localGenders, gender, selectGender }: IGenderV0Props) {
|
||||
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Title variant="h2" className={styles.title}>
|
||||
{translate("/gender.title")}
|
||||
</Title>
|
||||
<p className={styles.description}>{translate("/gender.description", {
|
||||
br: <br />,
|
||||
})}</p>
|
||||
{/* <ChooseGender onSelectGender={selectGender} /> */}
|
||||
<PrivacyPolicy containerClassName={styles["privacy-policy"]} haveCheckbox={false} />
|
||||
<div className={styles["genders-container"]}>
|
||||
{localGenders.map((_gender, index) => (
|
||||
<Answer
|
||||
key={index}
|
||||
answer={_gender}
|
||||
isSelected={gender === _gender.id}
|
||||
onClick={() => selectGender(genders.find((g) => g.id === _gender.id) ?? null)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<AlreadyHaveAccount text={translate("/gender.already_have_account")} />
|
||||
{/* {gender && !privacyPolicyChecked && (
|
||||
<Toast classNameContainer={styles["toast-container"]} variant="error">
|
||||
{translate("/gender.toast", undefined, ELocalesPlacement.V1)}
|
||||
</Toast>
|
||||
)} */}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default GenderV0
|
||||
@ -0,0 +1,62 @@
|
||||
import Title from "@/components/Title"
|
||||
import styles from "../../styles.module.scss"
|
||||
import { useTranslations } from "@/hooks/translations";
|
||||
import { ELocalesPlacement } from "@/locales";
|
||||
import PrivacyPolicy from "@/components/pages/ABDesign/v1/components/PrivacyPolicy";
|
||||
import { Gender } from "@/data";
|
||||
import { genders } from "@/components/pages/ABDesign/v1/data/genders";
|
||||
import Answer from "@/components/CompatibilityV2/components/Answer";
|
||||
import AlreadyHaveAccount from "@/components/ui/AlreadyHaveAccount";
|
||||
|
||||
interface IGenderV1Props {
|
||||
localGenders: Array<{
|
||||
id: string;
|
||||
title: React.ReactNode | string;
|
||||
}>;
|
||||
gender: string;
|
||||
selectGender: (gender: Gender | null) => void;
|
||||
}
|
||||
|
||||
function GenderV1({ localGenders, gender, selectGender }: IGenderV1Props) {
|
||||
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Title variant="h2" className={styles.title}>
|
||||
{translate("/gender.v1.title", {
|
||||
br: <br />,
|
||||
})}
|
||||
</Title>
|
||||
<p className={styles.subtitle}>{translate("/gender.v1.subtitle", {
|
||||
br: <br />,
|
||||
})}</p>
|
||||
<ul className={styles.points}>
|
||||
{Array.from({ length: 4 }).map((_, index) => (
|
||||
<li key={index}>
|
||||
{translate(`/gender.v1.points.point${index + 1}`)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{/* <ChooseGender onSelectGender={selectGender} /> */}
|
||||
<div className={styles["genders-container"]}>
|
||||
{localGenders.map((_gender, index) => (
|
||||
<Answer
|
||||
key={index}
|
||||
answer={_gender}
|
||||
isSelected={gender === _gender.id}
|
||||
onClick={() => selectGender(genders.find((g) => g.id === _gender.id) ?? null)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<PrivacyPolicy containerClassName={styles["privacy-policy"]} haveCheckbox={false} />
|
||||
<AlreadyHaveAccount text={translate("/gender.already_have_account")} />
|
||||
{/* {gender && !privacyPolicyChecked && (
|
||||
<Toast classNameContainer={styles["toast-container"]} variant="error">
|
||||
{translate("/gender.toast", undefined, ELocalesPlacement.V1)}
|
||||
</Toast>
|
||||
)} */}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default GenderV1
|
||||
@ -0,0 +1,67 @@
|
||||
import Title from "@/components/Title"
|
||||
import styles from "../../styles.module.scss"
|
||||
import { useTranslations } from "@/hooks/translations";
|
||||
import { ELocalesPlacement } from "@/locales";
|
||||
import PrivacyPolicy from "@/components/pages/ABDesign/v1/components/PrivacyPolicy";
|
||||
import { Gender } from "@/data";
|
||||
import { genders } from "@/components/pages/ABDesign/v1/data/genders";
|
||||
import Answer from "@/components/CompatibilityV2/components/Answer";
|
||||
import AlreadyHaveAccount from "@/components/ui/AlreadyHaveAccount";
|
||||
|
||||
interface IGenderV2Props {
|
||||
localGenders: Array<{
|
||||
id: string;
|
||||
title: React.ReactNode | string;
|
||||
}>;
|
||||
gender: string;
|
||||
selectGender: (gender: Gender | null) => void;
|
||||
}
|
||||
|
||||
function GenderV2({ localGenders, gender, selectGender }: IGenderV2Props) {
|
||||
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Title variant="h2" className={styles.title}>
|
||||
{translate("/gender.v2.title", {
|
||||
br: <br />,
|
||||
})}
|
||||
</Title>
|
||||
<ul className={styles.points}>
|
||||
{Array.from({ length: 5 }).map((_, index) => (
|
||||
<li key={index}>
|
||||
{translate(`/gender.v2.points.point${index + 1}`)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<p
|
||||
className={styles.subtitle}
|
||||
style={{
|
||||
marginTop: "28px",
|
||||
}}
|
||||
>{translate("/gender.v2.subtitle", {
|
||||
br: <br />,
|
||||
})}</p>
|
||||
{/* <ChooseGender onSelectGender={selectGender} /> */}
|
||||
<div className={styles["genders-container"]}>
|
||||
{localGenders.map((_gender, index) => (
|
||||
<Answer
|
||||
key={index}
|
||||
answer={_gender}
|
||||
isSelected={gender === _gender.id}
|
||||
onClick={() => selectGender(genders.find((g) => g.id === _gender.id) ?? null)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<PrivacyPolicy containerClassName={styles["privacy-policy"]} haveCheckbox={false} />
|
||||
<AlreadyHaveAccount text={translate("/gender.already_have_account")} />
|
||||
{/* {gender && !privacyPolicyChecked && (
|
||||
<Toast classNameContainer={styles["toast-container"]} variant="error">
|
||||
{translate("/gender.toast", undefined, ELocalesPlacement.V1)}
|
||||
</Toast>
|
||||
)} */}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default GenderV2
|
||||
@ -12,6 +12,8 @@ import { selectors } from "@/store";
|
||||
import { useSelector } from "react-redux";
|
||||
import { images } from "../../data";
|
||||
import { getZodiacSignByDate } from "@/services/zodiac-sign";
|
||||
import { EUnleashFlags, useUnleash } from "@/hooks/ab/unleash/useUnleash";
|
||||
import Loader, { LoaderColor } from "@/components/Loader";
|
||||
|
||||
function PalmsInformation() {
|
||||
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
|
||||
@ -24,10 +26,18 @@ function PalmsInformation() {
|
||||
preloadKey: ELottieKeys.scalesHeadPalmistry,
|
||||
});
|
||||
|
||||
const { isReady, variant: zodiacImages } = useUnleash({
|
||||
flag: EUnleashFlags.zodiacImages
|
||||
});
|
||||
|
||||
const handleNext = () => {
|
||||
navigate(routes.client.compatibilityV2RelationshipStatus());
|
||||
};
|
||||
|
||||
if (!isReady) {
|
||||
return <Loader color={LoaderColor.Black} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles["page-container"]}>
|
||||
{/* {animationData && (
|
||||
@ -39,13 +49,25 @@ function PalmsInformation() {
|
||||
width={1920}
|
||||
/>
|
||||
)} */}
|
||||
<div className={styles.zodiac}>
|
||||
<img
|
||||
className={styles.image}
|
||||
src={images(`zodiacs/${gender}/${zodiacSign.toUpperCase()}.webp`)}
|
||||
alt="Zodiac sign"
|
||||
/>
|
||||
</div>
|
||||
{zodiacImages !== "new" && (
|
||||
<div className={styles.zodiac}>
|
||||
<img
|
||||
className={styles.image}
|
||||
src={images(`zodiacs/${gender}/${zodiacSign.toUpperCase()}.webp`)}
|
||||
alt="Zodiac sign"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{zodiacImages === "new" && (
|
||||
<div className={styles.zodiacNew}>
|
||||
<img
|
||||
className={styles.image}
|
||||
// src={images(`zodiacs/${gender}/${zodiacSign.toUpperCase()}.webp`)}
|
||||
src={`/zodiac-signs/${gender?.toLowerCase()}/${zodiacSign.toLowerCase()}.svg`}
|
||||
alt="Zodiac sign"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<Title variant="h2" className={styles.title}>
|
||||
{translate(`/palms-information.${zodiacSign.toLowerCase()}.title`)}
|
||||
</Title>
|
||||
|
||||
@ -56,4 +56,19 @@
|
||||
.description {
|
||||
white-space: pre-line;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.zodiacNew {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
& > img {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
max-width: 260px;
|
||||
z-index: -2;
|
||||
}
|
||||
}
|
||||
@ -11,11 +11,13 @@ import { selectors } from "@/store";
|
||||
import { useSelector } from "react-redux";
|
||||
import { images } from "../../data";
|
||||
import { getZodiacSignByDate } from "@/services/zodiac-sign";
|
||||
import { EUnleashFlags, useUnleash } from "@/hooks/ab/unleash/useUnleash";
|
||||
import Loader, { LoaderColor } from "@/components/Loader";
|
||||
|
||||
function PalmsInformationPartner() {
|
||||
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
|
||||
const { partnerGender, partnerBirthdate } = useSelector(selectors.selectQuestionnaire);
|
||||
|
||||
|
||||
const zodiacSign = getZodiacSignByDate(partnerBirthdate);
|
||||
const navigate = useNavigate();
|
||||
// const { animationData } =
|
||||
@ -24,10 +26,18 @@ function PalmsInformationPartner() {
|
||||
preloadKey: ELottieKeys.scalesHeadPalmistry,
|
||||
});
|
||||
|
||||
const { isReady, variant: zodiacImages } = useUnleash({
|
||||
flag: EUnleashFlags.zodiacImages
|
||||
});
|
||||
|
||||
const handleNext = () => {
|
||||
navigate(routes.client.compatibilityV2DateEvent());
|
||||
};
|
||||
|
||||
if (!isReady) {
|
||||
return <Loader color={LoaderColor.Black} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles["page-container"]}>
|
||||
{/* {animationData && (
|
||||
@ -39,13 +49,25 @@ function PalmsInformationPartner() {
|
||||
width={1920}
|
||||
/>
|
||||
)} */}
|
||||
<div className={styles.zodiac}>
|
||||
<img
|
||||
className={styles.image}
|
||||
src={images(`zodiacs/${partnerGender}/${zodiacSign?.toUpperCase()}.webp`)}
|
||||
alt="Zodiac sign"
|
||||
/>
|
||||
</div>
|
||||
{zodiacImages !== "new" && (
|
||||
<div className={styles.zodiac}>
|
||||
<img
|
||||
className={styles.image}
|
||||
src={images(`zodiacs/${partnerGender}/${zodiacSign.toUpperCase()}.webp`)}
|
||||
alt="Zodiac sign"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{zodiacImages === "new" && (
|
||||
<div className={styles.zodiacNew}>
|
||||
<img
|
||||
className={styles.image}
|
||||
// src={images(`zodiacs/${gender}/${zodiacSign.toUpperCase()}.webp`)}
|
||||
src={`/zodiac-signs/${partnerGender?.toLowerCase()}/${zodiacSign.toLowerCase()}.svg`}
|
||||
alt="Zodiac sign"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<Title variant="h2" className={styles.title}>
|
||||
{translate(`/palms-information-partner.${zodiacSign?.toLowerCase()}.title`)}
|
||||
</Title>
|
||||
|
||||
@ -56,4 +56,19 @@
|
||||
.description {
|
||||
white-space: pre-line;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.zodiacNew {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
& > img {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
max-width: 260px;
|
||||
z-index: -2;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
import styles from "./styles.module.scss"
|
||||
|
||||
interface ZodiacImagesProps {
|
||||
gender: string;
|
||||
partnerGender?: string;
|
||||
zodiacSign: string;
|
||||
partnerZodiacSign?: string;
|
||||
relationshipStatus: string;
|
||||
classNameContainer?: string;
|
||||
}
|
||||
|
||||
function ZodiacImages({
|
||||
gender,
|
||||
partnerGender,
|
||||
zodiacSign,
|
||||
partnerZodiacSign,
|
||||
relationshipStatus,
|
||||
classNameContainer = ""
|
||||
}: ZodiacImagesProps) {
|
||||
|
||||
const getZodiacImagesWithPartnerClassName = () => {
|
||||
if (relationshipStatus === "single") {
|
||||
return "";
|
||||
}
|
||||
return `${styles["with-partner"]} ${styles[`with-partner-${gender}-${partnerGender}`]}`;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`${styles["zodiac-images"]} ${getZodiacImagesWithPartnerClassName()} ${classNameContainer}`}
|
||||
// style={{ marginBottom: `${-height / 2}px` }}
|
||||
>
|
||||
<img src={`/zodiac-signs/${gender?.toLowerCase()}/${zodiacSign?.toLowerCase()}.svg`} alt="Profile zodiac sign" />
|
||||
{relationshipStatus !== "single" && <img src={`/zodiac-signs/${partnerGender?.toLowerCase()}/${partnerZodiacSign?.toLowerCase()}.svg`} alt="Partner zodiac sign" />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ZodiacImages
|
||||
@ -0,0 +1,66 @@
|
||||
.zodiac-images {
|
||||
position: relative;
|
||||
width: 100dvw;
|
||||
max-width: 560px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 0px;
|
||||
margin-top: 8px;
|
||||
|
||||
&.with-partner {
|
||||
// &>img:first-child {
|
||||
// margin-right: -30%;
|
||||
// }
|
||||
|
||||
&>img:last-child {
|
||||
// margin-left: -10px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
&>img {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
position: relative;
|
||||
width: 70%;
|
||||
object-fit: cover;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
&.with-partner-male-female {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
&.with-partner-male-male {
|
||||
&>img:first-child {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
}
|
||||
|
||||
&.with-partner-female-female {
|
||||
&>img:last-child {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
}
|
||||
|
||||
// &::after {
|
||||
// content: "";
|
||||
// position: absolute;
|
||||
// bottom: 0;
|
||||
// left: 0;
|
||||
// width: 100%;
|
||||
// height: 60%;
|
||||
// background: linear-gradient(to bottom,
|
||||
// rgba(255, 255, 255, 0) 0%,
|
||||
// rgba(255, 255, 255, .7) 10%,
|
||||
// rgba(255, 255, 255, 1) 15%,
|
||||
// rgba(255, 255, 255, 1) 30%,
|
||||
// rgba(255, 255, 255, 1) 40%,
|
||||
// rgba(255, 255, 255, 1) 100%);
|
||||
// pointer-events: none;
|
||||
// z-index: -1;
|
||||
// }
|
||||
}
|
||||
@ -24,6 +24,9 @@ import { formatDateToLocale } from "@/locales/localFormats";
|
||||
import { useEffect } from "react";
|
||||
import metricService, { EGoals, EMetrics } from "@/services/metric/metricService";
|
||||
import MoneyBackGuarantee from "../../components/MoneyBackGuarantee";
|
||||
import ZodiacImages from "./components/ZodiacImages";
|
||||
import { EUnleashFlags, useUnleash } from "@/hooks/ab/unleash/useUnleash";
|
||||
import Loader, { LoaderColor } from "@/components/Loader";
|
||||
|
||||
function TrialPayment() {
|
||||
const { height, elementRef } = useDynamicSize<HTMLDivElement>({});
|
||||
@ -41,6 +44,10 @@ function TrialPayment() {
|
||||
"/v1/palmistry/ticket.svg",
|
||||
])
|
||||
|
||||
const { isReady, variant: zodiacImages } = useUnleash({
|
||||
flag: EUnleashFlags.zodiacImages
|
||||
});
|
||||
|
||||
const handleNext = () => {
|
||||
navigate(routes.client.compatibilityV2Payment());
|
||||
};
|
||||
@ -50,19 +57,31 @@ function TrialPayment() {
|
||||
metricService.reachGoal(EGoals.AURA_TRIAL_PAYMENT_PAGE_VISIT, [EMetrics.KLAVIYO]);
|
||||
}, []);
|
||||
|
||||
if (!isReady) {
|
||||
return <Loader color={LoaderColor.Black} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Title className={styles["information-title"]}>
|
||||
{translate("/trial-payment.information-title")}
|
||||
</Title>
|
||||
<div
|
||||
|
||||
{zodiacImages === "new" && <ZodiacImages
|
||||
gender={gender}
|
||||
zodiacSign={zodiacSign}
|
||||
relationshipStatus={relationshipStatus}
|
||||
partnerGender={partnerGender}
|
||||
partnerZodiacSign={partnerZodiacSign}
|
||||
/>}
|
||||
{zodiacImages !== "new" && <div
|
||||
className={`${styles["zodiac-images"]} ${relationshipStatus !== "single" ? styles["with-partner"] : ""}`}
|
||||
ref={elementRef}
|
||||
style={{ marginBottom: `${-height / 2}px` }}
|
||||
>
|
||||
<img src={images(`zodiacs/${gender}/${zodiacSign?.toUpperCase()}.webp`)} alt="Profile zodiac sign" />
|
||||
{relationshipStatus !== "single" && <img src={images(`zodiacs/${partnerGender}/${partnerZodiacSign?.toUpperCase()}.webp`)} alt="Partner zodiac sign" />}
|
||||
</div>
|
||||
</div>}
|
||||
{(relationshipStatus === "single" || !partnerBirthdate) &&
|
||||
<p className={styles["information-description"]}>
|
||||
{translate("/trial-payment.information-description-single", {
|
||||
|
||||
@ -1,25 +1,51 @@
|
||||
import { useFlagsStatus, useUnleashClient, useVariant } from "@unleash/proxy-client-react";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
|
||||
interface IUseUnleashProps {
|
||||
flag: string;
|
||||
export enum EUnleashFlags {
|
||||
"genderPageType" = "genderPageType",
|
||||
"zodiacImages" = "zodiacImages",
|
||||
}
|
||||
|
||||
export const useUnleash = ({
|
||||
/**
|
||||
* Интерфейс для входных параметров хука useUnleash
|
||||
* Использует дженерик T для типизации флага
|
||||
*/
|
||||
interface IUseUnleashProps<T extends EUnleashFlags> {
|
||||
flag: T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Интерфейс для возможных вариантов значений флагов
|
||||
* Каждый ключ соответствует флагу из EUnleashFlags
|
||||
*/
|
||||
interface IVariants {
|
||||
[EUnleashFlags.genderPageType]: "v0" | "v1" | "v2";
|
||||
[EUnleashFlags.zodiacImages]: "new" | "old";
|
||||
}
|
||||
|
||||
/**
|
||||
* Хук для получения значения A/B теста по флагу
|
||||
* @template T - Тип флага из EUnleashFlags
|
||||
* @returns Объект с информацией о готовности флага и его значении, типизированным в зависимости от переданного флага
|
||||
*/
|
||||
export const useUnleash = <T extends EUnleashFlags>({
|
||||
flag
|
||||
}: IUseUnleashProps) => {
|
||||
}: IUseUnleashProps<T>) => {
|
||||
const { flagsReady } = useFlagsStatus();
|
||||
const unleashClient = useUnleashClient();
|
||||
const abVariant = useVariant(flag);
|
||||
// const isEnabled = useFlag(flag);
|
||||
const [searchParams] = useSearchParams();
|
||||
const variantFromParams = searchParams.get(flag);
|
||||
|
||||
const isReady = useMemo(() => {
|
||||
return flagsReady ?? true;
|
||||
}, [flagsReady]);
|
||||
|
||||
const variant = useMemo(() => {
|
||||
return abVariant?.payload?.value;
|
||||
}, [abVariant]);
|
||||
return variantFromParams || abVariant?.payload?.value;
|
||||
}, [abVariant, variantFromParams]) as IVariants[T];
|
||||
|
||||
useEffect(() => {
|
||||
unleashClient.on("impression", (impressionEvent: any) => {
|
||||
@ -43,5 +69,5 @@ export const useUnleash = ({
|
||||
}), [
|
||||
isReady,
|
||||
variant
|
||||
])
|
||||
]) as { isReady: boolean; variant: IVariants[T] };
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user