diff --git a/public/locales/compatibility-v2/en/male_en.json b/public/locales/compatibility-v2/en/male_en.json index 9713a59..b8569ad 100644 --- a/public/locales/compatibility-v2/en/male_en.json +++ b/public/locales/compatibility-v2/en/male_en.json @@ -93,6 +93,19 @@ } } }, + "/compatibility-test": { + "title": "Тест на Совместимость", + "subtitle": "Всё начинается с вас! Выберите ваш пол.", + "points": { + "point1": "Тест займмет не более 1 мин.", + "point2": "Ты получишь разбор совместимости.", + "point3": "Решишь проблемы в отношениях за месяц.", + "point4": "Сэкономишь сотни долларов на ненадёжных прогнозах.", + "point5": "Получишь персональный анализ." + }, + "already_have_account": "Уже есть аккаунт? Войти", + "button": "Начать" + }, "/birthdate": { "title": "When Were You Born?", "text": "Your birth date can reveal strengths and values that may help you move forward" @@ -159,7 +172,71 @@ "answer1": "Single", "answer2": "In a Relationship", "answer3": "Married", - "answer4": "Divorced" + "answer4": "Divorced", + "v1": { + "title": "Чтобы яснее разобрать вашу суть, укажите какие у вас отношения сейчас?", + "answer1": "Single", + "answer2": "Начало", + "answer3": "Долгие отношения", + "answer4": "Развиваются непонятно куда", + "answer5": "Разрыв/кризис" + } + }, + "/relationship-status-result": { + "start": { + "title": "How can you really tell if your partner is the right one—and avoid making a mistake?", + "text": "Understanding your partner’s emotions is the key to a harmonious relationship. Our system predicts compatibility with up to 98% accuracy, giving you clear, detailed reports." + }, + "in_relationship": { + "title": "Love is important, but why isn’t love alone enough for a happy, lasting relationship?", + "text": "Daily life can either strengthen your relationship or create tension if your ideas of comfort and care don’t match. Our system predicts compatibility with up to 98% accuracy, helping you understand how long-lasting and harmonious your partnership can be." + }, + "developing": { + "title": "Feel like your partner just doesn’t get you? It’s not by chance—it’s about differences in your natal patterns.", + "text": "Closeness isn’t just about attraction—it’s about understanding each other’s wants and emotions. Our data from 2 million people backs this up, and we know how to help." + }, + "crisis": { + "title": "Why do some couples split up quickly, while others stay together for years?", + "text": "A shared future isn’t just about dreams—it’s about common goals, values, and everyday effort. Our system predicts compatibility with up to 98% accuracy. We’ll show you, step by step, how to build a strong relationship." + }, + "single": { + "title": "Does it feel like there are no worthy partners out there, or you keep ending up with the wrong people? It all comes down to incompatible choices.", + "text": "Our system predicts compatibility with up to 98% accuracy, helping you find the right partner and opening up new possibilities in your personal life." + } + }, + "/fear-in-relationship": { + "title": "Чего вы боитесь больше всего в отношениях?", + "answer1": "Потратить жизнь не на того", + "answer2": "Остаться одиноким", + "answer3": "Пропустить свою судьбу", + "answer4": "Любовь без уважения и поддержки", + "answer5": "Не узнать правду о совместимости" + }, + "/important-step": { + "title": "Ты сделал важный шаг!", + "text": "Обозначил свой главный страх в отношениях. Это шаг к тому, чтобы больше не терять время. Мы поможем избежать все ошибки." + }, + "/who-matter": { + "title": "О ком вы думаете, строя отношения?", + "answer1": "О себе", + "answer2": "О детях", + "answer3": "О семье" + }, + "/your-priority": { + "title": "Что сейчас для вас в приоритете?", + "answer1": "Внутренняя гармония", + "answer2": "Надёжные отношения", + "answer3": "Новые впечатления" + }, + "/personalized-relationship-analysis": { + "single": { + "title": "Что такое персонализированный анализ отношений?", + "text": "У вас свои сильные стороны, ожидания и трудности. Мы создаём персональный портрет, чтобы помочь вам лучше понять себя и свои истинные потребности в отношениях.

Мы анализируем ваши ответы и показываем, что мешало вам раньше, а что наоборот поможет встретить именно «своего» человека и построить счастливую любовь." + }, + "relationship": { + "title": "Что такое персонализированный анализ отношений?", + "text": "Каждая пара уникальна. У вас свои сильные стороны и свои трудности. Мы создаём персональный портрет отношений, чтобы помочь укрепить доверие, гармонию и близость именно в вашей паре.

Мы анализируем ваши ответы и показываем, что мешает вашей любви, а что наоборот поможет сделать её глубже и счастливее." + } }, "/element-resonates": { "title": "Which Element Empowers You the Most?", diff --git a/public/locales/compatibility-v2/ru/male_ru.json b/public/locales/compatibility-v2/ru/male_ru.json index 8044170..bd84310 100644 --- a/public/locales/compatibility-v2/ru/male_ru.json +++ b/public/locales/compatibility-v2/ru/male_ru.json @@ -56,6 +56,18 @@ } } }, + "/compatibility-test": { + "title": "Тест на Совместимость", + "subtitle": "Всё начинается с вас! Выберите ваш пол.", + "points": { + "point1": "Тест займмет не более 1 мин.", + "point2": "Ты получишь разбор совместимости по хиромантическому анализу линий на твоей ладони.", + "point3": "Решишь проблемы в отношениях за месяц.", + "point4": "Сэкономишь сотни долларов на ненадёжных прогнозах.", + "point5": "Получишь персональный анализ." + }, + "already_have_account": "Уже есть аккаунт? Войти" + }, "/birthdate": { "title": "Когда вы родились?", "text": "Ваша дата рождения может раскрыть сильные стороны и ценности, которые помогут вам двигаться вперёд." diff --git a/public/v2/compatibility/review/like_1.png b/public/v2/compatibility/review/like_1.png new file mode 100644 index 0000000..d586236 Binary files /dev/null and b/public/v2/compatibility/review/like_1.png differ diff --git a/public/v2/compatibility/review/like_2.png b/public/v2/compatibility/review/like_2.png new file mode 100644 index 0000000..34636fa Binary files /dev/null and b/public/v2/compatibility/review/like_2.png differ diff --git a/public/v2/compatibility/review/like_3.png b/public/v2/compatibility/review/like_3.png index 7d7a073..a2af948 100644 Binary files a/public/v2/compatibility/review/like_3.png and b/public/v2/compatibility/review/like_3.png differ diff --git a/src/api/resources/Session.ts b/src/api/resources/Session.ts index 5707e8b..77e7af5 100644 --- a/src/api/resources/Session.ts +++ b/src/api/resources/Session.ts @@ -44,7 +44,7 @@ export interface IAnswersSessionPalmistry { export interface IAnswersSessionCompatibilityV2 { what_aspects: 'love_relationships' | 'health_vitality' | 'career_destiny' | 'life_transitions', // Type: string, optional - 'love_relationships' | 'health_vitality' | 'career_destiny'; - relationship_status: 'single' | 'in_relationship' | 'engaged' | 'divorced' | 'complicated', // Type: string, optional - 'single' | 'in_relationship'; + relationship_status: 'single' | 'in_relationship' | 'engaged' | 'divorced' | 'complicated' | 'start' | 'developing' | 'crisis', // Type: string, optional - 'single' | 'in_relationship'; element_resonates: 'water' | 'fire' | 'air' | 'earth' | 'light' | 'darkness', // Type: string, optional - 'water' | 'fire' | 'air' | 'earth'; favorite_color: 'blue' | 'green' | 'orange' | 'violet' | 'red' | 'yellow' | 'turquoise', // Type: string, optional - 'blue' | 'green' | 'orange' | 'violet' | 'red' | 'yellow'; head_or_heart: 'head' | 'heart' | 'both' | 'depends', // Type: string, optional - 'head' | 'heart' | 'both'; @@ -57,6 +57,9 @@ export interface IAnswersSessionCompatibilityV2 { partner_expectations: 1 | 2 | 3 | 4 | 5; // Type: number, optional - 1 | 2 | 3 | 4 | 5; romantic_gestures: "love" | "neutral" | "dislike"; // Type: string, optional - "love" | "neutral" | "dislike"; checking_phone: "against" | "allow" | "normally"; // Type: string, optional - "against" | "allow" | "normally"; + fear_in_relationship: "wasting_life_for_wrong_person" | "stay_single" | "skip_destiny" | "love_without_respect_and_support" | "not_find_truth_about_compatibility"; + who_matter: "me" | "kids" | "family"; + your_priority: "inner_harmony" | "reliable_relationship" | "new_impressions"; } export interface IAnswersSessionCompatibilityV3 { diff --git a/src/components/CompatibilityV2/components/Answer/styles.module.scss b/src/components/CompatibilityV2/components/Answer/styles.module.scss index 4f93222..9f3c913 100644 --- a/src/components/CompatibilityV2/components/Answer/styles.module.scss +++ b/src/components/CompatibilityV2/components/Answer/styles.module.scss @@ -1,6 +1,7 @@ .container { width: 100%; - height: 71px; + // height: 71px; + padding: 25px 16px; border-radius: 20px; display: flex; align-items: center; diff --git a/src/components/CompatibilityV2/components/Review2/styles.module.scss b/src/components/CompatibilityV2/components/Review2/styles.module.scss index 852a98b..b2c6586 100644 --- a/src/components/CompatibilityV2/components/Review2/styles.module.scss +++ b/src/components/CompatibilityV2/components/Review2/styles.module.scss @@ -93,7 +93,7 @@ & > .likesImages { display: flex; flex-direction: row; - margin-left: 4px; + margin-left: 8px; & > .likesImage { width: 28px; @@ -102,8 +102,8 @@ background-size: cover; background-position: center; background-repeat: no-repeat; - border: 2px solid rgba(255, 255, 255, 1); - margin-left: -4px; + // border: 2px solid rgba(255, 255, 255, 1); + margin-left: -8px; } } } diff --git a/src/components/CompatibilityV2/pages/CompatibilityTest/index.tsx b/src/components/CompatibilityV2/pages/CompatibilityTest/index.tsx new file mode 100644 index 0000000..4ee9920 --- /dev/null +++ b/src/components/CompatibilityV2/pages/CompatibilityTest/index.tsx @@ -0,0 +1,57 @@ +import { useTranslations } from "@/hooks/translations"; +import styles from "./styles.module.scss"; +import { ELocalesPlacement } from "@/locales"; + +import Title from "@/components/Title"; +import PrivacyPolicy from "@/components/pages/ABDesign/v1/components/PrivacyPolicy"; +import Button from "../../components/Button"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; + +function CompatibilityTestPage() { + const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2); + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.compatibilityV2RelationshipStatus()); + }; + + return ( +
+ + {translate("/compatibility-test.title", { + br: <br />, + })} + + + {/* */} + {/*
+ {localGenders.map((_gender, index) => ( + + selectGender(genders.find((g) => g.id === _gender.id) ?? null) + } + /> + ))} +
*/} + + +
+ ); +} + +export default CompatibilityTestPage; diff --git a/src/components/CompatibilityV2/pages/CompatibilityTest/styles.module.scss b/src/components/CompatibilityV2/pages/CompatibilityTest/styles.module.scss new file mode 100644 index 0000000..5cb6645 --- /dev/null +++ b/src/components/CompatibilityV2/pages/CompatibilityTest/styles.module.scss @@ -0,0 +1,53 @@ +.container { + position: relative; + min-height: calc(100dvh - 110px); + display: flex; + flex-direction: column; + align-items: center; +} + +.title { + margin-top: 18px; + font-size: 28px; + font-weight: 500; + line-height: 125%; + margin-bottom: 0; +} + +.privacy-policy { + max-width: 316px; + text-align: center; + position: sticky; + margin-top: auto; +} + +.points { + margin-top: 46px; + color: #2c2c2c; + list-style-type: disc; + + li { + font-size: 20px; + line-height: 125%; + font-weight: 300; + margin-left: 28px; + + &::marker { + font-size: 14px; + } + } +} + +.button.button { + background: rgba(37, 99, 235, 1); + box-shadow: 2px 5px 2.5px -1px rgba(0, 0, 0, 0.2); + border-radius: 20px; + margin-top: 64px; + margin-bottom: 26px; +} + +:global(body.dark-theme) { + .points { + color: #f7f7f7; + } +} diff --git a/src/components/CompatibilityV2/pages/FearInRelationship/index.tsx b/src/components/CompatibilityV2/pages/FearInRelationship/index.tsx new file mode 100644 index 0000000..a589496 --- /dev/null +++ b/src/components/CompatibilityV2/pages/FearInRelationship/index.tsx @@ -0,0 +1,89 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.scss"; +import { useTranslations } from "@/hooks/translations"; +import { ELocalesPlacement } from "@/locales"; +import { IAnswersSessionCompatibilityV2 } from "@/api/resources/Session"; +import { useMemo } from "react"; +import Answer from "../../components/Answer"; +import { useSelector } from "react-redux"; +import { actions, selectors } from "@/store"; +import { useDispatch } from "react-redux"; +import { useSession } from "@/hooks/session/useSession"; +import { ESourceAuthorization } from "@/api/resources/User"; +import routes from "@/routes"; +import { useNavigate } from "react-router-dom"; +import { sleep } from "@/services/date"; +import { answerTimeOut } from "../../data"; + +function FearInRelationship() { + const navigate = useNavigate(); + const dispatch = useDispatch(); + const { updateSession } = useSession(); + const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2); + const { fearInRelationship } = useSelector( + selectors.selectCompatibilityV2Answers + ); + + const answers: { + id: IAnswersSessionCompatibilityV2["fear_in_relationship"]; + title: string; + }[] = useMemo( + () => [ + { + id: "wasting_life_for_wrong_person", + title: translate("/fear-in-relationship.answer1"), + }, + { + id: "stay_single", + title: translate("/fear-in-relationship.answer2"), + }, + { + id: "skip_destiny", + title: translate("/fear-in-relationship.answer3"), + }, + { + id: "love_without_respect_and_support", + title: translate("/fear-in-relationship.answer4"), + }, + { + id: "not_find_truth_about_compatibility", + title: translate("/fear-in-relationship.answer5"), + }, + ], + [translate] + ); + + const handleClick = async ( + id: IAnswersSessionCompatibilityV2["fear_in_relationship"] + ) => { + dispatch(actions.compatibilityV2Answers.update({ fearInRelationship: id })); + updateSession( + { + answers: { + fear_in_relationship: id, + }, + }, + ESourceAuthorization["aura.compatibility.v2"] + ); + if (id !== fearInRelationship) await sleep(answerTimeOut); + navigate(routes.client.compatibilityV2ImportantStep()); + }; + + return ( +
+ + {translate("/fear-in-relationship.title")} + + {answers.map((answers, index) => ( + handleClick(answers.id)} + /> + ))} +
+ ); +} + +export default FearInRelationship; diff --git a/src/components/CompatibilityV2/pages/FearInRelationship/styles.module.scss b/src/components/CompatibilityV2/pages/FearInRelationship/styles.module.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/components/CompatibilityV2/pages/Gender/index.tsx b/src/components/CompatibilityV2/pages/Gender/index.tsx index c2e95bc..6ec24ef 100644 --- a/src/components/CompatibilityV2/pages/Gender/index.tsx +++ b/src/components/CompatibilityV2/pages/Gender/index.tsx @@ -54,6 +54,10 @@ function GenderPage() { flag: EUnleashFlags.v2CompatibilityReviewPage, }); + const { variant: pathToEnteringBirthdate = "hide" } = useUnleash({ + flag: EUnleashFlags.v2CompatibilityPathToEnteringBirthdate, + }); + const pageType = flags?.genderPageType?.[0] || genderPageType || "v2"; const genderButtonIcon = flags?.genderButtonIcon?.[0] || "hide"; @@ -115,12 +119,24 @@ function GenderPage() { if (relationshipStatusPagePlacement === "v2") { return navigate(routes.client.compatibilityV2RelationshipStatus()); } + console.log(reviewPage); + if (reviewPage === "show") { return navigate(routes.client.compatibilityV2Review()); } + if (pathToEnteringBirthdate === "show") { + return navigate(routes.client.compatibilityV2CompatibilityTest()); + } return navigate(routes.client.compatibilityV2Birthdate()); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [gender, navigate]); + }, [ + gender, + navigate, + reviewPage, + pathToEnteringBirthdate, + relationshipStatusPagePlacement, + isReady, + ]); useEffect(() => { if (privacyPolicyChecked && gender && isSelected) { @@ -129,6 +145,20 @@ function GenderPage() { } }, [gender, handleNext, isSelected, privacyPolicyChecked]); + // useEffect(() => { + // if (pathToEnteringBirthdate === "show" && !pathToEnteringBirthdateShown) { + // dispatch( + // actions.compatibilityV2.update({ pathToEnteringBirthdateShown: true }) + // ); + // return navigate(routes.client.compatibilityV2CompatibilityTest()); + // } + // }, [ + // dispatch, + // navigate, + // pathToEnteringBirthdate, + // pathToEnteringBirthdateShown, + // ]); + if (!ready || !isReady) return ; if (relationshipStatusPagePlacement === "v1" && !noRedirectAB) { diff --git a/src/components/CompatibilityV2/pages/ImportantStep/index.tsx b/src/components/CompatibilityV2/pages/ImportantStep/index.tsx new file mode 100644 index 0000000..cc42a51 --- /dev/null +++ b/src/components/CompatibilityV2/pages/ImportantStep/index.tsx @@ -0,0 +1,26 @@ +import { useNavigate } from "react-router-dom"; +import { useTranslations } from "@/hooks/translations"; +import { ELocalesPlacement } from "@/locales"; +import AnswerExplanation from "../../templates/AnswerExplanation"; +import routes from "@/routes"; +import styles from "./styles.module.scss"; + +function ImportantStep() { + const navigate = useNavigate(); + const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2); + + return ( + { + navigate(routes.client.compatibilityV2WhoMatter()); + }} + /> + ); +} + +export default ImportantStep; diff --git a/src/components/CompatibilityV2/pages/ImportantStep/styles.module.scss b/src/components/CompatibilityV2/pages/ImportantStep/styles.module.scss new file mode 100644 index 0000000..56c27ef --- /dev/null +++ b/src/components/CompatibilityV2/pages/ImportantStep/styles.module.scss @@ -0,0 +1,8 @@ +.title { + font-weight: 700; + margin-bottom: 62px; +} + +.text { + margin-bottom: 62px; +} diff --git a/src/components/CompatibilityV2/pages/PalmsInformation/index.tsx b/src/components/CompatibilityV2/pages/PalmsInformation/index.tsx index bcab491..ca50a6e 100644 --- a/src/components/CompatibilityV2/pages/PalmsInformation/index.tsx +++ b/src/components/CompatibilityV2/pages/PalmsInformation/index.tsx @@ -14,7 +14,10 @@ import { getZodiacSignByDate } from "@/services/zodiac-sign"; import { EUnleashFlags, useUnleash } from "@/hooks/ab/unleash/useUnleash"; import Loader, { LoaderColor } from "@/components/Loader"; import { useEffect } from "react"; -import metricService, { EGoals, EMetrics } from "@/services/metric/metricService"; +import metricService, { + EGoals, + EMetrics, +} from "@/services/metric/metricService"; function PalmsInformation() { const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2); @@ -26,33 +29,47 @@ function PalmsInformation() { }); const { isReady, variant: zodiacImages } = useUnleash({ - flag: EUnleashFlags.zodiacImages + flag: EUnleashFlags.zodiacImages, }); const { variant: relationshipStatusPagePlacement = "v0" } = useUnleash({ - flag: EUnleashFlags.v2CompatibilityRelationshipStatusPagePlacement + flag: EUnleashFlags.v2CompatibilityRelationshipStatusPagePlacement, + }); + + const { variant: pathToEnteringBirthdate = "hide" } = useUnleash({ + flag: EUnleashFlags.v2CompatibilityPathToEnteringBirthdate, }); const handleNext = () => { - if (relationshipStatusPagePlacement === "v1" || relationshipStatusPagePlacement === "v2") { + if ( + relationshipStatusPagePlacement === "v1" || + relationshipStatusPagePlacement === "v2" || + pathToEnteringBirthdate === "show" + ) { return navigate(`${routes.client.compatibilityV2RelateFollowing()}/1`); } navigate(routes.client.compatibilityV2RelationshipStatus()); }; - if (!isReady) { - return ; - } - useEffect(() => { const ua = window.navigator.userAgent; if (ua.includes("FBAN") || ua.includes("FBAV") || ua.includes("FBIOS")) { - metricService.reachGoal(EGoals.STAYED_IN_FB, [EMetrics.YANDEX, EMetrics.KLAVIYO]) + metricService.reachGoal(EGoals.STAYED_IN_FB, [ + EMetrics.YANDEX, + EMetrics.KLAVIYO, + ]); } if (ua.includes("Instagram")) { - metricService.reachGoal(EGoals.STAYED_IN_INSTAGRAM, [EMetrics.YANDEX, EMetrics.KLAVIYO]) + metricService.reachGoal(EGoals.STAYED_IN_INSTAGRAM, [ + EMetrics.YANDEX, + EMetrics.KLAVIYO, + ]); } - }, []) + }, []); + + if (!isReady) { + return ; + } return (
@@ -78,11 +95,11 @@ function PalmsInformation() { {translate(`/palms-information.${zodiacSign?.toLowerCase()}.title`)}

- {translate(`/palms-information.${zodiacSign?.toLowerCase()}.description`)} + {translate( + `/palms-information.${zodiacSign?.toLowerCase()}.description` + )}

- + {translate("privacy_policy", { eulaLink: ( diff --git a/src/components/CompatibilityV2/pages/PersonalizedRelationshipAnalysis/index.tsx b/src/components/CompatibilityV2/pages/PersonalizedRelationshipAnalysis/index.tsx new file mode 100644 index 0000000..e8b5938 --- /dev/null +++ b/src/components/CompatibilityV2/pages/PersonalizedRelationshipAnalysis/index.tsx @@ -0,0 +1,40 @@ +import styles from "./styles.module.scss"; +import AnswerExplanation from "../../templates/AnswerExplanation"; +import { useTranslations } from "@/hooks/translations"; +import { ELocalesPlacement } from "@/locales"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import { useSelector } from "react-redux"; +import { selectors } from "@/store"; +import { useMemo } from "react"; + +function PersonalizedRelationshipAnalysis() { + const navigate = useNavigate(); + const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2); + const { relationshipStatus: relationshipStatusAnswer } = useSelector( + selectors.selectCompatibilityV2Answers + ); + + const relationshipStatus = useMemo(() => { + return relationshipStatusAnswer === "single" ? "single" : "relationship"; + }, [relationshipStatusAnswer]); + + return ( + { + navigate(routes.client.compatibilityV2Birthdate()); + }} + /> + ); +} + +export default PersonalizedRelationshipAnalysis; diff --git a/src/components/CompatibilityV2/pages/PersonalizedRelationshipAnalysis/styles.module.scss b/src/components/CompatibilityV2/pages/PersonalizedRelationshipAnalysis/styles.module.scss new file mode 100644 index 0000000..8a819e1 --- /dev/null +++ b/src/components/CompatibilityV2/pages/PersonalizedRelationshipAnalysis/styles.module.scss @@ -0,0 +1,7 @@ +.title { + font-weight: 700; +} + +.text { + margin-bottom: 38px; +} diff --git a/src/components/CompatibilityV2/pages/RelationshipStatus/index.tsx b/src/components/CompatibilityV2/pages/RelationshipStatus/index.tsx index 0f4397e..29c0a9a 100644 --- a/src/components/CompatibilityV2/pages/RelationshipStatus/index.tsx +++ b/src/components/CompatibilityV2/pages/RelationshipStatus/index.tsx @@ -14,6 +14,7 @@ import { useSession } from "@/hooks/session/useSession"; import { IAnswersSessionCompatibilityV2 } from "@/api/resources/Session"; import { ESourceAuthorization } from "@/api/resources/User"; import { EUnleashFlags, useUnleash } from "@/hooks/ab/unleash/useUnleash"; +import Loader, { LoaderColor } from "@/components/Loader"; function RelationshipStatus() { const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2); @@ -25,14 +26,47 @@ function RelationshipStatus() { ); const { variant: relationshipStatusPagePlacement = "v0" } = useUnleash({ - flag: EUnleashFlags.v2CompatibilityRelationshipStatusPagePlacement + flag: EUnleashFlags.v2CompatibilityRelationshipStatusPagePlacement, }); + const { variant: pathToEnteringBirthdate = "hide", isReady } = useUnleash({ + flag: EUnleashFlags.v2CompatibilityPathToEnteringBirthdate, + }); + + const isPathToEnteringBirthdate = useMemo( + () => isReady && pathToEnteringBirthdate === "show", + [isReady, pathToEnteringBirthdate] + ); + const answers: { id: IAnswersSessionCompatibilityV2["relationship_status"]; title: string; - }[] = useMemo( - () => [ + }[] = useMemo(() => { + if (isPathToEnteringBirthdate) { + return [ + { + id: "single", + title: translate("/relationship-status.v1.answer1"), + }, + { + id: "start", + title: translate("/relationship-status.v1.answer2"), + }, + { + id: "in_relationship", + title: translate("/relationship-status.v1.answer3"), + }, + { + id: "developing", + title: translate("/relationship-status.v1.answer4"), + }, + { + id: "crisis", + title: translate("/relationship-status.v1.answer5"), + }, + ]; + } + return [ { id: "single", title: translate("/relationship-status.answer1"), @@ -53,21 +87,31 @@ function RelationshipStatus() { // id: "complicated", // title: translate("/relationship-status.answer5"), // }, - ], - [translate] - ); + ]; + }, [isPathToEnteringBirthdate, translate]); - const handleClick = async (id: IAnswersSessionCompatibilityV2["relationship_status"]) => { + const handleClick = async ( + id: IAnswersSessionCompatibilityV2["relationship_status"] + ) => { dispatch(actions.compatibilityV2Answers.update({ relationshipStatus: id })); - updateSession({ - answers: { - relationship_status: id, + updateSession( + { + answers: { + relationship_status: id, + }, }, - }, ESourceAuthorization["aura.compatibility.v2"]); + ESourceAuthorization["aura.compatibility.v2"] + ); if (id !== relationshipStatus) await sleep(answerTimeOut); + if (isPathToEnteringBirthdate) { + return navigate(routes.client.compatibilityV2RelationshipStatusResult()); + } + if (relationshipStatusPagePlacement === "v1") { - return navigate(`${routes.client.compatibilityV2Gender()}?noRedirectAB=true`); + return navigate( + `${routes.client.compatibilityV2Gender()}?noRedirectAB=true` + ); } if (relationshipStatusPagePlacement === "v2") { @@ -77,10 +121,16 @@ function RelationshipStatus() { navigate(`${routes.client.compatibilityV2RelateFollowing()}/1`); }; + if (!isReady) { + return ; + } + return (
- {translate("/relationship-status.title")} + {isPathToEnteringBirthdate + ? translate("/relationship-status.v1.title") + : translate("/relationship-status.title")} {answers.map((answers, index) => ( { + navigate(routes.client.compatibilityV2FearInRelationship()); + }} + /> + ); +} + +export default RelationshipStatusResult; diff --git a/src/components/CompatibilityV2/pages/RelationshipStatusResult/styles.module.scss b/src/components/CompatibilityV2/pages/RelationshipStatusResult/styles.module.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/components/CompatibilityV2/pages/Review/index.tsx b/src/components/CompatibilityV2/pages/Review/index.tsx index a7f1693..c468145 100644 --- a/src/components/CompatibilityV2/pages/Review/index.tsx +++ b/src/components/CompatibilityV2/pages/Review/index.tsx @@ -11,15 +11,31 @@ import { images } from "../../data"; import Button from "../../components/Button"; import { useNavigate } from "react-router-dom"; import routes from "@/routes"; +import { EUnleashFlags, useUnleash } from "@/hooks/ab/unleash/useUnleash"; +import Loader, { LoaderColor } from "@/components/Loader"; function ReviewPage() { const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2); const navigate = useNavigate(); + const { variant: pathToEnteringBirthdate = "hide", isReady } = useUnleash({ + flag: EUnleashFlags.v2CompatibilityPathToEnteringBirthdate, + }); const handleNext = () => { + if (pathToEnteringBirthdate === "show") { + return navigate(routes.client.compatibilityV2CompatibilityTest()); + } navigate(routes.client.compatibilityV2Birthdate()); }; + if (!isReady) { + return ( +
+ +
+ ); + } + return (
@@ -51,9 +67,9 @@ function ReviewPage() { verifiedText={translate("/review.review.verified_user")} likesText={translate("/review.review.likes")} likesImages={[ - "review/like_1.jpg", - "review/like_2.jpg", - "review/like_3.png", + images("review/like_1.png"), + images("review/like_2.png"), + images("review/like_3.png"), ]} image={images("review/avatar.jpg")} /> diff --git a/src/components/CompatibilityV2/pages/Review/styles.module.scss b/src/components/CompatibilityV2/pages/Review/styles.module.scss index f567429..4a5e84e 100644 --- a/src/components/CompatibilityV2/pages/Review/styles.module.scss +++ b/src/components/CompatibilityV2/pages/Review/styles.module.scss @@ -6,6 +6,10 @@ min-height: 100dvh; margin: 0 auto; padding: 45px 24px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; & * { font-family: Inter; diff --git a/src/components/CompatibilityV2/pages/WhoMatter/index.tsx b/src/components/CompatibilityV2/pages/WhoMatter/index.tsx new file mode 100644 index 0000000..d585ff0 --- /dev/null +++ b/src/components/CompatibilityV2/pages/WhoMatter/index.tsx @@ -0,0 +1,79 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.scss"; +import { useTranslations } from "@/hooks/translations"; +import { ELocalesPlacement } from "@/locales"; +import { IAnswersSessionCompatibilityV2 } from "@/api/resources/Session"; +import { useMemo } from "react"; +import Answer from "../../components/Answer"; +import { useSelector } from "react-redux"; +import { actions, selectors } from "@/store"; +import { useDispatch } from "react-redux"; +import { useSession } from "@/hooks/session/useSession"; +import { ESourceAuthorization } from "@/api/resources/User"; +import routes from "@/routes"; +import { useNavigate } from "react-router-dom"; +import { sleep } from "@/services/date"; +import { answerTimeOut } from "../../data"; + +function WhoMatter() { + const navigate = useNavigate(); + const dispatch = useDispatch(); + const { updateSession } = useSession(); + const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2); + const { whoMatter } = useSelector(selectors.selectCompatibilityV2Answers); + + const answers: { + id: IAnswersSessionCompatibilityV2["who_matter"]; + title: string; + }[] = useMemo( + () => [ + { + id: "me", + title: translate("/who-matter.answer1"), + }, + { + id: "kids", + title: translate("/who-matter.answer2"), + }, + { + id: "family", + title: translate("/who-matter.answer3"), + }, + ], + [translate] + ); + + const handleClick = async ( + id: IAnswersSessionCompatibilityV2["who_matter"] + ) => { + dispatch(actions.compatibilityV2Answers.update({ whoMatter: id })); + updateSession( + { + answers: { + who_matter: id, + }, + }, + ESourceAuthorization["aura.compatibility.v2"] + ); + if (id !== whoMatter) await sleep(answerTimeOut); + navigate(routes.client.compatibilityV2YourPriority()); + }; + + return ( + <div className={styles.container}> + <Title variant="h2" className={styles.title}> + {translate("/who-matter.title")} + + {answers.map((answers, index) => ( + handleClick(answers.id)} + /> + ))} +
+ ); +} + +export default WhoMatter; diff --git a/src/components/CompatibilityV2/pages/WhoMatter/styles.module.scss b/src/components/CompatibilityV2/pages/WhoMatter/styles.module.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/components/CompatibilityV2/pages/YourPriority/index.tsx b/src/components/CompatibilityV2/pages/YourPriority/index.tsx new file mode 100644 index 0000000..7cf1393 --- /dev/null +++ b/src/components/CompatibilityV2/pages/YourPriority/index.tsx @@ -0,0 +1,79 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.scss"; +import { useTranslations } from "@/hooks/translations"; +import { ELocalesPlacement } from "@/locales"; +import { IAnswersSessionCompatibilityV2 } from "@/api/resources/Session"; +import { useMemo } from "react"; +import Answer from "../../components/Answer"; +import { useSelector } from "react-redux"; +import { actions, selectors } from "@/store"; +import { useDispatch } from "react-redux"; +import { useSession } from "@/hooks/session/useSession"; +import { ESourceAuthorization } from "@/api/resources/User"; +import routes from "@/routes"; +import { useNavigate } from "react-router-dom"; +import { sleep } from "@/services/date"; +import { answerTimeOut } from "../../data"; + +function YourPriority() { + const navigate = useNavigate(); + const dispatch = useDispatch(); + const { updateSession } = useSession(); + const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2); + const { yourPriority } = useSelector(selectors.selectCompatibilityV2Answers); + + const answers: { + id: IAnswersSessionCompatibilityV2["your_priority"]; + title: string; + }[] = useMemo( + () => [ + { + id: "inner_harmony", + title: translate("/your-priority.answer1"), + }, + { + id: "reliable_relationship", + title: translate("/your-priority.answer2"), + }, + { + id: "new_impressions", + title: translate("/your-priority.answer3"), + }, + ], + [translate] + ); + + const handleClick = async ( + id: IAnswersSessionCompatibilityV2["your_priority"] + ) => { + dispatch(actions.compatibilityV2Answers.update({ yourPriority: id })); + updateSession( + { + answers: { + your_priority: id, + }, + }, + ESourceAuthorization["aura.compatibility.v2"] + ); + if (id !== yourPriority) await sleep(answerTimeOut); + navigate(routes.client.compatibilityV2PersonalizedRelationshipAnalysis()); + }; + + return ( +
+ + {translate("/your-priority.title")} + + {answers.map((answers, index) => ( + handleClick(answers.id)} + /> + ))} +
+ ); +} + +export default YourPriority; diff --git a/src/components/CompatibilityV2/pages/YourPriority/styles.module.scss b/src/components/CompatibilityV2/pages/YourPriority/styles.module.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/components/CompatibilityV2/templates/AnswerExplanation/index.tsx b/src/components/CompatibilityV2/templates/AnswerExplanation/index.tsx new file mode 100644 index 0000000..eb9d99c --- /dev/null +++ b/src/components/CompatibilityV2/templates/AnswerExplanation/index.tsx @@ -0,0 +1,73 @@ +import { useTranslations } from "@/hooks/translations"; +import styles from "./styles.module.scss"; +import { ELocalesPlacement } from "@/locales"; +import Title from "@/components/Title"; +import Button from "../../components/Button"; +import { useNavigate } from "react-router-dom"; + +interface IAnswerExplanation { + title?: string; + text?: string; + buttonType?: "back_next" | "next"; + classNameTitle?: string; + classNameText?: string; + handleBack?: () => void; + handleNext: () => void; +} + +function AnswerExplanation({ + title, + text, + buttonType = "back_next", + classNameTitle = "", + classNameText = "", + handleBack, + handleNext, +}: IAnswerExplanation) { + const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2); + const navigate = useNavigate(); + + const handleBackClick = () => { + return handleBack ? handleBack() : navigate(-1); + }; + + const handleNextClick = () => { + return handleNext(); + }; + + return ( +
+ {!!title?.length && ( + + {title} + + )} + {!!text?.length && ( +

{text}

+ )} + {buttonType === "back_next" && ( +
+ + +
+ )} + {buttonType === "next" && ( + + )} +
+ ); +} + +export default AnswerExplanation; diff --git a/src/components/CompatibilityV2/templates/AnswerExplanation/styles.module.scss b/src/components/CompatibilityV2/templates/AnswerExplanation/styles.module.scss new file mode 100644 index 0000000..345363d --- /dev/null +++ b/src/components/CompatibilityV2/templates/AnswerExplanation/styles.module.scss @@ -0,0 +1,44 @@ +.container { + width: 100%; +} + +.title { + font-size: 28px; + font-weight: 500; + line-height: 40px; +} + +.text { + font-size: 20px; + line-height: 25px; + text-align: center; + margin-bottom: 74px; +} + +.buttons-container { + display: flex; + flex-direction: row; + justify-content: space-between; + padding-top: 24px; + + & > .button { + width: 48%; + min-width: 0px; + font-size: 23px; + height: 44px; + min-height: 0px; + + &.back-button { + background: none; + color: #2c2c2c; + border: solid #2c2c2c 2px; + } + } +} + +:global(body.dark-theme) { + .buttons-container > .button.back-button { + color: #fff; + border-color: #fff; + } +} diff --git a/src/hooks/ab/unleash/useUnleash.ts b/src/hooks/ab/unleash/useUnleash.ts index e52353b..2c48d1d 100644 --- a/src/hooks/ab/unleash/useUnleash.ts +++ b/src/hooks/ab/unleash/useUnleash.ts @@ -37,6 +37,7 @@ export enum EUnleashFlags { "v2CompatibilityCameraTemplate" = "v2-compatibility-camera-template", "v2CompatibilityRelationshipStatusPagePlacement" = "v2-compatibility-relationship-status-page-placement", "v2CompatibilityReviewPage" = "v2-compatibility-review-page", + "v2CompatibilityPathToEnteringBirthdate" = "v2-compatibility-path-to-entering-birthdate", } interface IUseUnleashProps { @@ -78,6 +79,7 @@ interface IVariants { [EUnleashFlags.v2CompatibilityCameraTemplate]: 'v0' | 'v1' | 'v2' | 'v3' | 'v4'; [EUnleashFlags.v2CompatibilityRelationshipStatusPagePlacement]: 'v0' | 'v1' | 'v2'; [EUnleashFlags.v2CompatibilityReviewPage]: 'show' | 'hide'; + [EUnleashFlags.v2CompatibilityPathToEnteringBirthdate]: 'hide' | 'show'; } /** diff --git a/src/routerComponents/Compatibility/v2/Layout/index.tsx b/src/routerComponents/Compatibility/v2/Layout/index.tsx index 112b1b1..33ea8c3 100644 --- a/src/routerComponents/Compatibility/v2/Layout/index.tsx +++ b/src/routerComponents/Compatibility/v2/Layout/index.tsx @@ -34,17 +34,28 @@ function Layout() { ]); const { variant: relationshipStatusPagePlacement = "v0" } = useUnleash({ - flag: EUnleashFlags.v2CompatibilityRelationshipStatusPagePlacement + flag: EUnleashFlags.v2CompatibilityRelationshipStatusPagePlacement, }); const getIsBackButtonVisible = () => { if ( - relationshipStatusPagePlacement === "v1" && location.pathname.includes(routes.client.compatibilityV2RelationshipStatus()) + location.pathname.includes( + routes.client.compatibilityV2RelationshipStatusResult() + ) ) { return false; } if ( - relationshipStatusPagePlacement === "v1" && location.pathname.includes(routes.client.compatibilityV2Gender()) + relationshipStatusPagePlacement === "v1" && + location.pathname.includes( + routes.client.compatibilityV2RelationshipStatus() + ) + ) { + return false; + } + if ( + relationshipStatusPagePlacement === "v1" && + location.pathname.includes(routes.client.compatibilityV2Gender()) ) { return true; } diff --git a/src/routerComponents/Compatibility/v2/StepperLayout/index.tsx b/src/routerComponents/Compatibility/v2/StepperLayout/index.tsx index 85b0f0a..9a86661 100644 --- a/src/routerComponents/Compatibility/v2/StepperLayout/index.tsx +++ b/src/routerComponents/Compatibility/v2/StepperLayout/index.tsx @@ -1,30 +1,13 @@ import { useSchemeColorByElement } from "@/hooks/useSchemeColorByElement"; -import { useRef } from "react"; +import { useMemo, useRef } from "react"; import { Outlet, useLocation } from "react-router-dom"; import routes from "@/routes"; import StepperBar from "@/components/CompatibilityV2/components/StepperBar"; import styles from "./styles.module.scss"; import { useSelector } from "react-redux"; import { selectors } from "@/store"; - -const stepperRoutes = [ - routes.client.compatibilityV2Birthdate(), - routes.client.compatibilityV2PalmsInformation(), - // routes.client.compatibilityV2WhatAspects(), - routes.client.compatibilityV2RelationshipStatus(), - routes.client.compatibilityV2RelateFollowing(), - routes.client.compatibilityV2RomanticGestures(), - routes.client.compatibilityV2CheckingPhone(), - routes.client.compatibilityV2BirthdatePartner(), - routes.client.compatibilityV2PalmsInformationPartner(), - routes.client.compatibilityV2DateEvent(), - - // routes.client.compatibilityV2ElementResonates(), - // routes.client.compatibilityV2FavoriteColor(), - routes.client.compatibilityV2HeadOrHeart(), - routes.client.compatibilityV2HeadOrHeartResult(), - routes.client.compatibilityV2Email(), -]; +import { EUnleashFlags, useUnleash } from "@/hooks/ab/unleash/useUnleash"; +import Loader, { LoaderColor } from "@/components/Loader"; function StepperLayout() { const darkTheme = useSelector(selectors.selectDarkTheme); @@ -33,27 +16,86 @@ function StepperLayout() { useSchemeColorByElement(mainRef.current, "section.page, .page, section", [ location, ]); + const { variant: pathToEnteringBirthdate = "hide", isReady } = useUnleash({ + flag: EUnleashFlags.v2CompatibilityPathToEnteringBirthdate, + }); + + const stepperRoutes = useMemo(() => { + if (pathToEnteringBirthdate === "show") { + return [ + routes.client.compatibilityV2RelationshipStatus(), + routes.client.compatibilityV2FearInRelationship(), + routes.client.compatibilityV2ImportantStep(), + routes.client.compatibilityV2WhoMatter(), + routes.client.compatibilityV2YourPriority(), + + routes.client.compatibilityV2Birthdate(), + routes.client.compatibilityV2PalmsInformation(), + // routes.client.compatibilityV2WhatAspects(), + routes.client.compatibilityV2RelateFollowing(), + routes.client.compatibilityV2RomanticGestures(), + routes.client.compatibilityV2CheckingPhone(), + routes.client.compatibilityV2BirthdatePartner(), + routes.client.compatibilityV2PalmsInformationPartner(), + routes.client.compatibilityV2DateEvent(), + + // routes.client.compatibilityV2ElementResonates(), + // routes.client.compatibilityV2FavoriteColor(), + routes.client.compatibilityV2HeadOrHeart(), + routes.client.compatibilityV2HeadOrHeartResult(), + routes.client.compatibilityV2Email(), + ]; + } + return [ + routes.client.compatibilityV2Birthdate(), + routes.client.compatibilityV2PalmsInformation(), + // routes.client.compatibilityV2WhatAspects(), + routes.client.compatibilityV2RelationshipStatus(), + routes.client.compatibilityV2RelateFollowing(), + routes.client.compatibilityV2RomanticGestures(), + routes.client.compatibilityV2CheckingPhone(), + routes.client.compatibilityV2BirthdatePartner(), + routes.client.compatibilityV2PalmsInformationPartner(), + routes.client.compatibilityV2DateEvent(), + + // routes.client.compatibilityV2ElementResonates(), + // routes.client.compatibilityV2FavoriteColor(), + routes.client.compatibilityV2HeadOrHeart(), + routes.client.compatibilityV2HeadOrHeartResult(), + routes.client.compatibilityV2Email(), + ]; + }, [pathToEnteringBirthdate]); const getCurrentStep = () => { let index = 0; for (const route of stepperRoutes) { if (location.pathname.includes(route)) { - if (location.pathname.includes(routes.client.compatibilityV2BirthdatePartner())) { + if ( + location.pathname.includes( + routes.client.compatibilityV2BirthdatePartner() + ) + ) { return 8; } - if (location.pathname.includes(routes.client.compatibilityV2PalmsInformationPartner())) { + if ( + location.pathname.includes( + routes.client.compatibilityV2PalmsInformationPartner() + ) + ) { return 9; } return index + 1; } - index++; - } return 0; }; + if (!isReady) { + return ; + } + return ( <> path.replace(compatibilityV2Prefix, ""); @@ -59,10 +68,6 @@ function CompatibilityV2Routes() { const dispatch = useDispatch(); const { setTheme } = useTheme(); - const { isReady, variant: darkThemeCompatibilityV2Variant } = useUnleash({ - flag: EUnleashFlags.darkThemeCompatibilityV2, - }); - const { funnelData } = useFunnel({ funnel: ELocalesPlacement.CompatibilityV2, paymentPlacement: "", @@ -140,28 +145,17 @@ function CompatibilityV2Routes() { } useEffect(() => { - if (darkThemeCompatibilityV2Variant === "enabled") { - setTheme(ESiteTheme.Dark); - } - return () => { - setTheme(ESiteTheme.Light); - }; - }, [darkThemeCompatibilityV2Variant]); + const systemColorScheme = getSystemColorScheme(); + setTheme(systemColorScheme); - if (!isReady) { - return ( -
- -
- ); - } + const unsubscribe = subscribeToSystemThemeChange((theme) => { + setTheme(theme); + }); + + return () => { + unsubscribe?.(); + }; + }, [setTheme]); return ( @@ -261,6 +255,12 @@ function CompatibilityV2Routes() { > } /> + } + /> } @@ -271,7 +271,39 @@ function CompatibilityV2Routes() { > } /> + } + /> + } + /> }> + } + /> + } + /> + } + /> + } + /> } diff --git a/src/routes.ts b/src/routes.ts index f314708..12d5d2b 100755 --- a/src/routes.ts +++ b/src/routes.ts @@ -224,6 +224,7 @@ const routes = { palmistryOnboardingV1: () => [palmistryV1Prefix, "onboarding"].join("/"), // CompatibilityV2 compatibilityV2Welcome: () => [compatibilityV2Prefix, "welcome"].join("/"), + compatibilityV2CompatibilityTest: () => [compatibilityV2Prefix, "compatibility-test"].join("/"), compatibilityV2Gender: () => [compatibilityV2Prefix, "gender"].join("/"), compatibilityV2GenderPartner: () => [compatibilityV2Prefix, "gender-partner"].join("/"), compatibilityV2Birthdate: () => [compatibilityV2Prefix, "birthdate"].join("/"), @@ -233,6 +234,11 @@ const routes = { compatibilityV2DateEvent: () => [compatibilityV2Prefix, "date-event"].join("/"), compatibilityV2WhatAspects: () => [compatibilityV2Prefix, "what-aspects"].join("/"), compatibilityV2RelationshipStatus: () => [compatibilityV2Prefix, "relationship-status"].join("/"), + compatibilityV2RelationshipStatusResult: () => [compatibilityV2Prefix, "relationship-status-result"].join("/"), + compatibilityV2FearInRelationship: () => [compatibilityV2Prefix, "fear-in-relationship"].join("/"), + compatibilityV2ImportantStep: () => [compatibilityV2Prefix, "important-step"].join("/"), + compatibilityV2WhoMatter: () => [compatibilityV2Prefix, "who-matter"].join("/"), + compatibilityV2YourPriority: () => [compatibilityV2Prefix, "your-priority"].join("/"), compatibilityV2ElementResonates: () => [compatibilityV2Prefix, "element-resonates"].join("/"), compatibilityV2FavoriteColor: () => [compatibilityV2Prefix, "favorite-color"].join("/"), compatibilityV2HeadOrHeart: () => [compatibilityV2Prefix, "head-or-heart"].join("/"), @@ -240,6 +246,7 @@ const routes = { compatibilityV2RelateFollowing: () => [compatibilityV2Prefix, "relate-following"].join("/"), compatibilityV2RomanticGestures: () => [compatibilityV2Prefix, "romantic-gestures"].join("/"), compatibilityV2CheckingPhone: () => [compatibilityV2Prefix, "checking-phone"].join("/"), + compatibilityV2PersonalizedRelationshipAnalysis: () => [compatibilityV2Prefix, "personalized-relationship-analysis"].join("/"), compatibilityV2LetScan: () => [compatibilityV2Prefix, "let-scan"].join("/"), compatibilityV2ScanInstruction: () => [compatibilityV2Prefix, "scan-instruction"].join("/"), compatibilityV2Camera: () => [compatibilityV2Prefix, "camera"].join("/"), diff --git a/src/store/compatibilityV2.ts b/src/store/compatibilityV2.ts index 69cf279..ec30b2f 100644 --- a/src/store/compatibilityV2.ts +++ b/src/store/compatibilityV2.ts @@ -2,7 +2,9 @@ import { IPalmistryFinger, IPalmistryLine } from "@/api/resources/Palmistry"; import { createSlice, createSelector } from "@reduxjs/toolkit"; import type { PayloadAction } from "@reduxjs/toolkit"; -export type ICompatibilityV2FingerLocal = IPalmistryFinger & { fingerName?: string } +export type ICompatibilityV2FingerLocal = IPalmistryFinger & { + fingerName?: string; +}; interface ICompatibilityV2 { lines: IPalmistryLine[]; @@ -35,7 +37,8 @@ export const selectCompatibilityV2Lines = createSelector( (compatibilityV2) => compatibilityV2 ); export const selectCompatibilityV2Fingers = createSelector( - (state: { compatibilityV2: ICompatibilityV2 }) => state.compatibilityV2.fingers, + (state: { compatibilityV2: ICompatibilityV2 }) => + state.compatibilityV2.fingers, (compatibilityV2) => compatibilityV2 ); export const selectCompatibilityV2Photo = createSelector( @@ -43,7 +46,8 @@ export const selectCompatibilityV2Photo = createSelector( (compatibilityV2) => compatibilityV2 ); export const selectCompatibilityV2FromRedesign = createSelector( - (state: { compatibilityV2: ICompatibilityV2 }) => state.compatibilityV2.fromRedesign, + (state: { compatibilityV2: ICompatibilityV2 }) => + state.compatibilityV2.fromRedesign, (compatibilityV2) => compatibilityV2 ); export default compatibilityV2Slice.reducer; diff --git a/src/store/compatibilityV2Answers.ts b/src/store/compatibilityV2Answers.ts index 955afea..d131102 100644 --- a/src/store/compatibilityV2Answers.ts +++ b/src/store/compatibilityV2Answers.ts @@ -2,41 +2,48 @@ import { createSlice, createSelector } from "@reduxjs/toolkit"; import type { PayloadAction } from "@reduxjs/toolkit"; export interface ICompatibilityV2Answers { - whatAspects: string; - relationshipStatus: string; - elementResonates: string; - favoriteColor: string; - headOrHeart: string; - dateEvent: string; - romanticGestures: string; - checkingPhone: string; + whatAspects: string; + relationshipStatus: string; + elementResonates: string; + favoriteColor: string; + headOrHeart: string; + dateEvent: string; + romanticGestures: string; + checkingPhone: string; + fearInRelationship: string; + whoMatter: string; + yourPriority: string; } const initialState: ICompatibilityV2Answers = { - whatAspects: "", - relationshipStatus: "", - elementResonates: "", - favoriteColor: "", - headOrHeart: "", - dateEvent: "", - romanticGestures: "", - checkingPhone: "", + whatAspects: "", + relationshipStatus: "", + elementResonates: "", + favoriteColor: "", + headOrHeart: "", + dateEvent: "", + romanticGestures: "", + checkingPhone: "", + fearInRelationship: "", + whoMatter: "", + yourPriority: "", }; const compatibilityV2AnswersSlice = createSlice({ - name: "compatibilityV2Answers", - initialState, - reducers: { - update(state, action: PayloadAction>) { - return { ...state, ...action.payload }; - }, + name: "compatibilityV2Answers", + initialState, + reducers: { + update(state, action: PayloadAction>) { + return { ...state, ...action.payload }; }, - extraReducers: (builder) => builder.addCase("reset", () => initialState), + }, + extraReducers: (builder) => builder.addCase("reset", () => initialState), }); export const { actions } = compatibilityV2AnswersSlice; export const selectCompatibilityV2Answers = createSelector( - (state: { compatibilityV2Answers: ICompatibilityV2Answers }) => state.compatibilityV2Answers, - (compatibilityV2Answers) => compatibilityV2Answers + (state: { compatibilityV2Answers: ICompatibilityV2Answers }) => + state.compatibilityV2Answers, + (compatibilityV2Answers) => compatibilityV2Answers ); export default compatibilityV2AnswersSlice.reducer; diff --git a/src/store/index.ts b/src/store/index.ts index 10dead6..812970f 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -88,39 +88,56 @@ import palmistry, { selectPalmistryFingers, selectPalmistryFromRedesign, selectPalmistryLines, - selectPalmistryPhoto + selectPalmistryPhoto, } from "./palmistry"; import compatibilityV2, { actions as compatibilityV2Actions, selectCompatibilityV2Fingers, selectCompatibilityV2FromRedesign, selectCompatibilityV2Lines, - selectCompatibilityV2Photo + selectCompatibilityV2Photo, } from "./compatibilityV2"; import retainingFunnel, { actions as retainingFunnelActions, selectRetainingFunnel, - selectCancellingSubscriptionId + selectCancellingSubscriptionId, } from "./retainingFunnel"; import compatibilityV3, { actions as compatibilityV3Actions, selectCompatibilityV3Fingers, selectCompatibilityV3FromRedesign, selectCompatibilityV3Lines, - selectCompatibilityV3Photo + selectCompatibilityV3Photo, } from "./compatibilityV3"; import compatibilityV4, { actions as compatibilityV4Actions, selectCompatibilityV4Fingers, selectCompatibilityV4FromRedesign, selectCompatibilityV4Lines, - selectCompatibilityV4Photo + selectCompatibilityV4Photo, } from "./compatibilityV4"; import { selectPaywallsIsMustUpdate, selectPaywalls } from "./paywalls"; -import privacyPolicy, { actions as privacyPolicyActions, selectPrivacyPolicy } from "./privacyPolicy"; -import personalVideo, { actions as personalVideoActions, selectPersonalVideo } from "./personalVideo"; -import chats, { actions as chatsActions, selectAnswers, selectCurrentStep } from "./chats"; -import chat, { actions as chatActions, selectCurrentAssistant, selectCurrentChatId, selectDateEndChatting, selectIsAutoRefill, selectIsPayedFirstPurchase } from "./chat"; +import privacyPolicy, { + actions as privacyPolicyActions, + selectPrivacyPolicy, +} from "./privacyPolicy"; +import personalVideo, { + actions as personalVideoActions, + selectPersonalVideo, +} from "./personalVideo"; +import chats, { + actions as chatsActions, + selectAnswers, + selectCurrentStep, +} from "./chats"; +import chat, { + actions as chatActions, + selectCurrentAssistant, + selectCurrentChatId, + selectDateEndChatting, + selectIsAutoRefill, + selectIsPayedFirstPurchase, +} from "./chat"; const preloadedState = loadStore(); export const actions = { diff --git a/src/utils/Theme/index.ts b/src/utils/Theme/index.ts new file mode 100644 index 0000000..3240fbb --- /dev/null +++ b/src/utils/Theme/index.ts @@ -0,0 +1,31 @@ +import { ESiteTheme } from "@/hooks/theme/useTheme"; + +export function getSystemColorScheme(): ESiteTheme { + if (typeof window !== "undefined" && window.matchMedia) { + return window.matchMedia("(prefers-color-scheme: dark)").matches + ? ESiteTheme.Dark + : ESiteTheme.Light; + } + + return ESiteTheme.Light; +} + +export function subscribeToSystemThemeChange( + callback: (theme: ESiteTheme) => void +) { + if (typeof window === "undefined" || !window.matchMedia) { + return; + } + + const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); + + const handleChange = (e: MediaQueryListEvent) => { + callback(e.matches ? ESiteTheme.Dark : ESiteTheme.Light); + }; + + mediaQuery.addEventListener("change", handleChange); + + return () => { + mediaQuery.removeEventListener("change", handleChange); + }; +}