diff --git a/public/chats/1.webp b/public/chats/1.webp new file mode 100644 index 0000000..e14b4a1 Binary files /dev/null and b/public/chats/1.webp differ diff --git a/public/chats/2.webp b/public/chats/2.webp new file mode 100644 index 0000000..76363c8 Binary files /dev/null and b/public/chats/2.webp differ diff --git a/public/chats/3.webp b/public/chats/3.webp new file mode 100644 index 0000000..54b8948 Binary files /dev/null and b/public/chats/3.webp differ diff --git a/public/chats/Avatar-10.webp b/public/chats/Avatar-10.webp new file mode 100644 index 0000000..5f293a3 Binary files /dev/null and b/public/chats/Avatar-10.webp differ diff --git a/public/chats/Avatar-2.webp b/public/chats/Avatar-2.webp new file mode 100644 index 0000000..e99f6cb Binary files /dev/null and b/public/chats/Avatar-2.webp differ diff --git a/public/chats/Avatar-4.webp b/public/chats/Avatar-4.webp new file mode 100644 index 0000000..23018b4 Binary files /dev/null and b/public/chats/Avatar-4.webp differ diff --git a/public/chats/Avatar-6.webp b/public/chats/Avatar-6.webp new file mode 100644 index 0000000..8cb2596 Binary files /dev/null and b/public/chats/Avatar-6.webp differ diff --git a/public/chats/Avatar-8.webp b/public/chats/Avatar-8.webp new file mode 100644 index 0000000..41ca630 Binary files /dev/null and b/public/chats/Avatar-8.webp differ diff --git a/public/chats/CareerWork.webp b/public/chats/CareerWork.webp new file mode 100644 index 0000000..0df6c52 Binary files /dev/null and b/public/chats/CareerWork.webp differ diff --git a/public/chats/Customer1.webp b/public/chats/Customer1.webp new file mode 100644 index 0000000..4270044 Binary files /dev/null and b/public/chats/Customer1.webp differ diff --git a/public/chats/Customer3.webp b/public/chats/Customer3.webp new file mode 100644 index 0000000..5addef2 Binary files /dev/null and b/public/chats/Customer3.webp differ diff --git a/public/chats/Customer4.webp b/public/chats/Customer4.webp new file mode 100644 index 0000000..f05c70d Binary files /dev/null and b/public/chats/Customer4.webp differ diff --git a/public/chats/Customer5.webp b/public/chats/Customer5.webp new file mode 100644 index 0000000..e389946 Binary files /dev/null and b/public/chats/Customer5.webp differ diff --git a/public/chats/Customer6.webp b/public/chats/Customer6.webp new file mode 100644 index 0000000..cf5396c Binary files /dev/null and b/public/chats/Customer6.webp differ diff --git a/public/chats/Customer9.webp b/public/chats/Customer9.webp new file mode 100644 index 0000000..94a6ef0 Binary files /dev/null and b/public/chats/Customer9.webp differ diff --git a/public/chats/FutureTelling.webp b/public/chats/FutureTelling.webp new file mode 100644 index 0000000..ea1cc4f Binary files /dev/null and b/public/chats/FutureTelling.webp differ diff --git a/public/chats/GuidanceLifePath.webp b/public/chats/GuidanceLifePath.webp new file mode 100644 index 0000000..4c20d40 Binary files /dev/null and b/public/chats/GuidanceLifePath.webp differ diff --git a/public/chats/LoveRelationship.webp b/public/chats/LoveRelationship.webp new file mode 100644 index 0000000..faf64f1 Binary files /dev/null and b/public/chats/LoveRelationship.webp differ diff --git a/public/chats/angel.webp b/public/chats/angel.webp new file mode 100644 index 0000000..f8a3e65 Binary files /dev/null and b/public/chats/angel.webp differ diff --git a/public/chats/answers_hub_bg.webp b/public/chats/answers_hub_bg.webp new file mode 100644 index 0000000..a07c804 Binary files /dev/null and b/public/chats/answers_hub_bg.webp differ diff --git a/public/chats/astrologers-card-mobile.webp b/public/chats/astrologers-card-mobile.webp new file mode 100644 index 0000000..71e53ed Binary files /dev/null and b/public/chats/astrologers-card-mobile.webp differ diff --git a/public/chats/astrologers.webp b/public/chats/astrologers.webp new file mode 100644 index 0000000..a336e0e Binary files /dev/null and b/public/chats/astrologers.webp differ diff --git a/public/chats/big_thumbs_up.webp b/public/chats/big_thumbs_up.webp new file mode 100644 index 0000000..199613c Binary files /dev/null and b/public/chats/big_thumbs_up.webp differ diff --git a/public/chats/bustle.webp b/public/chats/bustle.webp new file mode 100644 index 0000000..af58622 Binary files /dev/null and b/public/chats/bustle.webp differ diff --git a/public/chats/christofer.webp b/public/chats/christofer.webp new file mode 100644 index 0000000..b019b75 Binary files /dev/null and b/public/chats/christofer.webp differ diff --git a/public/chats/cosmopolitian.webp b/public/chats/cosmopolitian.webp new file mode 100644 index 0000000..5199e3c Binary files /dev/null and b/public/chats/cosmopolitian.webp differ diff --git a/public/chats/done.svg b/public/chats/done.svg new file mode 100644 index 0000000..f2f6127 --- /dev/null +++ b/public/chats/done.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/chats/done.webp b/public/chats/done.webp new file mode 100644 index 0000000..ae5549a Binary files /dev/null and b/public/chats/done.webp differ diff --git a/public/chats/female.webp b/public/chats/female.webp new file mode 100644 index 0000000..50c5189 Binary files /dev/null and b/public/chats/female.webp differ diff --git a/public/chats/hanna.webp b/public/chats/hanna.webp new file mode 100644 index 0000000..f9c8a13 Binary files /dev/null and b/public/chats/hanna.webp differ diff --git a/public/chats/hypebae.webp b/public/chats/hypebae.webp new file mode 100644 index 0000000..02e92e1 Binary files /dev/null and b/public/chats/hypebae.webp differ diff --git a/public/chats/life_goal_pic.webp b/public/chats/life_goal_pic.webp new file mode 100644 index 0000000..50b8175 Binary files /dev/null and b/public/chats/life_goal_pic.webp differ diff --git a/public/chats/male.webp b/public/chats/male.webp new file mode 100644 index 0000000..1124b89 Binary files /dev/null and b/public/chats/male.webp differ diff --git a/public/chats/new-york-times.webp b/public/chats/new-york-times.webp new file mode 100644 index 0000000..d9ef78c Binary files /dev/null and b/public/chats/new-york-times.webp differ diff --git a/public/chats/orbited_heart.webp b/public/chats/orbited_heart.webp new file mode 100644 index 0000000..3068004 Binary files /dev/null and b/public/chats/orbited_heart.webp differ diff --git a/public/chats/profile-intro-star.svg b/public/chats/profile-intro-star.svg new file mode 100644 index 0000000..8947a1f --- /dev/null +++ b/public/chats/profile-intro-star.svg @@ -0,0 +1,12 @@ + + Shining star + + + + \ No newline at end of file diff --git a/public/chats/refinery29.webp b/public/chats/refinery29.webp new file mode 100644 index 0000000..8cde010 Binary files /dev/null and b/public/chats/refinery29.webp differ diff --git a/public/chats/resonate-2.webp b/public/chats/resonate-2.webp new file mode 100644 index 0000000..07842f6 Binary files /dev/null and b/public/chats/resonate-2.webp differ diff --git a/public/chats/resonate-3.webp b/public/chats/resonate-3.webp new file mode 100644 index 0000000..fd17b6c Binary files /dev/null and b/public/chats/resonate-3.webp differ diff --git a/public/chats/resonate-4.webp b/public/chats/resonate-4.webp new file mode 100644 index 0000000..719ca5f Binary files /dev/null and b/public/chats/resonate-4.webp differ diff --git a/public/chats/smile-people.webp b/public/chats/smile-people.webp new file mode 100644 index 0000000..1d6cfd7 Binary files /dev/null and b/public/chats/smile-people.webp differ diff --git a/public/chats/sprites.svg b/public/chats/sprites.svg new file mode 100644 index 0000000..5cc54a7 --- /dev/null +++ b/public/chats/sprites.svg @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/chats/wing.webp b/public/chats/wing.webp new file mode 100644 index 0000000..fe71993 Binary files /dev/null and b/public/chats/wing.webp differ diff --git a/public/chats/zodiac-wheel-arrow.svg b/public/chats/zodiac-wheel-arrow.svg new file mode 100644 index 0000000..1b6074b --- /dev/null +++ b/public/chats/zodiac-wheel-arrow.svg @@ -0,0 +1,34 @@ + +Wheel arrow + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/chats/zodiacWheel.svg b/public/chats/zodiacWheel.svg new file mode 100644 index 0000000..7b658a6 --- /dev/null +++ b/public/chats/zodiacWheel.svg @@ -0,0 +1 @@ +Zodiac Wheel \ No newline at end of file diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index d326323..644fc2b 100755 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -26,6 +26,7 @@ import routes, { hasNavbarFooter, hasFullDataModal, palmistryV1Prefix, + chatsPrefix, } from "@/routes"; import BirthdayPage from "../BirthdayPage"; import BirthtimePage from "../BirthtimePage"; @@ -131,6 +132,7 @@ import AddGuides from "../palmistry/AdditionalPurchases/pages/AddGuides"; import SkipTrial from "../palmistry/AdditionalPurchases/pages/SkipTrial"; import { parseQueryParams } from "@/services/url"; import Auth from "../pages/Auth"; +import ChatsRoutes from "@/routerComponents/Chats"; const isProduction = import.meta.env.MODE === "production"; @@ -314,6 +316,7 @@ function App(): JSX.Element { } /> } /> + } /> } /> } /> }> diff --git a/src/components/ChatsPath/components/Address/index.tsx b/src/components/ChatsPath/components/Address/index.tsx new file mode 100644 index 0000000..258c46c --- /dev/null +++ b/src/components/ChatsPath/components/Address/index.tsx @@ -0,0 +1,12 @@ +import styles from "./styles.module.scss"; + +function Address() { + return ( +

+ 2024, Wit Apps LLC,
+ 123, Rimer Dr, Moraga, California, 94556, US +

+ ); +} + +export default Address; diff --git a/src/components/ChatsPath/components/Address/styles.module.scss b/src/components/ChatsPath/components/Address/styles.module.scss new file mode 100644 index 0000000..11d2493 --- /dev/null +++ b/src/components/ChatsPath/components/Address/styles.module.scss @@ -0,0 +1,5 @@ +.address { + color: #d3d3d3; + margin-top: 30px; + font-size: 10px; +} diff --git a/src/components/ChatsPath/components/AnimateMessages/index.tsx b/src/components/ChatsPath/components/AnimateMessages/index.tsx new file mode 100644 index 0000000..33ad353 --- /dev/null +++ b/src/components/ChatsPath/components/AnimateMessages/index.tsx @@ -0,0 +1,48 @@ +import { useEffect, useState } from "react"; +import styles from "./styles.module.scss"; +import { images } from "../../data"; +import { sleep } from "@/services/date"; + +export interface IAnimateMessage { + name: string; + text: string; + avatar: string; +} + +interface AnimateMessagesProps { + messages: IAnimateMessage[]; +} + +function AnimateMessages({ messages }: AnimateMessagesProps) { + const [activeMessage, setActiveMessage] = useState(0); + + useEffect(() => { + (async () => { + await sleep(2000); + setActiveMessage((activeMessage + 1) % messages.length); + })(); + }, [activeMessage, messages.length]); + + return ( +
+
    + {messages.map(({ name, text, avatar }, index) => ( +
  • + {`${name} +
    +

    {name}

    +

    {text}

    +
    +
  • + ))} +
+
+ ); +} + +export default AnimateMessages; diff --git a/src/components/ChatsPath/components/AnimateMessages/styles.module.scss b/src/components/ChatsPath/components/AnimateMessages/styles.module.scss new file mode 100644 index 0000000..3428967 --- /dev/null +++ b/src/components/ChatsPath/components/AnimateMessages/styles.module.scss @@ -0,0 +1,78 @@ +.container { + margin-top: 20vh; + margin-bottom: 8vh; +} + +.list { + position: relative; + height: 60px; + transform-origin: center bottom; + + &::before, + &::after { + content: ""; + position: absolute; + width: 100%; + height: 100%; + background: var(--primary-800); + border-radius: 16px; + opacity: 0.65; + z-index: -1; + } + + &::before { + transform: translateY(40%) scale(0.8); + } + + &::after { + transform: translateY(20%) scale(0.9); + } + + & > .item { + position: absolute; + width: 100%; + opacity: 0; + display: flex; + padding: 8px 10px; + border-radius: 16px; + background: var(--primary-800); + bottom: 0; + transform: translateY(40%) scale(0.8); + transition: opacity 0.4s ease-in-out, transform 0.4s ease-in-out; + box-shadow: 0 2px 6px 0 var(--primary-900-with-opacity-40); + z-index: 0; + + &.hide-up { + transform: translateY(-80%) scale(1); + } + + &.active { + transform: translate(0); + opacity: 1; + } + + & > img { + width: 34px; + height: 34px; + border-radius: 8px; + margin-right: 12px; + color: transparent; + } + + & .name { + color: var(--typography-100); + font-size: 14px; + font-style: normal; + font-weight: 700; + line-height: 135%; + } + + & .text { + color: var(--typography-100); + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 135%; + } + } +} diff --git a/src/components/ChatsPath/components/Answer/index.tsx b/src/components/ChatsPath/components/Answer/index.tsx new file mode 100644 index 0000000..5dd50c1 --- /dev/null +++ b/src/components/ChatsPath/components/Answer/index.tsx @@ -0,0 +1,43 @@ +import { useDispatch } from "react-redux"; +import { IAnswer } from "../../data"; +import styles from "./styles.module.scss"; +import { actions } from "@/store"; + +interface IAnswerProps { + answer: IAnswer; + classNameContainer?: string; + active?: boolean; + onClick?: () => void; +} + +function Answer({ + answer, + classNameContainer = "", + active = false, + onClick, +}: IAnswerProps) { + const dispatch = useDispatch(); + + const handleClick = () => { + dispatch( + actions.chats.updateAnswers({ + [answer.questionId]: answer.value, + }) + ); + onClick && onClick(); + }; + + return ( +
+ {answer.name} +
+ ); +} + +export default Answer; diff --git a/src/components/ChatsPath/components/Answer/styles.module.scss b/src/components/ChatsPath/components/Answer/styles.module.scss new file mode 100644 index 0000000..0d29f1e --- /dev/null +++ b/src/components/ChatsPath/components/Answer/styles.module.scss @@ -0,0 +1,37 @@ +.container { + min-height: 40px; + display: flex; + align-items: center; + justify-content: center; + font-weight: 600; + cursor: pointer; + transition: all 0.15s ease-in 0ms; + + padding: 16px; + border: 1px solid var(--primary); + box-shadow: 0 4px 4px rgba(0, 0, 0, 0.25); + border-radius: 16px; + + &:hover { + transform: scale(1.03); + background-color: rgba(#8e8cf0, 0.2); + } + + &:active { + transform: scale(1.1); + background: var(--gradient-tranquil); + } + + &.active { + background-color: var(--primary); + } +} + +.text { + color: var(--typography-100); + line-height: 21px; + font-weight: 400; + display: flex; + align-items: center; + font-size: 16px; +} diff --git a/src/components/ChatsPath/components/AnswerDescription/index.tsx b/src/components/ChatsPath/components/AnswerDescription/index.tsx new file mode 100644 index 0000000..75daaad --- /dev/null +++ b/src/components/ChatsPath/components/AnswerDescription/index.tsx @@ -0,0 +1,29 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.scss"; +import React from "react"; + +export interface IAnswerDescriptionProps { + title: string; + description: string; + footer?: string | React.ReactNode; +} + +function AnswerDescription({ + title, + description, + footer, +}: IAnswerDescriptionProps) { + return ( +
+
+ + {title} + +

{description}

+
+ {footer &&

{footer}

} +
+ ); +} + +export default AnswerDescription; diff --git a/src/components/ChatsPath/components/AnswerDescription/styles.module.scss b/src/components/ChatsPath/components/AnswerDescription/styles.module.scss new file mode 100644 index 0000000..f752f6b --- /dev/null +++ b/src/components/ChatsPath/components/AnswerDescription/styles.module.scss @@ -0,0 +1,39 @@ +.container { + display: flex; + flex-direction: column; + overflow: hidden; + border-radius: 16px; + border: 1px solid var(--white-with-opacity-15); + margin-top: 34px; +} + +.wrapper { + display: flex; + flex-direction: column; + padding: 16px 16px 20px; + background-color: var(--secondary); +} + +.title { + margin: 0; + color: var(--primary-100); + font-size: 14px; + font-weight: 700; + line-height: 135%; + text-align: left; +} + +.text { + color: var(--primary-100); + font-size: 14px; + font-weight: 400; + line-height: 135%; + text-align: left; + margin-top: 8px; +} + +.footer { + padding: 7px 10px; + font-size: 14px; + font-weight: 400; +} diff --git a/src/components/ChatsPath/components/Answers/index.tsx b/src/components/ChatsPath/components/Answers/index.tsx new file mode 100644 index 0000000..fdbe46b --- /dev/null +++ b/src/components/ChatsPath/components/Answers/index.tsx @@ -0,0 +1,34 @@ +import { IAnswer } from "../../data"; +import Answer from "../Answer"; +import styles from "./styles.module.scss"; + +interface IAnswersProps { + answers: IAnswer[]; + classNameAnswer?: string; + activeAnswer?: string; +} + +function Answers({ + answers, + activeAnswer, + classNameAnswer = "", +}: IAnswersProps) { + return ( +
+
    + {answers.map((answer, index) => ( +
  • + +
  • + ))} +
+
+ ); +} + +export default Answers; diff --git a/src/components/ChatsPath/components/Answers/styles.module.scss b/src/components/ChatsPath/components/Answers/styles.module.scss new file mode 100644 index 0000000..4a2c9de --- /dev/null +++ b/src/components/ChatsPath/components/Answers/styles.module.scss @@ -0,0 +1,11 @@ +.container { + width: 100%; +} + +.list { + margin-bottom: -20px; + + & > .item { + padding-bottom: 10px; + } +} diff --git a/src/components/ChatsPath/components/AppStoreReviews/index.tsx b/src/components/ChatsPath/components/AppStoreReviews/index.tsx new file mode 100644 index 0000000..d800f87 --- /dev/null +++ b/src/components/ChatsPath/components/AppStoreReviews/index.tsx @@ -0,0 +1,36 @@ +import { images } from "../../data"; +import Stars from "../Stars"; +import styles from "./styles.module.scss"; + +function AppStoreReviews() { + return ( +
+
+ wing +
+

App Store

+

215K reviews

+
+ wing +
+ +
+ | 4.8 rating +
+
+ ); +} + +export default AppStoreReviews; diff --git a/src/components/ChatsPath/components/AppStoreReviews/styles.module.scss b/src/components/ChatsPath/components/AppStoreReviews/styles.module.scss new file mode 100644 index 0000000..2465824 --- /dev/null +++ b/src/components/ChatsPath/components/AppStoreReviews/styles.module.scss @@ -0,0 +1,49 @@ +.app-wrapper { + margin-left: auto; + margin-right: auto; + margin-bottom: 40px; +} + +.app-review { + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 8px; +} + +.wing { + width: 27px; + height: 58px; + color: transparent; +} + +.wing-right { + width: 27px; + height: 58px; + transform: scaleX(-1); + color: transparent; +} + +.app-info { + text-align: center; + margin-left: 5px; + margin-right: 5px; +} + +.app-title { + font-weight: 700; + font-size: 14px; + margin-bottom: 5px; +} + +.app-text { + font-weight: 600; + font-size: 14px; + line-height: 24px; +} + +.app-rating { + display: flex; + align-items: center; + justify-content: center; +} diff --git a/src/components/ChatsPath/components/Astrologers/index.tsx b/src/components/ChatsPath/components/Astrologers/index.tsx new file mode 100644 index 0000000..383b898 --- /dev/null +++ b/src/components/ChatsPath/components/Astrologers/index.tsx @@ -0,0 +1,28 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.scss"; +import { images } from "../../data"; +import Button from "../../ui/Button"; + +interface IAstrologersProps { + onButtonClick: () => void; +} + +function Astrologers({ onButtonClick }: IAstrologersProps) { + return ( +
+
+ + Best psychics in the love & relationship area + + Astrologers +
+
+ ); +} + +export default Astrologers; diff --git a/src/components/ChatsPath/components/Astrologers/styles.module.scss b/src/components/ChatsPath/components/Astrologers/styles.module.scss new file mode 100644 index 0000000..19d58ba --- /dev/null +++ b/src/components/ChatsPath/components/Astrologers/styles.module.scss @@ -0,0 +1,30 @@ +.container { + padding: 50px 15px; + background: var(--secondary-800); +} + +.wrapper { + margin: 0 auto; + max-width: 1068px; + display: flex; + flex-direction: column; + align-items: center; +} + +.title { + font-family: Open Sans, sans-serif; + font-size: 24px; + line-height: 32px; + font-weight: 600; + text-align: center; + margin-bottom: 30px; + max-width: 796px; +} + +.image { + max-width: 500px; + width: 100%; + position: relative; + margin-left: auto; + margin-right: auto; +} diff --git a/src/components/ChatsPath/components/ChooseGender/index.tsx b/src/components/ChatsPath/components/ChooseGender/index.tsx new file mode 100644 index 0000000..02c97db --- /dev/null +++ b/src/components/ChatsPath/components/ChooseGender/index.tsx @@ -0,0 +1,68 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.scss"; +import { images } from "../../data"; +import { useDispatch } from "react-redux"; +import { actions } from "@/store"; + +interface IChooseGenderProps { + onSelectGender?: (gender: string) => void; +} + +function ChooseGender({ onSelectGender }: IChooseGenderProps) { + const dispatch = useDispatch(); + + const selectGender = (gender: string) => { + dispatch(actions.questionnaire.update({ gender })); + onSelectGender && onSelectGender(gender); + }; + + return ( +
+
+ + Choose your gender + +
    +
  • +
    + +
    +
  • +
  • +
    + +
    +
  • +
+

+ Our algorithm will match you to our top psychics. Get readings, + guidance and accurate answers from your psychic expert +

+
+
+ ); +} + +export default ChooseGender; diff --git a/src/components/ChatsPath/components/ChooseGender/styles.module.scss b/src/components/ChatsPath/components/ChooseGender/styles.module.scss new file mode 100644 index 0000000..d9b3a16 --- /dev/null +++ b/src/components/ChatsPath/components/ChooseGender/styles.module.scss @@ -0,0 +1,77 @@ +.container { + border-top-left-radius: 16px; + border-top-right-radius: 16px; + border: 1px solid var(--secondary); + background: var(--secondary-600); + padding: 20px 16px; +} + +.title { + margin-bottom: 14px; + text-align: center; + font-size: 20px; + font-weight: 600; +} + +.list { + display: flex; + justify-content: center; + margin-bottom: 8px; + + & > .item { + width: auto; + margin-left: 10px; + margin-right: 10px; + + & > .button-wrapper { + margin-top: 0; + margin-bottom: 30px; + + & > button { + padding: 0; + border: none; + height: auto; + width: auto; + background: transparent; + display: inline-flex; + align-items: center; + justify-content: center; + text-align: center; + text-decoration: none; + vertical-align: middle; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + align-self: center; + border-radius: 30px; + outline: none; + color: var(--typography-100); + font-size: 16px; + line-height: 24px; + transition: all 0.15s ease-in-out 0ms; + + &:active { + transform: scale(1.03); + } + + & > .button-label { + display: inherit; + align-items: inherit; + justify-content: inherit; + + & > img { + object-fit: contain; + width: 100%; + height: auto; + } + } + } + } + } +} + +.description { + font-size: 12px; + line-height: 130%; + text-align: center; +} diff --git a/src/components/ChatsPath/components/DrawerMenu/index.tsx b/src/components/ChatsPath/components/DrawerMenu/index.tsx new file mode 100644 index 0000000..c69a512 --- /dev/null +++ b/src/components/ChatsPath/components/DrawerMenu/index.tsx @@ -0,0 +1,37 @@ +import Drawer from "@mui/material/Drawer"; +import styles from "./styles.module.scss"; +import DrawerMenuList from "../DrawerMenuList"; +import { drawerMenuItems, sprites } from "../../data"; + +interface IDrawerMenuProps { + open: boolean; + toggleDrawer: (newOpen: boolean) => () => void; +} + +function DrawerMenu({ open, toggleDrawer }: IDrawerMenuProps) { + return ( + +
+ + + +
+ +
+ ); +} + +export default DrawerMenu; diff --git a/src/components/ChatsPath/components/DrawerMenu/styles.module.scss b/src/components/ChatsPath/components/DrawerMenu/styles.module.scss new file mode 100644 index 0000000..c02f495 --- /dev/null +++ b/src/components/ChatsPath/components/DrawerMenu/styles.module.scss @@ -0,0 +1,25 @@ +.drawer-paper { + width: 100%; + max-width: 312px; + background: var(--gradient-amethyst); + padding: 20px 15px; + color: var(--typography-200) !important; +} + +.close { + margin-bottom: 20px; + + & > .close-wrapper { + display: inline-flex; + align-items: center; + justify-content: center; + cursor: pointer; + + & > .close-icon { + fill: var(--typography-100); + width: 20px; + height: 20px; + flex-shrink: 0; + } + } +} diff --git a/src/components/ChatsPath/components/DrawerMenuList/index.tsx b/src/components/ChatsPath/components/DrawerMenuList/index.tsx new file mode 100644 index 0000000..ff709a0 --- /dev/null +++ b/src/components/ChatsPath/components/DrawerMenuList/index.tsx @@ -0,0 +1,24 @@ +import { IDrawerMenuItem } from "../../data"; +import styles from "./styles.module.scss"; + +interface IDrawerMenuListProps { + items: IDrawerMenuItem[]; +} + +function DrawerMenuList({ items }: IDrawerMenuListProps) { + return ( + + ); +} + +export default DrawerMenuList; diff --git a/src/components/ChatsPath/components/DrawerMenuList/styles.module.scss b/src/components/ChatsPath/components/DrawerMenuList/styles.module.scss new file mode 100644 index 0000000..6799d2f --- /dev/null +++ b/src/components/ChatsPath/components/DrawerMenuList/styles.module.scss @@ -0,0 +1,21 @@ +.container { + display: flex; + flex-direction: column; + justify-content: space-between; + height: 100%; +} + +.list { + margin-top: -10px; + margin-bottom: -10px; + + & > .item { + padding-top: 10px; + padding-bottom: 10px; + + & > .link { + font-size: 14px; + line-height: 20px; + } + } +} diff --git a/src/components/ChatsPath/components/Feedback/index.tsx b/src/components/ChatsPath/components/Feedback/index.tsx new file mode 100644 index 0000000..f84ddf3 --- /dev/null +++ b/src/components/ChatsPath/components/Feedback/index.tsx @@ -0,0 +1,22 @@ +import { welcomeReviews } from "../../data"; +import AppStoreReviews from "../AppStoreReviews"; +import Review from "../Review"; +import styles from "./styles.module.scss"; + +function Feedback() { + return ( +
+
+ + +
+ {welcomeReviews.map((review, index) => ( + + ))} +
+
+
+ ); +} + +export default Feedback; diff --git a/src/components/ChatsPath/components/Feedback/styles.module.scss b/src/components/ChatsPath/components/Feedback/styles.module.scss new file mode 100644 index 0000000..46d35d2 --- /dev/null +++ b/src/components/ChatsPath/components/Feedback/styles.module.scss @@ -0,0 +1,11 @@ +.container { + padding: 50px 15px; + background: var(--secondary-800); +} + +.wrapper { + margin: 0 auto; + max-width: 1108px; + padding-left: 10px; + padding-right: 10px; +} diff --git a/src/components/ChatsPath/components/Header/index.tsx b/src/components/ChatsPath/components/Header/index.tsx new file mode 100644 index 0000000..e8e8037 --- /dev/null +++ b/src/components/ChatsPath/components/Header/index.tsx @@ -0,0 +1,45 @@ +import { useNavigate } from "react-router-dom"; +import styles from "./styles.module.scss"; +import BackButton from "@/components/pages/ABDesign/v1/ui/BackButton"; +import Title from "@/components/Title"; +import Burger from "../../ui/Burger"; + +interface IHeaderProps { + isBackButtonVisible?: boolean; + isBurgerVisible?: boolean; + className?: string; + classNameTitle?: string; + onBack?: () => void; + onBurger?: () => void; +} + +function Header({ + classNameTitle = "", + isBackButtonVisible = true, + isBurgerVisible = true, + onBurger, + onBack, +}: IHeaderProps) { + const navigate = useNavigate(); + const handleBack = onBack ? onBack : () => navigate(-1); + + return ( +
+ {isBackButtonVisible && ( + + )} + + AURA + + {isBurgerVisible && ( + + )} +
+ ); +} + +export default Header; diff --git a/src/components/ChatsPath/components/Header/styles.module.scss b/src/components/ChatsPath/components/Header/styles.module.scss new file mode 100644 index 0000000..40ca0b9 --- /dev/null +++ b/src/components/ChatsPath/components/Header/styles.module.scss @@ -0,0 +1,43 @@ +.header { + display: flex; + align-items: center; + justify-content: center; + flex-grow: 0; + flex-shrink: 0; + width: 100%; + position: relative; + align-self: center; + padding: 17px 25px 0; + margin-bottom: 16px; +} + +.title { + font-size: 28px; + margin-bottom: 0; + font-weight: 500; + line-height: 100%; +} + +.back-button { + position: absolute; + left: 15px; + transition: all 0.1s ease-in-out 0ms; + + border: none; + background: inherit; + font-family: inherit; + font-size: inherit; + cursor: pointer; + padding: 0; + outline: none; +} + +.burger { + position: absolute; + right: 25px; + left: auto; + top: 18px; + bottom: 0; + display: flex; + align-items: center; +} diff --git a/src/components/ChatsPath/components/HowItWorks/index.tsx b/src/components/ChatsPath/components/HowItWorks/index.tsx new file mode 100644 index 0000000..9238fcf --- /dev/null +++ b/src/components/ChatsPath/components/HowItWorks/index.tsx @@ -0,0 +1,61 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.scss"; +import { images } from "../../data"; +import Button from "../../ui/Button"; + +interface IHowItWorksProps { + onButtonClick: () => void; +} + +function HowItWorks({ onButtonClick }: IHowItWorksProps) { + return ( +
+
+ + How it works + +
    +
  • + one +
    + + Create account + +

    + Answer simple questions to help us design your profile and + personalize your experience +

    +
    +
  • +
  • + two +
    + + Meet our best psychics + +

    + Get matched based on your answers and choose the best psychic to + chat with +

    +
    +
  • +
  • + three +
    + + Ask your questions + +

    + Start online chat to connect with relationship psychics and gain + clarity today +

    +
    +
  • +
+
+
+ ); +} + +export default HowItWorks; diff --git a/src/components/ChatsPath/components/HowItWorks/styles.module.scss b/src/components/ChatsPath/components/HowItWorks/styles.module.scss new file mode 100644 index 0000000..82630a1 --- /dev/null +++ b/src/components/ChatsPath/components/HowItWorks/styles.module.scss @@ -0,0 +1,49 @@ +.container { + padding: 50px 15px; + background: var(--secondary-800); +} + +.wrapper { + margin: 0 auto; + max-width: 1068px; +} + +.title { + font-family: Open Sans, sans-serif; + font-size: 24px; + text-align: center; + line-height: 32px; + font-weight: 600; + margin-bottom: 50px; +} + +.list { + display: flex; + flex-direction: column; + + & > .item { + display: flex; + margin-bottom: 40px; + text-align: left; + + & > img { + position: relative; + width: 75px; + height: 75px; + flex-shrink: 0; + margin-right: 20px; + color: transparent; + } + + & .item-title { + font-weight: 600; + margin-bottom: 5px; + text-align: left; + } + + & .item-description { + font-size: 14px; + line-height: 24px; + } + } +} diff --git a/src/components/ChatsPath/components/InputAnswerModal/index.tsx b/src/components/ChatsPath/components/InputAnswerModal/index.tsx new file mode 100644 index 0000000..2c45ab0 --- /dev/null +++ b/src/components/ChatsPath/components/InputAnswerModal/index.tsx @@ -0,0 +1,64 @@ +import Modal from "@mui/material/Modal"; +import styles from "./styles.module.scss"; +import Button, { IButtonProps } from "../../ui/Button"; +import { DetailedHTMLProps, InputHTMLAttributes } from "react"; + +interface IInputAnswerModalProps { + open: boolean; + inputProps: DetailedHTMLProps< + InputHTMLAttributes, + HTMLInputElement + >; + buttonProps: IButtonProps; + onClose: () => void; +} + +function InputAnswerModal({ + open, + buttonProps, + inputProps, + onClose, +}: IInputAnswerModalProps) { + return ( + +
+ +

Enter your own answer

+
+
+ +
+
+ +
+
+ ); +} + +export default InputAnswerModal; diff --git a/src/components/ChatsPath/components/InputAnswerModal/styles.module.scss b/src/components/ChatsPath/components/InputAnswerModal/styles.module.scss new file mode 100644 index 0000000..667c8cb --- /dev/null +++ b/src/components/ChatsPath/components/InputAnswerModal/styles.module.scss @@ -0,0 +1,85 @@ +.container { + position: relative; + background-color: var(--primary-100); + width: 330px; + padding: 40px 20px 16px; + border-radius: 16px; + + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.close-icon { + position: absolute; + top: 12px; + right: 12px; + opacity: 0.7; + width: 24px; + height: 24px; + border: none; + background: none; + + & > .close-icon-label { + display: inherit; + align-items: inherit; + justify-content: inherit; + + & > svg { + color: var(--secondary-600); + width: 16px; + height: 16px; + fill: currentColor; + transition: fill 0.3s ease-in-out, opacity 0.3s ease-in-out; + flex-shrink: 0; + display: inline-block; + } + } +} + +.title { + margin-bottom: 16px; + color: var(--typography-900); + text-align: center; + font-size: 24px; + font-weight: 600; + line-height: 150%; +} + +.input-container { + width: 100%; + position: relative; + + & > .input-wrapper { + position: relative; + cursor: text; + + & > input { + display: block; + font-weight: 400; + background-clip: padding-box; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + -webkit-appearance: none; + appearance: none; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + width: 100%; + height: 50px; + margin-bottom: 28px; + font-size: 16px; + line-height: 135%; + border: 1px solid var(--typography); + border-radius: 25px; + padding: 10px 15px; + color: var(--typography-900); + background-color: transparent; + } + } +} + +.button { + margin-top: 16px; + & > button { + height: 50px; + } +} diff --git a/src/components/ChatsPath/components/MultiplyAnswer/index.tsx b/src/components/ChatsPath/components/MultiplyAnswer/index.tsx new file mode 100644 index 0000000..336b3ce --- /dev/null +++ b/src/components/ChatsPath/components/MultiplyAnswer/index.tsx @@ -0,0 +1,42 @@ +import { IAnswer } from "../../data"; +import styles from "./styles.module.scss"; +import Checkbox from "../../ui/Checkbox"; + +interface IAnswerProps { + answer: IAnswer; + classNameContainer?: string; + active?: boolean; + onClick?: (answer: IAnswer) => void; +} + +function MultiplyAnswer({ + answer, + classNameContainer = "", + active = false, + onClick, +}: IAnswerProps) { + const handleClick = (event: React.MouseEvent) => { + event?.stopPropagation(); + event?.preventDefault(); + onClick && onClick(answer); + }; + + return ( +
+ {answer.name} + +
+ ); +} + +export default MultiplyAnswer; diff --git a/src/components/ChatsPath/components/MultiplyAnswer/styles.module.scss b/src/components/ChatsPath/components/MultiplyAnswer/styles.module.scss new file mode 100644 index 0000000..acfcf84 --- /dev/null +++ b/src/components/ChatsPath/components/MultiplyAnswer/styles.module.scss @@ -0,0 +1,27 @@ +.container { + min-height: 40px; + display: flex; + align-items: center; + justify-content: space-between; + font-weight: 600; + cursor: pointer; + transition: all 0.15s ease-in 0ms; + + padding: 16px; + border: 1px solid var(--primary); + box-shadow: 0 4px 4px rgba(0, 0, 0, 0.25); + border-radius: 16px; + + &.active { + background-color: rgba(#8e8cf0, 0.2); + } +} + +.text { + color: var(--typography-100); + line-height: 21px; + font-weight: 400; + display: flex; + align-items: center; + font-size: 16px; +} diff --git a/src/components/ChatsPath/components/MultiplyAnswers/index.tsx b/src/components/ChatsPath/components/MultiplyAnswers/index.tsx new file mode 100644 index 0000000..9c5fda0 --- /dev/null +++ b/src/components/ChatsPath/components/MultiplyAnswers/index.tsx @@ -0,0 +1,78 @@ +import { useDispatch, useSelector } from "react-redux"; +import { IAnswer } from "../../data"; +import MultiplyAnswer from "../MultiplyAnswer"; +import styles from "./styles.module.scss"; +import { actions, selectors } from "@/store"; + +interface IAnswersProps { + answers: IAnswer[]; + classNameAnswer?: string; + activeAnswer?: string; +} + +function MultiplyAnswers({ answers, classNameAnswer = "" }: IAnswersProps) { + const dispatch = useDispatch(); + const storeAnswers = useSelector(selectors.selectAnswers); + + const handleClickAll = (answer: IAnswer, storeAnswer: string[]) => { + if (storeAnswer?.length === answers.length) { + return dispatch( + actions.chats.updateAnswers({ + [answer.questionId]: [], + }) + ); + } + return dispatch( + actions.chats.updateAnswers({ + [answer.questionId]: answers.map((item) => item.value), + }) + ); + }; + + const handleClick = (answer: IAnswer) => { + const storeAnswer = (storeAnswers?.[ + answer.questionId as keyof typeof storeAnswers + ] || []) as string[]; + + if (answer.value === "all") { + return handleClickAll(answer, storeAnswer); + } + + if (storeAnswer?.includes(answer.value)) { + dispatch( + actions.chats.updateAnswers({ + [answer.questionId]: storeAnswer?.filter( + (item) => item !== answer.value && item !== "all" + ), + }) + ); + } else { + dispatch( + actions.chats.updateAnswers({ + [answer.questionId]: [...storeAnswer, answer.value], + }) + ); + } + }; + + return ( +
+
    + {answers.map((answer, index) => ( +
  • + +
  • + ))} +
+
+ ); +} + +export default MultiplyAnswers; diff --git a/src/components/ChatsPath/components/MultiplyAnswers/styles.module.scss b/src/components/ChatsPath/components/MultiplyAnswers/styles.module.scss new file mode 100644 index 0000000..4a2c9de --- /dev/null +++ b/src/components/ChatsPath/components/MultiplyAnswers/styles.module.scss @@ -0,0 +1,11 @@ +.container { + width: 100%; +} + +.list { + margin-bottom: -20px; + + & > .item { + padding-bottom: 10px; + } +} diff --git a/src/components/ChatsPath/components/Partners/index.tsx b/src/components/ChatsPath/components/Partners/index.tsx new file mode 100644 index 0000000..f3e09e1 --- /dev/null +++ b/src/components/ChatsPath/components/Partners/index.tsx @@ -0,0 +1,64 @@ +import { images } from "../../data"; +import styles from "./styles.module.scss"; + +function Partners() { + return ( +
+

As featured in

+
    +
  • +
    + The New York Times +
    +
  • +
  • +
    + Bustle +
    +
  • +
  • +
    + Hypebae +
    +
  • +
  • +
    + Refinery +
    +
  • +
  • +
    + Cosmopolitan +
    +
  • +
+
+ ); +} + +export default Partners; diff --git a/src/components/ChatsPath/components/Partners/styles.module.scss b/src/components/ChatsPath/components/Partners/styles.module.scss new file mode 100644 index 0000000..46e92da --- /dev/null +++ b/src/components/ChatsPath/components/Partners/styles.module.scss @@ -0,0 +1,60 @@ +.container { + background: var(--typography-900); + padding: 30px 15px; +} + +.title { + font-family: Open Sans, sans-serif; + font-size: 24px; + text-align: center; + line-height: 32px; + font-weight: 600; + margin-bottom: 30px; +} + +.list { + max-width: 360px; + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-items: center; + margin-left: auto; + margin-right: auto; + margin-bottom: -30px; + + & > .item { + margin-bottom: 30px; + + & img { + display: inline-block; + width: 100%; + height: 100%; + color: transparent; + } + } +} + +.newYorkTimes { + width: 215px; + height: 28px; +} + +.bustle { + width: 74px; + height: 20px; +} + +.hypebae { + width: 85px; + height: 22px; +} + +.refinery { + width: 60px; + height: 37px; +} + +.cosmopolitan { + width: 131px; + height: 19px; +} diff --git a/src/components/ChatsPath/components/ProgressBar/index.tsx b/src/components/ChatsPath/components/ProgressBar/index.tsx new file mode 100644 index 0000000..df6cb1a --- /dev/null +++ b/src/components/ChatsPath/components/ProgressBar/index.tsx @@ -0,0 +1,121 @@ +import { progressBarSteps } from "../../data"; +import styles from "./styles.module.scss"; + +interface IProgressBarProps { + currentStep: number; +} + +function calculateProgress(currentStep: number) { + const totalProgress: number[] = []; + let accumulatedLength = 0; + + progressBarSteps.forEach((step) => { + if (currentStep >= accumulatedLength + step.length) { + totalProgress.push(100); + } else if ( + currentStep > accumulatedLength && + currentStep < accumulatedLength + step.length + ) { + const stepProgress = + ((currentStep - accumulatedLength) / step.length) * 100; + totalProgress.push(stepProgress); + } else { + totalProgress.push(0); + } + accumulatedLength += step.length; + }); + + return totalProgress; +} + +function ProgressBar({ currentStep }: IProgressBarProps) { + const totalProgress = calculateProgress(currentStep); + const totalLength = progressBarSteps.reduce( + (acc, step) => acc + step.length, + 0 + ); + + return ( +
+
+
+
+ + Your answers are confidential +
+
+ {currentStep}/{totalLength} +
+
+
+ {progressBarSteps.map((step, index) => ( +
+
{index + 1}
+ + + + + +
+
+ + + +
+
+
+ ))} +
+
{progressBarSteps.length + 1}
+ + + + + +
+
+
+
+ ); +} + +export default ProgressBar; diff --git a/src/components/ChatsPath/components/ProgressBar/styles.module.scss b/src/components/ChatsPath/components/ProgressBar/styles.module.scss new file mode 100644 index 0000000..d004019 --- /dev/null +++ b/src/components/ChatsPath/components/ProgressBar/styles.module.scss @@ -0,0 +1,162 @@ +.container { + margin-bottom: 15px; + text-align: center; + max-width: 330px; + margin-left: auto; + margin-right: auto; +} + +.wrapper { + margin-bottom: 15px; +} + +.header { + margin-bottom: 12px; + display: flex; + justify-content: flex-end; + align-items: center; + + & .text { + display: inline-block; + margin-left: 4px; + color: var(--typography-200-with-opacity-50); + text-align: center; + font-size: 12px; + line-height: 120%; + } + + & > .counter { + margin-left: 36px; + padding: 4px 8px; + border-radius: 50px; + background: var(--primary-800); + color: var(--primary-200); + font-size: 12px; + font-weight: 600; + line-height: 1; + } +} + +.stepper { + display: flex; + flex-direction: row; + -webkit-box-align: center; + align-items: center; + justify-content: center; + background: transparent !important; + z-index: 1; + padding: 0 0 32px !important; +} + +.step { + padding: 0 !important; + display: flex; + position: relative; + + &.completed { + .circle { + background: var(--primary-300); + color: var(--typography-800); + } + + .progress::after { + font-weight: 700; + color: var(--typography-100); + } + } + + & > .circle { + background: var(--primary-800); + width: 16px; + height: 16px; + border-radius: 50%; + position: absolute; + display: flex; + justify-content: center; + align-items: center; + color: var(--typography-300); + text-align: center; + font-size: 10px; + font-weight: 600; + line-height: 150%; + } + + .step-label { + display: flex; + -webkit-box-align: center; + align-items: center; + + & > .svg { + flex-shrink: 0; + display: flex; + padding-right: 0; + + & > svg { + user-select: none; + fill: currentcolor; + flex-shrink: 0; + font-size: 1.5rem; + display: block; + transition: color 150ms cubic-bezier(0.4, 0, 0.2, 1); + width: 16px; + height: 16px; + border-radius: 50%; + + &.completed { + color: var(--primary-800); + border: none; + } + } + } + } +} + +.progress { + position: relative; + padding: 0 !important; + background: none !important; + width: 92px; + color: rgba(0, 0, 0, 0.87); + box-shadow: none; + display: flex; + flex-direction: row; + -webkit-box-pack: justify; + justify-content: space-between; + -webkit-box-align: center; + align-items: center; + transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1); + + &::after { + content: attr(data-label); + width: 95px; + position: absolute; + left: 50%; + top: 16px; + transform: translateX(-50%); + text-align: center; + font-size: 12px; + line-height: 150%; + color: var(--typography-400); + } + + & > .progress-bar { + position: relative; + overflow: hidden; + display: block; + width: 100%; + height: 4px; + background: var(--primary-800); + z-index: 0; + + & > .progress-bar-fill { + width: 100%; + position: absolute; + left: 0px; + bottom: 0px; + top: 0px; + transition: transform 0.4s linear; + transform-origin: left center; + background: var(--primary-300); + } + } +} diff --git a/src/components/ChatsPath/components/Review/index.tsx b/src/components/ChatsPath/components/Review/index.tsx new file mode 100644 index 0000000..71b0738 --- /dev/null +++ b/src/components/ChatsPath/components/Review/index.tsx @@ -0,0 +1,46 @@ +import { images, IReview } from "../../data"; +import Stars from "../Stars"; +import styles from "./styles.module.scss"; + +type TReviewProps = IReview; + +function Review({ avatar, name, date, text }: TReviewProps) { + return ( +
+
+ avatar +
+ {name} + {date} +
+ +
+
+
+ + + +

{text}

+
+
+
+ ); +} + +export default Review; diff --git a/src/components/ChatsPath/components/Review/styles.module.scss b/src/components/ChatsPath/components/Review/styles.module.scss new file mode 100644 index 0000000..13a835a --- /dev/null +++ b/src/components/ChatsPath/components/Review/styles.module.scss @@ -0,0 +1,76 @@ +.container { + margin-left: auto; + margin-right: auto; + border-radius: 20px; + width: 100%; + position: relative; + background: var(--typography-100); + color: var(--typography-800); + padding: 16px 25px 16px 16px; + display: flex; + flex-direction: column; + overflow: hidden; + height: auto !important; + margin-bottom: 20px; +} + +.info-wrapper { + display: flex; + align-items: flex-start; +} + +.avatar { + display: block; + border-radius: 50%; + color: transparent; +} + +.info { + display: flex; + flex-direction: column; + margin-left: 10px; + max-width: 55%; + flex-basis: 50%; + overflow: hidden; + text-align: left; +} + +.name { + font-weight: 600; + font-size: 18px; + line-height: 24px; + max-height: 48px; + overflow: hidden; + text-overflow: ellipsis; +} + +.date { + font-size: 12px; + line-height: 16px; + color: var(--typography-300); +} + +.quote-wrapper { + flex-grow: 1; + overflow-y: auto; +} + +.quote-container { + display: flex; + margin-top: 10px; + overflow: hidden; + text-overflow: ellipsis; + margin-bottom: 10px; +} + +.text { + width: 100%; + font-size: 14px; + line-height: 24px; + margin-left: 8px; + text-align: left; +} + +.stars { + margin-left: auto; +} diff --git a/src/components/ChatsPath/components/Review2/index.tsx b/src/components/ChatsPath/components/Review2/index.tsx new file mode 100644 index 0000000..d54fd2e --- /dev/null +++ b/src/components/ChatsPath/components/Review2/index.tsx @@ -0,0 +1,39 @@ +import { images, IReview, sprites } from "../../data"; +import Stars from "../Stars"; +import styles from "./styles.module.scss"; + +type TReviewProps = IReview; + +function Review2({ avatar, name, date, text }: TReviewProps) { + return ( +
+
+ +

{text}

+
+
+
+ avatar +
+

{name}

+
+ + Verified user +
+
+
+ {date} +
+
+ ); +} + +export default Review2; diff --git a/src/components/ChatsPath/components/Review2/styles.module.scss b/src/components/ChatsPath/components/Review2/styles.module.scss new file mode 100644 index 0000000..f6d042c --- /dev/null +++ b/src/components/ChatsPath/components/Review2/styles.module.scss @@ -0,0 +1,69 @@ +.container { + margin-left: auto; + margin-right: auto; + border-radius: 20px; + width: 100%; + position: relative; + background: var(--secondary-600); + color: var(--typography-800); + padding: 16px; + display: flex; + flex-direction: column; + justify-content: space-between; + overflow: hidden; + margin-bottom: 20px; + text-align: left; + height: 310px; + width: 303px; +} + +.text { + margin-top: 16px; + color: var(--typography-100); + font-size: 16px; + line-height: 1.65; +} + +.footer { + display: flex; + justify-content: space-between; + align-items: flex-end; +} + +.info-wrapper { + display: flex; +} + +.info { + margin-left: 12px; + + & > .name { + color: var(--typography-100); + font-size: 14px; + font-weight: 600; + line-height: 1.35; + } + + & > .verified { + margin-top: 2px; + display: flex; + + & > svg { + fill: #219653; + flex-shrink: 0; + } + + & > span { + margin-left: 4px; + color: var(--typography-300); + font-size: 12px; + line-height: 1.3; + } + } +} + +.date { + color: var(--typography-300); + font-size: 12px; + line-height: 1.3334; +} diff --git a/src/components/ChatsPath/components/Stars/index.tsx b/src/components/ChatsPath/components/Stars/index.tsx new file mode 100644 index 0000000..a252b99 --- /dev/null +++ b/src/components/ChatsPath/components/Stars/index.tsx @@ -0,0 +1,83 @@ +import styles from "./styles.module.scss"; + +interface IStarsProps { + containerClassName?: string; + color?: string; +} + +function Stars({ + color = "rgb(250, 175, 0)", + containerClassName = "", +}: IStarsProps) { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} + +export default Stars; diff --git a/src/components/ChatsPath/components/Stars/styles.module.scss b/src/components/ChatsPath/components/Stars/styles.module.scss new file mode 100644 index 0000000..6924152 --- /dev/null +++ b/src/components/ChatsPath/components/Stars/styles.module.scss @@ -0,0 +1,27 @@ +.stars { + display: inline-flex; + position: relative; + font-size: 1.5rem; + color: rgb(250, 175, 0); + cursor: pointer; + text-align: left; + width: min-content; + -webkit-tap-highlight-color: transparent; + pointer-events: none; +} + +.star { + display: flex; + pointer-events: none; + transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1); + + & > svg { + width: 1em; + height: 1em; + display: inline-block; + fill: currentcolor; + flex-shrink: 0; + font-size: inherit; + transition: fill 200ms cubic-bezier(0.4, 0, 0.2, 1); + } +} diff --git a/src/components/ChatsPath/components/Summary/index.tsx b/src/components/ChatsPath/components/Summary/index.tsx new file mode 100644 index 0000000..d829c44 --- /dev/null +++ b/src/components/ChatsPath/components/Summary/index.tsx @@ -0,0 +1,456 @@ +import { images } from "../../data"; +import styles from "./styles.module.scss"; + +function Summary() { + return ( +
+
+

+ Exclusive livechats with + professional + psychics +

+
+ + + astrologers + +
+
    +
  • + + + + + + + + + + + Learn about the possible twists of fate in your love life + (marriage, divorce, pregnancy and more). + +
  • +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gain insight on what you need to do in order to find your way to + happiness in the present and in the future. + +
  • +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Get peace of mind, insight on relationships and closure. + +
  • +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + Resolve unanswered questions through a professional medium + reading. + +
  • +
  • + + + + + + + + + + + + + + + + + + + + + Find out if your partner is your soul mate or a recipe for + disaster. + +
  • +
+
+
+ ); +} + +export default Summary; diff --git a/src/components/ChatsPath/components/Summary/styles.module.scss b/src/components/ChatsPath/components/Summary/styles.module.scss new file mode 100644 index 0000000..41efc6e --- /dev/null +++ b/src/components/ChatsPath/components/Summary/styles.module.scss @@ -0,0 +1,61 @@ +.container { + background: var(--secondary-700); + padding: 50px 15px; +} + +.wrapper { + margin: 0 auto; + max-width: 1068px; + display: flex; + align-items: center; + flex-direction: column; +} + +.title { + font-family: Open Sans, sans-serif; + font-size: 24px; + text-align: center; + line-height: 32px; + font-weight: 600; + margin-bottom: 50px; + max-width: 796px; + + & > .title-gradient { + background: var(--gradient-pink-base); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + } +} + +.astrologers { + width: 100%; + max-width: 539px; + margin-bottom: 50px; +} + +.list { + display: flex; + flex-direction: column; + max-width: 590px; + margin-left: auto; + margin-right: auto; + text-align: left; + + & > .list-item { + display: flex; + align-items: center; + margin-bottom: 30px; + + & > svg { + width: 48px; + flex-shrink: 0; + } + + & > .item-text { + font-size: 14px; + line-height: 24px; + margin-left: 20px; + } + } +} diff --git a/src/components/ChatsPath/components/Tip/index.tsx b/src/components/ChatsPath/components/Tip/index.tsx new file mode 100644 index 0000000..1db97e6 --- /dev/null +++ b/src/components/ChatsPath/components/Tip/index.tsx @@ -0,0 +1,18 @@ +import styles from "./styles.module.scss"; + +interface ITipProps { + icon: string; + text: string; +} + +function Tip({ icon, text }: ITipProps) { + return ( +
+

+ {icon} {text} +

+
+ ); +} + +export default Tip; diff --git a/src/components/ChatsPath/components/Tip/styles.module.scss b/src/components/ChatsPath/components/Tip/styles.module.scss new file mode 100644 index 0000000..548a5d0 --- /dev/null +++ b/src/components/ChatsPath/components/Tip/styles.module.scss @@ -0,0 +1,22 @@ +.tip-container { + text-align: left; + padding: 10px 15px; + background: var(--white-with-opacity-5); + border: 1px solid var(--white-with-opacity-15); + border-radius: 8px; + margin-bottom: 20px; + display: flex; + + & > .tip { + display: flex; + font-size: 13px; + line-height: 145%; + + & > span { + margin-top: 7px; + font-size: 24px; + margin-right: 10px; + height: 100%; + } + } +} diff --git a/src/components/ChatsPath/components/YesNoButtons/index.tsx b/src/components/ChatsPath/components/YesNoButtons/index.tsx new file mode 100644 index 0000000..51c5128 --- /dev/null +++ b/src/components/ChatsPath/components/YesNoButtons/index.tsx @@ -0,0 +1,60 @@ +import styles from "./styles.module.scss"; + +interface IYesNoButtonProps { + onClick: (answer: "yes" | "no") => void; +} + +function YesNoButtons({ onClick }: IYesNoButtonProps) { + return ( +
+
+ +
+
+ +
+
+ ); +} + +export default YesNoButtons; diff --git a/src/components/ChatsPath/components/YesNoButtons/styles.module.scss b/src/components/ChatsPath/components/YesNoButtons/styles.module.scss new file mode 100644 index 0000000..0be3a87 --- /dev/null +++ b/src/components/ChatsPath/components/YesNoButtons/styles.module.scss @@ -0,0 +1,58 @@ +.container { + margin-top: 24px; + width: 100%; + display: flex; +} + +.button-container { + height: 50px; + flex-basis: calc(50% - 6px); + margin-top: 0; + margin-bottom: 0; + + &:not(:last-child) { + margin-right: 12px; + } + + & > .button { + display: inline-flex; + align-items: center; + text-align: center; + text-decoration: none; + vertical-align: middle; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + padding: 5px 10px; + align-self: center; + outline: none; + color: var(--typography-100); + font-size: 16px; + line-height: 24px; + transition: all 0.15s ease-in-out 0ms; + width: 100%; + height: 100%; + justify-content: center; + background: none; + border-radius: 30px; + border: 1px solid var(--primary); + + &:active { + transform: scale(1.03); + } + + & > .label { + display: inherit; + align-items: inherit; + justify-content: inherit; + + & > .text { + margin-left: 8px; + font-size: 16px; + font-weight: 600; + line-height: 135%; + padding-right: 6px; + } + } + } +} diff --git a/src/components/ChatsPath/components/ZodiacWheel/index.tsx b/src/components/ChatsPath/components/ZodiacWheel/index.tsx new file mode 100644 index 0000000..d677ded --- /dev/null +++ b/src/components/ChatsPath/components/ZodiacWheel/index.tsx @@ -0,0 +1,52 @@ +import { getZodiacSignByDate } from "@/services/zodiac-sign"; +import { images } from "../../data"; +import ZodiacWheelSVG from "../../ui/ZodiacWheelSVG"; +import styles from "./styles.module.scss"; + +interface IZodiacWheelProps { + date: string; +} + +const zodiacs = [ + "Gemini", + "Cancer", + "Leo", + "Virgo", + "Libra", + "Scorpio", + "Sagittarius", + "Capricorn", + "Aquarius", + "Pisces", + "Aries", + "Taurus", +]; + +function ZodiacWheel({ date }: IZodiacWheelProps) { + const zodiac = getZodiacSignByDate(date); + + const getWheelRotation = () => { + const index = zodiacs.indexOf(zodiac); + if (index === -1) return 0; + return index * 30; + }; + + return ( +
+ + wheel arrow +
+ ); +} + +export default ZodiacWheel; diff --git a/src/components/ChatsPath/components/ZodiacWheel/styles.module.scss b/src/components/ChatsPath/components/ZodiacWheel/styles.module.scss new file mode 100644 index 0000000..a1f8eb8 --- /dev/null +++ b/src/components/ChatsPath/components/ZodiacWheel/styles.module.scss @@ -0,0 +1,23 @@ +.container { + position: relative; + width: 250px; + height: 125px; + overflow: hidden; + margin-left: auto; + margin-right: auto; +} + +.zodiac-wheel { + & path { + fill: var(--secondary); + } +} + +.wheel-arrow { + position: absolute; + top: 0; + left: 50%; + right: 50%; + transform: translateX(-50%); + color: transparent; +} diff --git a/src/components/ChatsPath/data/index.tsx b/src/components/ChatsPath/data/index.tsx new file mode 100644 index 0000000..b1a9087 --- /dev/null +++ b/src/components/ChatsPath/data/index.tsx @@ -0,0 +1,96 @@ +import React from "react"; + +export const sprites = "/chats/sprites.svg"; +export const images = (path: string) => `/chats/${path}`; + +export interface IReview { + avatar: string; + name: string; + date: string; + text: string; +} + +export const welcomeReviews: IReview[] = [ + { + avatar: "angel.webp", + name: "Angel", + date: "06/09/2021", + text: "Absolutely incredible - readings have helped me in ways I never knew were possible. Thank you isn’t enough to describe how grateful I am. The consultation helped me figure out my relationship and mend fences with my husband. ", + }, + { + avatar: "hanna.webp", + name: "Hanna", + date: "29/08/2021", + text: "It was really helpful. Finally, I let go of my ex-boyfriend, knowing he no longer felt anything for me. It made me feel so much better! Now I clearly understand what I should do with my life. I'll contact you again for advice and support. ", + }, + { + avatar: "christofer.webp", + name: "Christofer", + date: "11/10/2021", + text: "So accurate with readings! I am shocked! Such a great soul that will do his best to help as much as possible and be very transparent if needed! Very happy with this site! ❤️", + }, +]; + +interface IProgressBarSteps { + name: string; + length: number; + index: number; +} + +export const progressBarSteps: IProgressBarSteps[] = [ + { + index: 1, + name: "Your profile", + length: 5, + }, + { + index: 2, + name: "Personal traits", + length: 16, + }, + { + index: 3, + name: "Preferences", + length: 8, + }, +]; + +export interface IAnswer { + id: number; + value: string; + name: string | React.ReactNode; + questionId: string; + onClick?: () => void; +} + +export interface IDrawerMenuItem { + text: string; + link: string; +} + +export const drawerMenuItems: IDrawerMenuItem[] = [ + { + text: "Privacy policy", + link: "https://aura.wit.life/privacy", + }, + { + text: "Terms of use", + link: "https://aura.wit.life/terms", + }, + { + text: "Money back policy", + link: "https://aura.wit.life/privacy", + }, + { + text: "Cookie policy", + link: "https://aura.wit.life/privacy", + }, + { + text: "FAQ", + link: "https://aura.wit.life/privacy", + }, + { + text: "Contact us", + link: "https://witapps.us/en#contact-us", + }, +]; diff --git a/src/components/ChatsPath/hooks/useUpdateStep.ts b/src/components/ChatsPath/hooks/useUpdateStep.ts new file mode 100644 index 0000000..9b1622a --- /dev/null +++ b/src/components/ChatsPath/hooks/useUpdateStep.ts @@ -0,0 +1,12 @@ +import { actions } from "@/store"; +import { useEffect } from "react"; +import { useDispatch } from "react-redux"; + + +export const useUpdateStep = (step: number) => { + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(actions.chats.updateCurrentStep(step)); + }, [dispatch, step]); +}; \ No newline at end of file diff --git a/src/components/ChatsPath/pages/AnswerHub/index.tsx b/src/components/ChatsPath/pages/AnswerHub/index.tsx new file mode 100644 index 0000000..ca5e902 --- /dev/null +++ b/src/components/ChatsPath/pages/AnswerHub/index.tsx @@ -0,0 +1,65 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import Button from "../../ui/Button"; +import AnimateMessages, { + IAnimateMessage, +} from "../../components/AnimateMessages"; + +const messages: IAnimateMessage[] = [ + { + name: "Taylor", + text: "Will my ex and I get back together?", + avatar: "Avatar-2.webp", + }, + { + name: "Shawn", + text: "When will I start a new relationship?", + avatar: "Avatar-4.webp", + }, + { + name: "Philip", + text: "How is my ex feeling about me?", + avatar: "Avatar-6.webp", + }, + { + name: "Darrell", + text: "Is there anything unresolved with my ex?", + avatar: "Avatar-8.webp", + }, + { + name: "Arthur", + text: "Does my ex think about me?", + avatar: "Avatar-10.webp", + }, +]; + +function AnswerHub() { + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsQuizWhatYouWant()); + }; + + return ( +
+ + + Get answers to every question that bothers you + +

+ Our experts already helped 10 million men with their + personal questions, and look forward to{" "} + + guiding you towards confident choices + +

+ +
+ ); +} + +export default AnswerHub; diff --git a/src/components/ChatsPath/pages/AnswerHub/styles.module.scss b/src/components/ChatsPath/pages/AnswerHub/styles.module.scss new file mode 100644 index 0000000..b9bb72b --- /dev/null +++ b/src/components/ChatsPath/pages/AnswerHub/styles.module.scss @@ -0,0 +1,51 @@ +.container { + max-width: 360px; + width: 100%; + padding-left: 16px; + padding-right: 16px; + padding-top: 16px; + margin: 0 auto; + text-align: left; +} + +.title { + color: var(--typography-100); + font-size: 20px; + font-weight: 700; + line-height: 150%; + text-align: center; + margin-bottom: 16px; +} + +.text { + color: var(--typography-100); + font-size: 14px; + font-weight: 400; + line-height: 135%; + text-align: center; + margin-bottom: 80px; + + & > strong { + font-weight: 700; + } + + & > .purple { + color: var(--primary); + } +} + +.button { + margin: 0; + position: fixed; + left: 50%; + transform: translateX(-50%); + bottom: calc(0dvh + 30px); + & > button { + height: 50px; + font-weight: 600; + } + + &.back-button > button { + background: transparent; + } +} diff --git a/src/components/ChatsPath/pages/Answers/BelieveInSpirituality/index.tsx b/src/components/ChatsPath/pages/Answers/BelieveInSpirituality/index.tsx new file mode 100644 index 0000000..6195a0f --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/BelieveInSpirituality/index.tsx @@ -0,0 +1,50 @@ +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import Answers from "@/components/ChatsPath/components/Answers"; + +function BelieveInSpirituality() { + useUpdateStep(22); + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsQuizReadingExperience()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "yes", + name: "Yes", + questionId: "believeInSpirituality", + onClick: handleNext, + }, + { + id: 2, + value: "no", + name: "No", + questionId: "believeInSpirituality", + onClick: handleNext, + }, + { + id: 3, + value: "not_sure", + name: "Not sure", + questionId: "believeInSpirituality", + onClick: handleNext, + }, + ]; + + return ( + <> +

+ Do you believe in spirituality? +

+ + + ); +} + +export default BelieveInSpirituality; diff --git a/src/components/ChatsPath/pages/Answers/BelieveInSpirituality/styles.module.scss b/src/components/ChatsPath/pages/Answers/BelieveInSpirituality/styles.module.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/components/ChatsPath/pages/Answers/Date/index.tsx b/src/components/ChatsPath/pages/Answers/Date/index.tsx new file mode 100644 index 0000000..99e0637 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/Date/index.tsx @@ -0,0 +1,55 @@ +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import { useDispatch, useSelector } from "react-redux"; +import { actions, selectors } from "@/store"; +import { DatePicker } from "@/components/DateTimePicker"; +import { useState } from "react"; +import Button from "@/components/ChatsPath/ui/Button"; +import ZodiacWheel from "@/components/ChatsPath/components/ZodiacWheel"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; + +function Date() { + const dispatch = useDispatch(); + useUpdateStep(4); + const navigate = useNavigate(); + const birthdate = useSelector(selectors.selectBirthdate); + const [isDisabled, setIsDisabled] = useState(true); + + const handleNext = () => { + navigate(routes.client.chatsQuizParentStatus()); + }; + + const handleValid = (birthdate: string) => { + dispatch(actions.form.addDate(birthdate)); + setIsDisabled(birthdate === ""); + }; + + return ( + <> + + +

+ What is your birthday? +

+ + setIsDisabled(true)} + inputClassName="date-picker-input" + /> + + + + ); +} + +export default Date; diff --git a/src/components/ChatsPath/pages/Answers/Date/styles.module.scss b/src/components/ChatsPath/pages/Answers/Date/styles.module.scss new file mode 100644 index 0000000..ee98d78 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/Date/styles.module.scss @@ -0,0 +1,11 @@ +.button { + margin-top: 30px; + & > button { + height: 50px; + width: 100%; + } +} + +.title { + margin-top: 24px; +} diff --git a/src/components/ChatsPath/pages/Answers/DecisionGuidance/index.tsx b/src/components/ChatsPath/pages/Answers/DecisionGuidance/index.tsx new file mode 100644 index 0000000..d4690f0 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/DecisionGuidance/index.tsx @@ -0,0 +1,83 @@ +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import Answers from "@/components/ChatsPath/components/Answers"; +import AnswerDescription, { + IAnswerDescriptionProps, +} from "@/components/ChatsPath/components/AnswerDescription"; +import { useSelector } from "react-redux"; +import { selectors } from "@/store"; +import Button from "@/components/ChatsPath/ui/Button"; + +function DecisionGuidance() { + useUpdateStep(18); + const navigate = useNavigate(); + const answer = useSelector(selectors.selectAnswers)?.decisionGuidance; + + const handleNext = () => { + navigate(routes.client.chatsQuizResonateLove()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "yes", + name: "Yes", + questionId: "decisionGuidance", + }, + { + id: 2, + value: "sometimes", + name: "Sometimes", + questionId: "decisionGuidance", + }, + { + id: 3, + value: "not_sure", + name: "Not sure", + questionId: "decisionGuidance", + }, + ]; + + const descriptions: Record = { + yes: { + title: "🙌 Guided decisions bring positive results", + description: + "Aura psychics are here to help you understand which important decision to make in order to achieve happiness", + }, + sometimes: { + title: "🙌 It's natural to need guidance at times", + description: + "Aura psychics are here to help you understand which important decisions to make whenever you need it", + }, + not_sure: { + title: "🙌 Guided decisions bring positive results", + description: + "Aura psychics will help you uncover and understand what you truly need at this moment", + }, + }; + + return ( + <> +

+ Do you feel that you need guidance on which important decision to make? +

+ + {!!answer && ( + + )} + {!!answer && ( + + )} + + ); +} + +export default DecisionGuidance; diff --git a/src/components/ChatsPath/pages/Answers/DecisionGuidance/styles.module.scss b/src/components/ChatsPath/pages/Answers/DecisionGuidance/styles.module.scss new file mode 100644 index 0000000..28d68da --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/DecisionGuidance/styles.module.scss @@ -0,0 +1,7 @@ +.button { + margin-top: 30px; + & > button { + height: 50px; + width: 100%; + } +} diff --git a/src/components/ChatsPath/pages/Answers/Goal/index.tsx b/src/components/ChatsPath/pages/Answers/Goal/index.tsx new file mode 100644 index 0000000..e50de22 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/Goal/index.tsx @@ -0,0 +1,55 @@ +import Answers from "@/components/ChatsPath/components/Answers"; +import { IAnswer } from "../../../data"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import styles from "./styles.module.scss"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; + +function Goal() { + useUpdateStep(2); + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsGoalSetup()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "about_ex", + name: "💖 Find out about my ex", + questionId: "goal", + onClick: handleNext, + }, + { + id: 2, + value: "give_advice", + name: "👩‍❤️‍👨 Give advice for my love life", + questionId: "goal", + onClick: handleNext, + }, + { + id: 3, + value: "give_guidance", + name: "✨ Give guidance on my future", + questionId: "goal", + onClick: handleNext, + }, + { + id: 3, + value: "all", + name: "🔮 All above", + questionId: "goal", + onClick: handleNext, + }, + ]; + + return ( + <> +

How can our psychic help you?

+ + + ); +} + +export default Goal; diff --git a/src/components/ChatsPath/pages/Answers/Goal/styles.module.scss b/src/components/ChatsPath/pages/Answers/Goal/styles.module.scss new file mode 100644 index 0000000..5b5f01e --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/Goal/styles.module.scss @@ -0,0 +1,3 @@ +.answer { + justify-content: flex-start; +} diff --git a/src/components/ChatsPath/pages/Answers/GuidanceArea/index.tsx b/src/components/ChatsPath/pages/Answers/GuidanceArea/index.tsx new file mode 100644 index 0000000..3cbf64e --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/GuidanceArea/index.tsx @@ -0,0 +1,102 @@ +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import MultiplyAnswers from "@/components/ChatsPath/components/MultiplyAnswers"; +import Button from "@/components/ChatsPath/ui/Button"; +import { useSelector } from "react-redux"; +import { selectors } from "@/store"; + +function GuidanceArea() { + useUpdateStep(27); + const navigate = useNavigate(); + const answer = useSelector(selectors.selectAnswers)?.guidanceArea; + + const handleNext = () => { + if (!answer?.length) return; + navigate(routes.client.chatsQuizPsychicComfortable()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "love_relationship", + name: ( + + 💖 Love & Relationship + + ), + questionId: "guidanceArea", + }, + { + id: 2, + value: "destiny_life", + name: ( + + 🛤️ Destiny & Life path + + ), + questionId: "guidanceArea", + }, + { + id: 3, + value: "career_work", + name: ( + + 💼 Career & Work + + ), + questionId: "guidanceArea", + }, + { + id: 4, + value: "future_telling", + name: ( + + 🔮 Future telling + + ), + questionId: "guidanceArea", + }, + { + id: 5, + value: "family_friends", + name: ( + + 💍 Family & Friends + + ), + questionId: "guidanceArea", + }, + { + id: 6, + value: "spirit_guidance", + name: ( + + 🧿 Spirit guidance + + ), + questionId: "guidanceArea", + }, + ]; + + return ( + <> +

+ What area do you need help with? +

+

Select all that apply

+ + + + ); +} + +export default GuidanceArea; diff --git a/src/components/ChatsPath/pages/Answers/GuidanceArea/styles.module.scss b/src/components/ChatsPath/pages/Answers/GuidanceArea/styles.module.scss new file mode 100644 index 0000000..e68e11d --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/GuidanceArea/styles.module.scss @@ -0,0 +1,29 @@ +.subtitle { + color: var(--typography-200); + text-align: center; + font-size: 14px; + line-height: 150%; + margin-bottom: 24px; +} + +.answer { + display: flex; + align-items: center; + + & > span { + font-size: 24px; + margin-right: 8px; + } +} + +.button { + position: fixed; + left: 50%; + transform: translateX(-50%); + bottom: calc(0dvh + 16px); + + & > button { + height: 50px; + font-weight: 600; + } +} diff --git a/src/components/ChatsPath/pages/Answers/HeadOrHeart/index.tsx b/src/components/ChatsPath/pages/Answers/HeadOrHeart/index.tsx new file mode 100644 index 0000000..29497d4 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/HeadOrHeart/index.tsx @@ -0,0 +1,83 @@ +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import Answers from "@/components/ChatsPath/components/Answers"; +import AnswerDescription, { + IAnswerDescriptionProps, +} from "@/components/ChatsPath/components/AnswerDescription"; +import { useSelector } from "react-redux"; +import { selectors } from "@/store"; +import Button from "@/components/ChatsPath/ui/Button"; + +function HeadOrHeart() { + useUpdateStep(15); + const navigate = useNavigate(); + const answer = useSelector(selectors.selectAnswers)?.headOrHeart; + + const handleNext = () => { + navigate(routes.client.chatsQuizHowConfident()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "heart", + name: "Heart", + questionId: "headOrHeart", + }, + { + id: 2, + value: "head", + name: "Head", + questionId: "headOrHeart", + }, + { + id: 3, + value: "both", + name: "Both", + questionId: "headOrHeart", + }, + ]; + + const descriptions: Record = { + heart: { + title: "💕 You are an intuitive decision-maker", + description: + "Feelings and intuition can sometimes lead you to rushed decisions. Our psychics can guide you to better choices.", + }, + head: { + title: "🧠 You are a rational thinker", + description: + "Relying on logic and facts, you may ignore your intuition and miss big chances. Aura psychics will help you make better decisions.", + }, + both: { + title: "⚖️ You are a balanced decision-maker", + description: + "You consider both logic and emotions, but this can make decisions harder at times. Our psychics can provide you with extra clarity.", + }, + }; + + return ( + <> +

+ Do you make decisions with your head or heart? +

+ + {!!answer && ( + + )} + {!!answer && ( + + )} + + ); +} + +export default HeadOrHeart; diff --git a/src/components/ChatsPath/pages/Answers/HeadOrHeart/styles.module.scss b/src/components/ChatsPath/pages/Answers/HeadOrHeart/styles.module.scss new file mode 100644 index 0000000..28d68da --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/HeadOrHeart/styles.module.scss @@ -0,0 +1,7 @@ +.button { + margin-top: 30px; + & > button { + height: 50px; + width: 100%; + } +} diff --git a/src/components/ChatsPath/pages/Answers/HowConfident/index.tsx b/src/components/ChatsPath/pages/Answers/HowConfident/index.tsx new file mode 100644 index 0000000..33f590f --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/HowConfident/index.tsx @@ -0,0 +1,56 @@ +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import Answers from "@/components/ChatsPath/components/Answers"; + +function HowConfident() { + useUpdateStep(16); + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsQuizNeedGuidance()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "very_confident", + name: "Very confident", + questionId: "howConfident", + onClick: handleNext, + }, + { + id: 2, + value: "somewhat_confident", + name: "Somewhat confident", + questionId: "howConfident", + onClick: handleNext, + }, + { + id: 3, + value: "not_very_confident", + name: "Not very confident", + questionId: "howConfident", + onClick: handleNext, + }, + { + id: 4, + value: "not_confident_at_all", + name: "Not confident at all", + questionId: "howConfident", + onClick: handleNext, + }, + ]; + + return ( + <> +

+ How confident do you feel in making important life decisions? +

+ + + ); +} + +export default HowConfident; diff --git a/src/components/ChatsPath/pages/Answers/HowConfident/styles.module.scss b/src/components/ChatsPath/pages/Answers/HowConfident/styles.module.scss new file mode 100644 index 0000000..ee98d78 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/HowConfident/styles.module.scss @@ -0,0 +1,11 @@ +.button { + margin-top: 30px; + & > button { + height: 50px; + width: 100%; + } +} + +.title { + margin-top: 24px; +} diff --git a/src/components/ChatsPath/pages/Answers/InterestedHowLong/index.tsx b/src/components/ChatsPath/pages/Answers/InterestedHowLong/index.tsx new file mode 100644 index 0000000..a7fd7cd --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/InterestedHowLong/index.tsx @@ -0,0 +1,64 @@ +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import Answers from "@/components/ChatsPath/components/Answers"; + +function InterestedHowLong() { + useUpdateStep(24); + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsQuizMainReason()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "beginner", + name: "I am a beginner", + questionId: "interestedHowLong", + onClick: handleNext, + }, + { + id: 2, + value: "up_to_a_year", + name: "Up to a year", + questionId: "interestedHowLong", + onClick: handleNext, + }, + { + id: 3, + value: "for_1_2_years", + name: "For 1-2 years", + questionId: "interestedHowLong", + onClick: handleNext, + }, + { + id: 4, + value: "from_2_to_5_years", + name: "From 2 to 5 years", + questionId: "interestedHowLong", + onClick: handleNext, + }, + { + id: 5, + value: "for_more_than_5_years", + name: "For more than 5 years", + questionId: "interestedHowLong", + onClick: handleNext, + }, + ]; + + return ( + <> +

+ How long have you been interested in the psychic field? +

+ + + ); +} + +export default InterestedHowLong; diff --git a/src/components/ChatsPath/pages/Answers/InterestedHowLong/styles.module.scss b/src/components/ChatsPath/pages/Answers/InterestedHowLong/styles.module.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/components/ChatsPath/pages/Answers/MainReason/index.tsx b/src/components/ChatsPath/pages/Answers/MainReason/index.tsx new file mode 100644 index 0000000..0598fb4 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/MainReason/index.tsx @@ -0,0 +1,64 @@ +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import Answers from "@/components/ChatsPath/components/Answers"; + +function MainReason() { + useUpdateStep(25); + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsQuizWhatToExpect()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "curiosity", + name: "Curiosity", + questionId: "mainReason", + onClick: handleNext, + }, + { + id: 2, + value: "a_specific_issue", + name: "A specific issue", + questionId: "mainReason", + onClick: handleNext, + }, + { + id: 3, + value: "uncertainties_in_life", + name: "Uncertainties in life", + questionId: "mainReason", + onClick: handleNext, + }, + { + id: 4, + value: "upcoming_changes", + name: "Upcoming changes", + questionId: "mainReason", + onClick: handleNext, + }, + { + id: 5, + value: "all_the_above", + name: "All the above", + questionId: "mainReason", + onClick: handleNext, + }, + ]; + + return ( + <> +

+ What makes you consider getting a psychic reading now? +

+ + + ); +} + +export default MainReason; diff --git a/src/components/ChatsPath/pages/Answers/MainReason/styles.module.scss b/src/components/ChatsPath/pages/Answers/MainReason/styles.module.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/components/ChatsPath/pages/Answers/MissingInLife/index.tsx b/src/components/ChatsPath/pages/Answers/MissingInLife/index.tsx new file mode 100644 index 0000000..b0d2f23 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/MissingInLife/index.tsx @@ -0,0 +1,70 @@ +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import Answers from "@/components/ChatsPath/components/Answers"; + +function MissingInLife() { + useUpdateStep(9); + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsRecognize()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "love_happiness", + name: "Love happiness", + questionId: "missingInLife", + onClick: handleNext, + }, + { + id: 2, + value: "personal_fulfillment", + name: "Personal fulfillment", + questionId: "missingInLife", + onClick: handleNext, + }, + { + id: 3, + value: "guidance_and_support", + name: "Guidance and support", + questionId: "missingInLife", + onClick: handleNext, + }, + { + id: 4, + value: "self_confidence", + name: "Self-confidence", + questionId: "missingInLife", + onClick: handleNext, + }, + { + id: 5, + value: "all_the_above", + name: "All the above", + questionId: "missingInLife", + onClick: handleNext, + }, + { + id: 6, + value: "not_sure", + name: "Not sure", + questionId: "missingInLife", + onClick: handleNext, + }, + ]; + + return ( + <> +

+ Do you always know exactly what you want? +

+ + + ); +} + +export default MissingInLife; diff --git a/src/components/ChatsPath/pages/Answers/MissingInLife/styles.module.scss b/src/components/ChatsPath/pages/Answers/MissingInLife/styles.module.scss new file mode 100644 index 0000000..ee98d78 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/MissingInLife/styles.module.scss @@ -0,0 +1,11 @@ +.button { + margin-top: 30px; + & > button { + height: 50px; + width: 100%; + } +} + +.title { + margin-top: 24px; +} diff --git a/src/components/ChatsPath/pages/Answers/NeedGuidance/index.tsx b/src/components/ChatsPath/pages/Answers/NeedGuidance/index.tsx new file mode 100644 index 0000000..31c56b0 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/NeedGuidance/index.tsx @@ -0,0 +1,49 @@ +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import Answers from "@/components/ChatsPath/components/Answers"; + +function NeedGuidance() { + useUpdateStep(17); + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsQuizDecisionGuidance()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "no", + name: "No", + questionId: "needGuidance", + onClick: handleNext, + }, + { + id: 2, + value: "yes", + name: "Yes", + questionId: "needGuidance", + onClick: handleNext, + }, + { + id: 3, + value: "not_sure", + name: "Not sure", + questionId: "needGuidance", + onClick: handleNext, + }, + ]; + + return ( + <> +

+ Do you struggle with questions that deal with uncertainty? +

+ + + ); +} + +export default NeedGuidance; diff --git a/src/components/ChatsPath/pages/Answers/NeedGuidance/styles.module.scss b/src/components/ChatsPath/pages/Answers/NeedGuidance/styles.module.scss new file mode 100644 index 0000000..ee98d78 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/NeedGuidance/styles.module.scss @@ -0,0 +1,11 @@ +.button { + margin-top: 30px; + & > button { + height: 50px; + width: 100%; + } +} + +.title { + margin-top: 24px; +} diff --git a/src/components/ChatsPath/pages/Answers/ParentStatus/index.tsx b/src/components/ChatsPath/pages/Answers/ParentStatus/index.tsx new file mode 100644 index 0000000..cb64d6c --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/ParentStatus/index.tsx @@ -0,0 +1,40 @@ +import Answers from "@/components/ChatsPath/components/Answers"; +import { IAnswer } from "../../../data"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; + +function ParentStatus() { + useUpdateStep(5); + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsProfileIntro()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "yes", + name: "Yes", + questionId: "parentStatus", + onClick: handleNext, + }, + { + id: 2, + value: "no", + name: "No", + questionId: "parentStatus", + onClick: handleNext, + }, + ]; + + return ( + <> +

Are you a parent?

+ + + ); +} + +export default ParentStatus; diff --git a/src/components/ChatsPath/pages/Answers/ParentStatus/styles.module.scss b/src/components/ChatsPath/pages/Answers/ParentStatus/styles.module.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/components/ChatsPath/pages/Answers/ProneToOverthinking/index.tsx b/src/components/ChatsPath/pages/Answers/ProneToOverthinking/index.tsx new file mode 100644 index 0000000..c1ac5b0 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/ProneToOverthinking/index.tsx @@ -0,0 +1,81 @@ +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import Answers from "@/components/ChatsPath/components/Answers"; +import AnswerDescription, { + IAnswerDescriptionProps, +} from "@/components/ChatsPath/components/AnswerDescription"; +import { useSelector } from "react-redux"; +import { selectors } from "@/store"; +import Button from "@/components/ChatsPath/ui/Button"; + +function ProneToOverthinking() { + useUpdateStep(12); + const navigate = useNavigate(); + const answer = useSelector(selectors.selectAnswers)?.proneToOverthinking; + + const handleNext = () => { + navigate(routes.client.chatsQuizWorriesImpact()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "yes", + name: "Yes", + questionId: "proneToOverthinking", + }, + { + id: 2, + value: "sometimes", + name: "Sometimes", + questionId: "proneToOverthinking", + }, + { + id: 3, + value: "no", + name: "No", + questionId: "proneToOverthinking", + }, + ]; + + const descriptions: Record = { + yes: { + title: "🙌 Overthinking can be overwhelming", + description: + "We understand your concerns and will focus your first reading on bringing you clarity and easing your doubts", + }, + sometimes: { + title: "🙌 We all need clarity at times", + description: + "Based on your responses, we will tailor your reading to provide certainty and ease your doubts", + }, + no: { + title: "👍 You seem confident in your decisions", + description: + "Our psychics will help confirm that your intuition is leading you in the right direction", + }, + }; + + return ( + <> +

Are you prone to overthinking?

+ + {!!answer && ( + + )} + {!!answer && ( + + )} + + ); +} + +export default ProneToOverthinking; diff --git a/src/components/ChatsPath/pages/Answers/ProneToOverthinking/styles.module.scss b/src/components/ChatsPath/pages/Answers/ProneToOverthinking/styles.module.scss new file mode 100644 index 0000000..ee98d78 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/ProneToOverthinking/styles.module.scss @@ -0,0 +1,11 @@ +.button { + margin-top: 30px; + & > button { + height: 50px; + width: 100%; + } +} + +.title { + margin-top: 24px; +} diff --git a/src/components/ChatsPath/pages/Answers/PsychicComfortable/index.tsx b/src/components/ChatsPath/pages/Answers/PsychicComfortable/index.tsx new file mode 100644 index 0000000..9d94642 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/PsychicComfortable/index.tsx @@ -0,0 +1,82 @@ +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import MultiplyAnswers from "@/components/ChatsPath/components/MultiplyAnswers"; +import Button from "@/components/ChatsPath/ui/Button"; +import { useSelector } from "react-redux"; +import { selectors } from "@/store"; +import Tip from "@/components/ChatsPath/components/Tip"; + +function PsychicComfortable() { + useUpdateStep(28); + const navigate = useNavigate(); + const answer = useSelector(selectors.selectAnswers)?.psychicComfortable; + + const handleNext = () => { + if (!answer?.length) return; + navigate(routes.client.chatsQuizUserName()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "straightforward_and_honest", + name: "Straightforward and honest", + questionId: "psychicComfortable", + }, + { + id: 2, + value: "soft_and_empathetic", + name: "Soft and empathetic", + questionId: "psychicComfortable", + }, + { + id: 3, + value: "patient_and_grounded", + name: "Patient and grounded", + questionId: "psychicComfortable", + }, + { + id: 4, + value: "proactive", + name: "Proactive", + questionId: "psychicComfortable", + }, + { + id: 5, + value: "encouraging", + name: "Encouraging", + questionId: "psychicComfortable", + }, + { + id: 6, + value: "all", + name: "All the above", + questionId: "psychicComfortable", + }, + ]; + + return ( + <> +

+ Which psychic would you be comfortable talking to? +

+ + + + + ); +} + +export default PsychicComfortable; diff --git a/src/components/ChatsPath/pages/Answers/PsychicComfortable/styles.module.scss b/src/components/ChatsPath/pages/Answers/PsychicComfortable/styles.module.scss new file mode 100644 index 0000000..13cb01d --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/PsychicComfortable/styles.module.scss @@ -0,0 +1,21 @@ +.answer { + display: flex; + align-items: center; + + & > span { + font-size: 24px; + margin-right: 8px; + } +} + +.button { + position: fixed; + left: 50%; + transform: translateX(-50%); + bottom: calc(0dvh + 16px); + + & > button { + height: 50px; + font-weight: 600; + } +} diff --git a/src/components/ChatsPath/pages/Answers/PsychicReading/index.tsx b/src/components/ChatsPath/pages/Answers/PsychicReading/index.tsx new file mode 100644 index 0000000..2eff7bd --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/PsychicReading/index.tsx @@ -0,0 +1,42 @@ +import Answers from "@/components/ChatsPath/components/Answers"; +import { IAnswer } from "../../../data"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; + +function PsychicReading() { + useUpdateStep(1); + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsGuidance()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "yes", + name: "Yes", + questionId: "psychicReading", + onClick: handleNext, + }, + { + id: 2, + value: "no", + name: "No", + questionId: "psychicReading", + onClick: handleNext, + }, + ]; + + return ( + <> +

+ Are you aware of what a psychic reading is? +

+ + + ); +} + +export default PsychicReading; diff --git a/src/components/ChatsPath/pages/Answers/PsychicReading/styles.module.scss b/src/components/ChatsPath/pages/Answers/PsychicReading/styles.module.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/components/ChatsPath/pages/Answers/ReadingExperience/index.tsx b/src/components/ChatsPath/pages/Answers/ReadingExperience/index.tsx new file mode 100644 index 0000000..ab4aa72 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/ReadingExperience/index.tsx @@ -0,0 +1,77 @@ +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import Answers from "@/components/ChatsPath/components/Answers"; +import AnswerDescription, { + IAnswerDescriptionProps, +} from "@/components/ChatsPath/components/AnswerDescription"; +import { useSelector } from "react-redux"; +import { selectors } from "@/store"; +import Button from "@/components/ChatsPath/ui/Button"; + +function ReadingExperience() { + useUpdateStep(23); + const navigate = useNavigate(); + const answer = useSelector(selectors.selectAnswers)?.readingExperience; + + const handleNext = () => { + navigate(routes.client.chatsQuizInterestedHowLong()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "yes", + name: "Yes", + questionId: "readingExperience", + }, + { + id: 2, + value: "no", + name: "No", + questionId: "readingExperience", + }, + ]; + + const descriptions: Record = { + yes: { + title: "👍️ You are in the right place", + description: + "Choose from our 600+ skilled psychics who are ready to help you with the questions that bother you the most", + }, + no: { + title: "🙌 We'll guide you through every step", + description: + "Aura offers support and tips to ensure your first reading is both comforting and insightful", + }, + }; + + return ( + <> +

+ Have you ever received a psychic reading? +

+ + {!!answer && ( + + Your first 3 sessions are free 🎁 + + } + /> + )} + {!!answer && ( + + )} + + ); +} + +export default ReadingExperience; diff --git a/src/components/ChatsPath/pages/Answers/ReadingExperience/styles.module.scss b/src/components/ChatsPath/pages/Answers/ReadingExperience/styles.module.scss new file mode 100644 index 0000000..28d68da --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/ReadingExperience/styles.module.scss @@ -0,0 +1,7 @@ +.button { + margin-top: 30px; + & > button { + height: 50px; + width: 100%; + } +} diff --git a/src/components/ChatsPath/pages/Answers/RelationshipStatus/index.tsx b/src/components/ChatsPath/pages/Answers/RelationshipStatus/index.tsx new file mode 100644 index 0000000..5bced36 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/RelationshipStatus/index.tsx @@ -0,0 +1,61 @@ +import Answers from "@/components/ChatsPath/components/Answers"; +import { IAnswer } from "../../../data"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; + +function RelationshipStatus() { + useUpdateStep(3); + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsQuizDate()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "single", + name: "Single", + questionId: "relationshipStatus", + onClick: handleNext, + }, + { + id: 2, + value: "relationship", + name: "In a relationship", + questionId: "relationshipStatus", + onClick: handleNext, + }, + { + id: 3, + value: "married", + name: "Married", + questionId: "relationshipStatus", + onClick: handleNext, + }, + { + id: 4, + value: "complicated", + name: "Complicated", + questionId: "relationshipStatus", + onClick: handleNext, + }, + { + id: 5, + value: "other", + name: "Unsure / Other", + questionId: "relationshipStatus", + onClick: handleNext, + }, + ]; + + return ( + <> +

What is your relationship status?

+ + + ); +} + +export default RelationshipStatus; diff --git a/src/components/ChatsPath/pages/Answers/RelationshipStatus/styles.module.scss b/src/components/ChatsPath/pages/Answers/RelationshipStatus/styles.module.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/components/ChatsPath/pages/Answers/ResonateFuture/index.tsx b/src/components/ChatsPath/pages/Answers/ResonateFuture/index.tsx new file mode 100644 index 0000000..4009e74 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/ResonateFuture/index.tsx @@ -0,0 +1,35 @@ +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { useDispatch } from "react-redux"; +import { actions } from "@/store"; +import YesNoButtons from "@/components/ChatsPath/components/YesNoButtons"; +import { images } from "@/components/ChatsPath/data"; + +function ResonateFuture() { + const dispatch = useDispatch(); + useUpdateStep(21); + const navigate = useNavigate(); + + const handleNext = (answer: "yes" | "no") => { + dispatch(actions.chats.updateAnswers({ resonateFuture: answer })); + navigate(routes.client.chatsPreferencesIntro()); + }; + + return ( + <> +

+ Does this topic sound interesting to you? +

+ Image + handleNext(answer)} /> + + ); +} + +export default ResonateFuture; diff --git a/src/components/ChatsPath/pages/Answers/ResonateFuture/styles.module.scss b/src/components/ChatsPath/pages/Answers/ResonateFuture/styles.module.scss new file mode 100644 index 0000000..0f0a2f3 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/ResonateFuture/styles.module.scss @@ -0,0 +1,10 @@ +.title { + margin-top: 24px; +} + +.image { + display: block; + width: 328px; + height: 352px; + color: transparent; +} diff --git a/src/components/ChatsPath/pages/Answers/ResonateLife/index.tsx b/src/components/ChatsPath/pages/Answers/ResonateLife/index.tsx new file mode 100644 index 0000000..b112618 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/ResonateLife/index.tsx @@ -0,0 +1,35 @@ +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { useDispatch } from "react-redux"; +import { actions } from "@/store"; +import YesNoButtons from "@/components/ChatsPath/components/YesNoButtons"; +import { images } from "@/components/ChatsPath/data"; + +function ResonateLife() { + const dispatch = useDispatch(); + useUpdateStep(20); + const navigate = useNavigate(); + + const handleNext = (answer: "yes" | "no") => { + dispatch(actions.chats.updateAnswers({ resonateLife: answer })); + navigate(routes.client.chatsQuizResonateFuture()); + }; + + return ( + <> +

+ Does this topic sound interesting to you? +

+ Image + handleNext(answer)} /> + + ); +} + +export default ResonateLife; diff --git a/src/components/ChatsPath/pages/Answers/ResonateLife/styles.module.scss b/src/components/ChatsPath/pages/Answers/ResonateLife/styles.module.scss new file mode 100644 index 0000000..0f0a2f3 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/ResonateLife/styles.module.scss @@ -0,0 +1,10 @@ +.title { + margin-top: 24px; +} + +.image { + display: block; + width: 328px; + height: 352px; + color: transparent; +} diff --git a/src/components/ChatsPath/pages/Answers/ResonateLove/index.tsx b/src/components/ChatsPath/pages/Answers/ResonateLove/index.tsx new file mode 100644 index 0000000..4853aea --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/ResonateLove/index.tsx @@ -0,0 +1,35 @@ +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { useDispatch } from "react-redux"; +import { actions } from "@/store"; +import YesNoButtons from "@/components/ChatsPath/components/YesNoButtons"; +import { images } from "@/components/ChatsPath/data"; + +function ResonateLove() { + const dispatch = useDispatch(); + useUpdateStep(19); + const navigate = useNavigate(); + + const handleNext = (answer: "yes" | "no") => { + dispatch(actions.chats.updateAnswers({ resonateLove: answer })); + navigate(routes.client.chatsQuizResonateLife()); + }; + + return ( + <> +

+ Does this topic sound interesting to you? +

+ Image + handleNext(answer)} /> + + ); +} + +export default ResonateLove; diff --git a/src/components/ChatsPath/pages/Answers/ResonateLove/styles.module.scss b/src/components/ChatsPath/pages/Answers/ResonateLove/styles.module.scss new file mode 100644 index 0000000..0f0a2f3 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/ResonateLove/styles.module.scss @@ -0,0 +1,10 @@ +.title { + margin-top: 24px; +} + +.image { + display: block; + width: 328px; + height: 352px; + color: transparent; +} diff --git a/src/components/ChatsPath/pages/Answers/SatisfiedWithLife/index.tsx b/src/components/ChatsPath/pages/Answers/SatisfiedWithLife/index.tsx new file mode 100644 index 0000000..96c810f --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/SatisfiedWithLife/index.tsx @@ -0,0 +1,83 @@ +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import Answers from "@/components/ChatsPath/components/Answers"; +import AnswerDescription, { + IAnswerDescriptionProps, +} from "@/components/ChatsPath/components/AnswerDescription"; +import { useSelector } from "react-redux"; +import { selectors } from "@/store"; +import Button from "@/components/ChatsPath/ui/Button"; + +function SatisfiedWithLife() { + useUpdateStep(6); + const navigate = useNavigate(); + const answer = useSelector(selectors.selectAnswers)?.satisfiedWithLife; + + const handleNext = () => { + navigate(routes.client.chatsQuizWhatEmotion()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "no", + name: "No", + questionId: "satisfiedWithLife", + }, + { + id: 2, + value: "yes", + name: "Yes", + questionId: "satisfiedWithLife", + }, + { + id: 3, + value: "not_sure", + name: "Not sure", + questionId: "satisfiedWithLife", + }, + ]; + + const descriptions: Record = { + no: { + title: "🙌 We are here to help you", + description: + "Your answers will help us personalize your reading to address your questions and guide you toward happiness", + }, + yes: { + title: "👍 It's great to hear!", + description: + "Your honest responses will help us personalize your reading and address your questions more accurately", + }, + not_sure: { + title: "🙌 It's okay to feel uncertain", + description: + "Your honest responses will help us tailor your reading to provide clarity and guidance where you need it most", + }, + }; + + return ( + <> +

+ Are you happy with the way things are going in your life? +

+ + {!!answer && ( + + )} + {!!answer && ( + + )} + + ); +} + +export default SatisfiedWithLife; diff --git a/src/components/ChatsPath/pages/Answers/SatisfiedWithLife/styles.module.scss b/src/components/ChatsPath/pages/Answers/SatisfiedWithLife/styles.module.scss new file mode 100644 index 0000000..28d68da --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/SatisfiedWithLife/styles.module.scss @@ -0,0 +1,7 @@ +.button { + margin-top: 30px; + & > button { + height: 50px; + width: 100%; + } +} diff --git a/src/components/ChatsPath/pages/Answers/SensitiveToCriticism/index.tsx b/src/components/ChatsPath/pages/Answers/SensitiveToCriticism/index.tsx new file mode 100644 index 0000000..479e4cb --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/SensitiveToCriticism/index.tsx @@ -0,0 +1,54 @@ +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import Answers from "@/components/ChatsPath/components/Answers"; + +function SensitiveToCriticism() { + useUpdateStep(14); + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsQuizHeadOrHeart()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "yes", + name: "Yes", + questionId: "sensitiveToCriticism", + onClick: handleNext, + }, + { + id: 2, + value: "sometimes", + name: "Sometimes", + questionId: "sensitiveToCriticism", + onClick: handleNext, + }, + { + id: 3, + value: "rarely", + name: "Rarely", + questionId: "sensitiveToCriticism", + onClick: handleNext, + }, + { + id: 4, + value: "not_at_all", + name: "Not at all", + questionId: "sensitiveToCriticism", + onClick: handleNext, + }, + ]; + + return ( + <> +

Are you sensitive to criticism?

+ + + ); +} + +export default SensitiveToCriticism; diff --git a/src/components/ChatsPath/pages/Answers/SensitiveToCriticism/styles.module.scss b/src/components/ChatsPath/pages/Answers/SensitiveToCriticism/styles.module.scss new file mode 100644 index 0000000..ee98d78 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/SensitiveToCriticism/styles.module.scss @@ -0,0 +1,11 @@ +.button { + margin-top: 30px; + & > button { + height: 50px; + width: 100%; + } +} + +.title { + margin-top: 24px; +} diff --git a/src/components/ChatsPath/pages/Answers/SomethingWorrying/index.tsx b/src/components/ChatsPath/pages/Answers/SomethingWorrying/index.tsx new file mode 100644 index 0000000..27f9be7 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/SomethingWorrying/index.tsx @@ -0,0 +1,49 @@ +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import Answers from "@/components/ChatsPath/components/Answers"; + +function SomethingWorrying() { + useUpdateStep(11); + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsQuizProneToOverthinking()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "yes", + name: "Yes", + questionId: "somethingWorrying", + onClick: handleNext, + }, + { + id: 2, + value: "no", + name: "No", + questionId: "somethingWorrying", + onClick: handleNext, + }, + { + id: 3, + value: "not_sure", + name: "Not sure", + questionId: "somethingWorrying", + onClick: handleNext, + }, + ]; + + return ( + <> +

+ Do you feel worried when thinking about your goal? +

+ + + ); +} + +export default SomethingWorrying; diff --git a/src/components/ChatsPath/pages/Answers/SomethingWorrying/styles.module.scss b/src/components/ChatsPath/pages/Answers/SomethingWorrying/styles.module.scss new file mode 100644 index 0000000..ee98d78 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/SomethingWorrying/styles.module.scss @@ -0,0 +1,11 @@ +.button { + margin-top: 30px; + & > button { + height: 50px; + width: 100%; + } +} + +.title { + margin-top: 24px; +} diff --git a/src/components/ChatsPath/pages/Answers/UserName/index.tsx b/src/components/ChatsPath/pages/Answers/UserName/index.tsx new file mode 100644 index 0000000..d70e196 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/UserName/index.tsx @@ -0,0 +1,76 @@ +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import Button from "@/components/ChatsPath/ui/Button"; +import { useDispatch, useSelector } from "react-redux"; +import { actions, selectors } from "@/store"; +import Tip from "@/components/ChatsPath/components/Tip"; +import NameInput from "@/components/pages/ABDesign/v1/pages/EmailEnterPage/NameInput"; +import { useState } from "react"; + +function UserName() { + useUpdateStep(29); + const navigate = useNavigate(); + const dispatch = useDispatch(); + const answer = useSelector(selectors.selectAnswers)?.userName; + const [name, setName] = useState(""); + const [isValidName, setIsValidName] = useState(false); + + const handleNext = () => { + if (!answer?.length) return; + navigate(routes.client.chatsQuizProcessing()); + }; + + const handleValidName = (name: string) => { + if (name) { + dispatch( + actions.user.update({ + username: name, + }) + ); + dispatch(actions.chats.updateAnswers({ userName: name })); + } + setName(name); + setIsValidName(true); + }; + + const handleInvalidName = () => { + dispatch( + actions.user.update({ + username: "", + }) + ); + dispatch(actions.chats.updateAnswers({ userName: "" })); + setName(""); + setIsValidName(false); + }; + + return ( + <> +

+ What is your name? +

+ + + + + ); +} + +export default UserName; diff --git a/src/components/ChatsPath/pages/Answers/UserName/styles.module.scss b/src/components/ChatsPath/pages/Answers/UserName/styles.module.scss new file mode 100644 index 0000000..31ce23e --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/UserName/styles.module.scss @@ -0,0 +1,42 @@ +.answer { + display: flex; + align-items: center; + + & > span { + font-size: 24px; + margin-right: 8px; + } +} + +.button { + position: fixed; + left: 50%; + transform: translateX(-50%); + bottom: calc(0dvh + 16px); + + & > button { + height: 50px; + font-weight: 600; + } +} + +.input-name { + width: 100% !important; + display: block !important; + color: var(--typography-100) !important; + font-weight: 400 !important; + font-size: 16px !important; + line-height: 24px !important; + background-color: transparent !important; + background-clip: padding-box !important; + padding-left: 15px !important; + padding-right: 15px !important; + border: 1px solid var(--secondary-100) !important; + border-radius: 25px !important; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out !important; + -webkit-appearance: none !important; + appearance: none !important; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; + height: 50px !important; + margin-top: 8px !important; +} diff --git a/src/components/ChatsPath/pages/Answers/WhatEmotion/index.tsx b/src/components/ChatsPath/pages/Answers/WhatEmotion/index.tsx new file mode 100644 index 0000000..f50fece --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/WhatEmotion/index.tsx @@ -0,0 +1,63 @@ +import Answers from "@/components/ChatsPath/components/Answers"; +import { IAnswer } from "../../../data"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; + +function WhatEmotion() { + useUpdateStep(7); + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsAnswerHub()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "confused_about_choices", + name: "Confused about choices", + questionId: "whatEmotion", + onClick: handleNext, + }, + { + id: 2, + value: "worried_future", + name: "Worried about the future", + questionId: "whatEmotion", + onClick: handleNext, + }, + { + id: 3, + value: "disappointed_in_love_life", + name: "Disappointed in love life", + questionId: "whatEmotion", + onClick: handleNext, + }, + { + id: 4, + value: "optimistic_for_changes", + name: "Optimistic for changes", + questionId: "whatEmotion", + onClick: handleNext, + }, + { + id: 5, + value: "not_sure", + name: "Not sure", + questionId: "whatEmotion", + onClick: handleNext, + }, + ]; + + return ( + <> +

+ Which emotion best describes you in the moment? +

+ + + ); +} + +export default WhatEmotion; diff --git a/src/components/ChatsPath/pages/Answers/WhatEmotion/styles.module.scss b/src/components/ChatsPath/pages/Answers/WhatEmotion/styles.module.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/components/ChatsPath/pages/Answers/WhatToExpect/index.tsx b/src/components/ChatsPath/pages/Answers/WhatToExpect/index.tsx new file mode 100644 index 0000000..8a13c0c --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/WhatToExpect/index.tsx @@ -0,0 +1,71 @@ +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import Answers from "@/components/ChatsPath/components/Answers"; + +function WhatToExpect() { + useUpdateStep(26); + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsQuizGuidanceArea()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "specific_predictions", + name: "Specific predictions", + questionId: "whatToExpect", + onClick: handleNext, + }, + { + id: 2, + value: "guidance_on_decisions", + name: "Guidance on decisions", + questionId: "whatToExpect", + onClick: handleNext, + }, + { + id: 3, + value: "confirmation_of_own_intuition", + name: "Confirmation of my own intuition", + questionId: "whatToExpect", + onClick: handleNext, + }, + { + id: 4, + value: "general_advice", + name: "General advice", + questionId: "whatToExpect", + onClick: handleNext, + }, + { + id: 5, + value: "all_the_above", + name: "All the above", + questionId: "whatToExpect", + onClick: handleNext, + }, + { + id: 6, + value: "not_sure", + name: "Not sure", + questionId: "whatToExpect", + onClick: handleNext, + }, + ]; + + return ( + <> +

+ What are you looking to gain from our psychic? +

+ + + ); +} + +export default WhatToExpect; diff --git a/src/components/ChatsPath/pages/Answers/WhatToExpect/styles.module.scss b/src/components/ChatsPath/pages/Answers/WhatToExpect/styles.module.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/components/ChatsPath/pages/Answers/WhatYouWant/index.tsx b/src/components/ChatsPath/pages/Answers/WhatYouWant/index.tsx new file mode 100644 index 0000000..f729ec2 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/WhatYouWant/index.tsx @@ -0,0 +1,49 @@ +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import Answers from "@/components/ChatsPath/components/Answers"; + +function WhatYouWant() { + useUpdateStep(8); + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsQuizMissingInLife()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "no", + name: "No", + questionId: "whatYouWant", + onClick: handleNext, + }, + { + id: 2, + value: "yes", + name: "Yes", + questionId: "whatYouWant", + onClick: handleNext, + }, + { + id: 3, + value: "not_sure", + name: "Not sure", + questionId: "whatYouWant", + onClick: handleNext, + }, + ]; + + return ( + <> +

+ Do you always know exactly what you want? +

+ + + ); +} + +export default WhatYouWant; diff --git a/src/components/ChatsPath/pages/Answers/WhatYouWant/styles.module.scss b/src/components/ChatsPath/pages/Answers/WhatYouWant/styles.module.scss new file mode 100644 index 0000000..ee98d78 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/WhatYouWant/styles.module.scss @@ -0,0 +1,11 @@ +.button { + margin-top: 30px; + & > button { + height: 50px; + width: 100%; + } +} + +.title { + margin-top: 24px; +} diff --git a/src/components/ChatsPath/pages/Answers/WorriesImpact/index.tsx b/src/components/ChatsPath/pages/Answers/WorriesImpact/index.tsx new file mode 100644 index 0000000..d93f045 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/WorriesImpact/index.tsx @@ -0,0 +1,56 @@ +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import Answers from "@/components/ChatsPath/components/Answers"; + +function WorriesImpact() { + useUpdateStep(13); + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsQuizSensitiveToCriticism()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "often", + name: "Often", + questionId: "worriesImpact", + onClick: handleNext, + }, + { + id: 2, + value: "sometimes", + name: "Sometimes", + questionId: "worriesImpact", + onClick: handleNext, + }, + { + id: 3, + value: "rarely", + name: "Rarely", + questionId: "worriesImpact", + onClick: handleNext, + }, + { + id: 4, + value: "never", + name: "Never", + questionId: "worriesImpact", + onClick: handleNext, + }, + ]; + + return ( + <> +

+ How often do you let your worries impact your decisions? +

+ + + ); +} + +export default WorriesImpact; diff --git a/src/components/ChatsPath/pages/Answers/WorriesImpact/styles.module.scss b/src/components/ChatsPath/pages/Answers/WorriesImpact/styles.module.scss new file mode 100644 index 0000000..ee98d78 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/WorriesImpact/styles.module.scss @@ -0,0 +1,11 @@ +.button { + margin-top: 30px; + & > button { + height: 50px; + width: 100%; + } +} + +.title { + margin-top: 24px; +} diff --git a/src/components/ChatsPath/pages/Answers/YourGoal/index.tsx b/src/components/ChatsPath/pages/Answers/YourGoal/index.tsx new file mode 100644 index 0000000..91c7d9d --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/YourGoal/index.tsx @@ -0,0 +1,98 @@ +import { useNavigate } from "react-router-dom"; +import { useUpdateStep } from "@/components/ChatsPath/hooks/useUpdateStep"; +import routes from "@/routes"; +import { IAnswer } from "@/components/ChatsPath/data"; +import Answers from "@/components/ChatsPath/components/Answers"; +import InputAnswerModal from "@/components/ChatsPath/components/InputAnswerModal"; +import { useState } from "react"; +import { useDispatch } from "react-redux"; +import { actions } from "@/store"; + +function YourGoal() { + useUpdateStep(10); + const navigate = useNavigate(); + const dispatch = useDispatch(); + + const [answer, setAnswer] = useState(""); + + const [open, setOpen] = useState(false); + + const handleOpen = () => setOpen(true); + const handleClose = () => setOpen(false); + + const handleNext = () => { + navigate(routes.client.chatsQuizSomethingWorrying()); + }; + + const answers: IAnswer[] = [ + { + id: 1, + value: "back_together", + name: "Find out if we’ll get back together", + questionId: "yourGoal", + onClick: handleNext, + }, + { + id: 2, + value: "ex_still_feelings", + name: "Find out if ex still has feelings", + questionId: "yourGoal", + onClick: handleNext, + }, + { + id: 3, + value: "ex_has_someone_else", + name: "Find out if my ex has someone else", + questionId: "yourGoal", + onClick: handleNext, + }, + { + id: 4, + value: "move_on_after_breakup", + name: "Move on after breakup", + questionId: "yourGoal", + onClick: handleNext, + }, + { + id: 5, + value: "other", + name: "Other (please specify)", + questionId: "yourGoal", + onClick: handleOpen, + }, + ]; + + const handleChangeAnswer = (event: React.ChangeEvent) => { + setAnswer(event.target.value); + }; + + const handleModalNext = () => { + dispatch( + actions.chats.updateAnswers({ + yourGoal: answer, + }) + ); + handleNext(); + }; + + return ( + <> + +

What is your goal?

+ + + ); +} + +export default YourGoal; diff --git a/src/components/ChatsPath/pages/Answers/YourGoal/styles.module.scss b/src/components/ChatsPath/pages/Answers/YourGoal/styles.module.scss new file mode 100644 index 0000000..ee98d78 --- /dev/null +++ b/src/components/ChatsPath/pages/Answers/YourGoal/styles.module.scss @@ -0,0 +1,11 @@ +.button { + margin-top: 30px; + & > button { + height: 50px; + width: 100%; + } +} + +.title { + margin-top: 24px; +} diff --git a/src/components/ChatsPath/pages/GoalSetup/index.tsx b/src/components/ChatsPath/pages/GoalSetup/index.tsx new file mode 100644 index 0000000..611b505 --- /dev/null +++ b/src/components/ChatsPath/pages/GoalSetup/index.tsx @@ -0,0 +1,221 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import { useSelector } from "react-redux"; +import { selectors } from "@/store"; +import Button from "../../ui/Button"; + +function GoalSetup() { + const navigate = useNavigate(); + const { goal } = useSelector(selectors.selectAnswers); + + const handleNext = () => { + navigate(routes.client.chatsReviews()); + }; + + const handleBack = () => { + navigate(-1); + }; + + return ( +
+

+ Great! You just set your first goal! +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + {goal === "about_ex" && <>Finding out about my ex</>} + {goal === "give_advice" && <>Getting advice for my love life</>} + {goal === "give_guidance" && <>Getting guidance on my future</>} + {goal === "all" && <>Getting advice on various aspects of life</>} + +

+ {goal === "about_ex" && ( + <> + Every once in a while, we all need some{" "} + guidance about our relationships. We will do our best + to help you! + + )} + {goal === "give_advice" && ( + <> + Every once in a while, we all need some{" "} + guidance about our love lives. We will do our best to + help you! + + )} + {goal === "give_guidance" && ( + <> + Every once in a while, we all need some{" "} + advice on what the future holds. We will do our best to + help you! + + )} + {goal === "all" && ( + <> + Every once in a while, we all need some{" "} + advice about different aspects of life. We will do our + best to help you! + + )} +

+
+

Do not worry! You can change your goal anytime.

+ + +
+
+ ); +} + +export default GoalSetup; diff --git a/src/components/ChatsPath/pages/GoalSetup/styles.module.scss b/src/components/ChatsPath/pages/GoalSetup/styles.module.scss new file mode 100644 index 0000000..de7f949 --- /dev/null +++ b/src/components/ChatsPath/pages/GoalSetup/styles.module.scss @@ -0,0 +1,66 @@ +.container { + max-width: 360px; + width: 100%; + padding-left: 16px; + padding-right: 16px; + padding-top: 16px; + margin: 0 auto; +} + +.title { + color: var(--typography-100); + font-size: 20px; + font-weight: 700; + line-height: 135%; + text-align: center; + margin-bottom: 16px; + margin-top: 48px; +} + +.text { + font-size: 16px; + line-height: 1.35; + font-weight: 400; + margin-top: 16px; + + & > span { + color: var(--primary); + } +} + +.image-container { + width: 206px; + height: 168px; + overflow: hidden; + margin: 0px auto; + outline: none; +} + +.button { + margin: 0; + & > button { + height: 50px; + font-weight: 600; + } + + &.back-button > button { + background: transparent; + } +} + +.footer { + position: fixed; + left: 0; + bottom: calc(0dvh + 30px); + display: flex; + flex-direction: column; + width: 100%; + + & > p { + margin-bottom: 24px; + color: var(--typography-200-with-opacity-50); + text-align: center; + font-size: 14px; + line-height: 1.35; + } +} diff --git a/src/components/ChatsPath/pages/Guidance/index.tsx b/src/components/ChatsPath/pages/Guidance/index.tsx new file mode 100644 index 0000000..50c85e1 --- /dev/null +++ b/src/components/ChatsPath/pages/Guidance/index.tsx @@ -0,0 +1,127 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import { useSelector } from "react-redux"; +import { selectors } from "@/store"; +import { images } from "../../data"; +import Button from "../../ui/Button"; + +function Guidance() { + const navigate = useNavigate(); + const { psychicReading } = useSelector(selectors.selectAnswers); + + const handleNext = () => { + navigate(routes.client.chatsQuizGoal()); + }; + + return ( +
+ + {psychicReading === "yes" && ( + <>Get the most accurate psychic readings with Aura</> + )} + {psychicReading === "no" && ( + <>Do not worry! Aura is the best place to start your journey</> + )} + +

+ {psychicReading === "yes" && ( + <> + Our psychics provide a personalized approach to readings on various + topics to meet your needs + + )} + {psychicReading === "no" && ( + <> + A psychic reading dives into your past, present, and future to + provide answers on various topics + + )} +

+
    + + + + + + +
  • + Love & Relationship +

    Love & Relationship

    +
  • +
  • + Guidance & Life path +

    Guidance & Life path

    +
  • +
  • + Career & Work +

    Career & Work

    +
  • +
  • + Future telling +

    Future telling

    +
  • +
+ +
+ ); +} + +export default Guidance; diff --git a/src/components/ChatsPath/pages/Guidance/styles.module.scss b/src/components/ChatsPath/pages/Guidance/styles.module.scss new file mode 100644 index 0000000..100e7ba --- /dev/null +++ b/src/components/ChatsPath/pages/Guidance/styles.module.scss @@ -0,0 +1,81 @@ +.container { + max-width: 360px; + width: 100%; + padding-left: 16px; + padding-right: 16px; + margin: 0 auto; +} + +.title { + color: var(--typography-100); + font-size: 20px; + font-weight: 700; + line-height: 135%; + text-align: center; + margin-bottom: 16px; +} + +.text { + color: var(--typography-100); + font-size: 14px; + font-weight: 400; + line-height: 135%; + text-align: center; + margin-bottom: 24px; +} + +.list { + position: relative; + display: grid; + grid-template-columns: repeat(2, 1fr); + grid-template-rows: repeat(2, 1fr); + justify-content: space-around; + background-color: var(--alternative-page-background); + border-radius: 12px; + margin-bottom: 80px; + padding: 4px; + width: 342px; + left: 50%; + transform: translateX(-50%); + + & > svg { + position: absolute; + width: 90%; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + + & > line { + stroke: var(--primary-700); + } + } + + & > .item { + position: relative; + display: flex; + flex-direction: column; + justify-content: center; + margin: 12px; + + & > img { + border-radius: 8px; + color: transparent; + } + + & > .label { + color: var(--primary-100); + text-align: center; + font-size: 14px; + font-weight: 600; + line-height: 135%; + margin-top: 9px; + } + } +} + +.button { + position: fixed; + bottom: calc(0dvh + 20px); + left: 50%; + transform: translateX(-50%); +} diff --git a/src/components/ChatsPath/pages/PreferencesIntro/index.tsx b/src/components/ChatsPath/pages/PreferencesIntro/index.tsx new file mode 100644 index 0000000..d1b4327 --- /dev/null +++ b/src/components/ChatsPath/pages/PreferencesIntro/index.tsx @@ -0,0 +1,70 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import Button from "../../ui/Button"; +import { images } from "../../data"; + +function PreferencesIntro() { + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsQuizBelieveInSpirituality()); + }; + + return ( +
+ orbited heart + + Congratulations! + + + “Personal traits” section is completed + +
+
+
+
+ Star +
+
+
    +
  • +

    You are

    +

    + Confused about choices +

    +
  • +
  • +

    Goal to achieve

    +

    Get back with ex

    +
  • +
  • +

    Area of improvement

    +

    Love happiness

    +
  • +
+
+

+ Your responses indicate you need a specific approach. That’s why the + last section is designed to match you with the psychic for your goal. +

+ +
+ ); +} + +export default PreferencesIntro; diff --git a/src/components/ChatsPath/pages/PreferencesIntro/styles.module.scss b/src/components/ChatsPath/pages/PreferencesIntro/styles.module.scss new file mode 100644 index 0000000..f42747c --- /dev/null +++ b/src/components/ChatsPath/pages/PreferencesIntro/styles.module.scss @@ -0,0 +1,222 @@ +.container { + max-width: 360px; + width: 100%; + padding-left: 16px; + padding-right: 16px; + padding-top: 16px; + margin: 0 auto; + text-align: left; +} + +.image { + display: block; + margin: 0 auto 8px; + align-self: center; + color: transparent; +} + +.title { + color: var(--typography-100); + text-align: center; + font-size: 24px; + font-weight: 700; + line-height: 1.3; + margin-bottom: 0; +} + +.subtitle { + margin-top: 8px; + color: var(--primary-100); + text-align: center; + font-size: 16px; + line-height: 1.35; +} + +.text { + margin-top: 32px; + margin-bottom: 7px; + color: var(--typography-100); + text-align: center; + font-size: 14px; + line-height: 1.5; + + & > strong { + font-weight: 700; + } +} + +.button { + margin: 0; + position: fixed; + left: 50%; + transform: translateX(-50%); + bottom: calc(0dvh + 30px); + & > button { + height: 50px; + font-weight: 600; + } + + &.back-button > button { + background: transparent; + } +} + +.summary { + display: flex; + + & > .indicator { + position: relative; + width: 2px; + height: 170px; + margin-left: 6px; + margin-right: 30px; + background-color: var(--secondary-700); + border-radius: 2px; + + & > .progress { + position: absolute; + top: 0; + left: 0; + width: 2px; + transition: 0.5s linear; + transition-property: height; + background: linear-gradient( + 180deg, + rgba(69, 104, 220, 0), + rgba(176, 106, 179, 0.85), + hsla(0, 0%, 98%, 0.85) + ); + filter: blur(1px); + transform: translateZ(0); + + animation: progress 4s linear forwards; + } + + & > .pointer { + position: absolute; + left: 50%; + top: 0; + transform: translateX(-50%) translateY(0); + transition: 0.5s linear; + transition-property: transform; + + animation: pointer 4s linear forwards; + + & > img { + color: transparent; + } + } + } + + .list { + & > .item { + margin-top: 20px; + + @for $i from 1 through 3 { + &:nth-child(#{$i}) > .trait-name { + animation-delay: ($i - 1) * 1s; + } + } + + @for $i from 1 through 3 { + &:nth-child(#{$i}) > .trait-value { + animation-delay: ($i - 1) * 1s; + } + } + + &:first-child { + margin-top: 0; + } + + & > .trait-name { + font-size: 14px; + line-height: 1.35; + transition: 0.5s linear; + transition-property: color; + color: var(--primary-100); + opacity: 0.25; + animation-name: trait-name; + animation-timing-function: linear; + animation-fill-mode: forwards; + animation-duration: 0.5s; + } + + & > .trait-value { + display: flex; + align-items: center; + margin-top: 2px; + font-size: 16px; + font-weight: 700; + line-height: 1.35; + transition: 0.5s linear; + transition-property: color, opacity; + color: var(--primary-100); + opacity: 0; + animation-name: trait-value; + animation-timing-function: linear; + animation-fill-mode: forwards; + animation-duration: 0.5s; + } + } + } +} + +@keyframes progress { + 0% { + height: 0px; + } + 12% { + height: 0px; + } + 25% { + height: 82px; + } + 50% { + height: 82px; + } + 75% { + height: 170px; + } + 100% { + height: 170px; + } +} + +@keyframes pointer { + 0% { + transform: translateX(-50%) translateY(-10px); + } + 12% { + transform: translateX(-50%) translateY(-10px); + } + 25% { + transform: translateX(-50%) translateY(72px); + } + 50% { + transform: translateX(-50%) translateY(72px); + } + 75% { + transform: translateX(-50%) translateY(160px); + } + 100% { + transform: translateX(-50%) translateY(160px); + } +} + +@keyframes trait-name { + 0% { + opacity: 0.25; + } + 100% { + opacity: 1; + } +} + +@keyframes trait-value { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} diff --git a/src/components/ChatsPath/pages/Processing/index.tsx b/src/components/ChatsPath/pages/Processing/index.tsx new file mode 100644 index 0000000..5c5ab7b --- /dev/null +++ b/src/components/ChatsPath/pages/Processing/index.tsx @@ -0,0 +1,109 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +// import routes from "@/routes"; +import { useSelector } from "react-redux"; +import { selectors } from "@/store"; +import { CircularProgressbar } from "react-circular-progressbar"; +import { useCallback, useEffect, useState } from "react"; +import { sleep } from "@/services/date"; +import { images } from "../../data"; + +function Processing() { + const navigate = useNavigate(); + const { username } = useSelector(selectors.selectUser); + const [loadingProgress, setLoadingProgress] = useState(0); + + const handleNext = useCallback(() => { + // navigate(routes.client.home()); + }, [navigate]); + + useEffect(() => { + (async () => { + if (loadingProgress >= 100) { + await sleep(2000); + return handleNext(); + } + if (loadingProgress === 51) { + await sleep(1500); + } else if (loadingProgress === 73) { + await sleep(1500); + } else { + await sleep(200); + } + setLoadingProgress((value) => value + 1); + })(); + }, [handleNext, loadingProgress]); + + return ( +
+ + <span>{username}, you are all set,</span> now we are creating your + profile + + + + + + + + + + + +
+
+ +
+ +
    +
  • +
    + done +
    + Analyzing your answers... +
  • +
  • +
    + done +
    + Fetching a list of available psychics... +
  • +
  • +
    + done +
    + Matching you to the best psychics... +
  • +
  • +
    + done +
    + Personalizing your experience... +
  • +
+
+ ); +} + +export default Processing; diff --git a/src/components/ChatsPath/pages/Processing/styles.module.scss b/src/components/ChatsPath/pages/Processing/styles.module.scss new file mode 100644 index 0000000..6962f44 --- /dev/null +++ b/src/components/ChatsPath/pages/Processing/styles.module.scss @@ -0,0 +1,131 @@ +.container { + max-width: 360px; + width: 100%; + padding-left: 16px; + padding-right: 16px; + padding-top: 16px; + margin: 0 auto; + text-align: left; +} + +.title { + color: var(--typography-100); + text-align: center; + font-size: 24px; + font-weight: 700; + line-height: 1.3; + margin-bottom: 0; + + & > span { + background: var(--gradient-pink-base); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + } +} + +.progress-container { + position: relative; + width: 200px; + margin: 16px auto; + + & > .background-gradient { + position: absolute; + left: 0; + right: 0; + bottom: 0; + top: 0; + background: var(--gradient-azure); + opacity: 0.3; + border-radius: 50%; + filter: blur(40px); + } +} + +.svg-defs { + width: 0; + height: 0; +} + +.list { + display: flex; + flex-direction: column; + align-items: center; + font-size: 14px; + color: var(--typography-100); + line-height: 24px; + max-width: 400px; + margin: 0 auto; + margin-top: 32px; + + @for $i from 1 through 20 { + & > .item:nth-child(#{$i}) { + animation-delay: $i * 5.65s; + + & > .circle { + animation-delay: $i * 5.65s; + + & > img { + animation-delay: $i * 5.65s; + } + } + } + } + + & > .item { + display: flex; + align-items: center; + margin-bottom: 20px; + color: var(--primary-700); + width: 320px; + background: var(--primary-700-with-opacity-30); + border-radius: 20px; + animation-duration: 1.5s; + animation-fill-mode: both; + animation-name: appearance-item; + + & > .circle { + border-radius: 50%; + margin-right: 15px; + background: var(--primary-700-with-opacity-30); + display: flex; + align-items: center; + justify-content: center; + padding: 12px 9px; + animation-duration: 1.5s; + animation-fill-mode: both; + animation-name: appearance-circle; + + & > img { + animation-duration: 1.5s; + animation-fill-mode: both; + animation-name: appearance-img; + width: 22px; + height: 16px; + } + } + } +} + +@keyframes appearance-item { + 100% { + opacity: 1; + color: var(--primary-100); + background: var(--primary-with-opacity-30); + } +} + +@keyframes appearance-circle { + 100% { + background: var(--primary-400-with-opacity-30); + } +} + +@keyframes appearance-img { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} diff --git a/src/components/ChatsPath/pages/ProfileIntro/index.tsx b/src/components/ChatsPath/pages/ProfileIntro/index.tsx new file mode 100644 index 0000000..9e2ce79 --- /dev/null +++ b/src/components/ChatsPath/pages/ProfileIntro/index.tsx @@ -0,0 +1,78 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import Button from "../../ui/Button"; +import { images } from "../../data"; +import ZodiacIconSVG from "../../ui/ZodiacIconSVG"; +import { useSelector } from "react-redux"; +import { selectors } from "@/store"; +import { getZodiacSignByDate } from "@/services/zodiac-sign"; + +function ProfileIntro() { + const navigate = useNavigate(); + const birthdate = useSelector(selectors.selectBirthdate); + const zodiac = getZodiacSignByDate(birthdate); + + const handleNext = () => { + navigate(routes.client.chatsQuizSatisfiedWithLife()); + }; + + return ( +
+ Thumbs up + + Well done! + + + “Your Profile” section is completed. + +
+
+
+
+ Star +
+
+
    +
  • +

    Zodiac sign

    +

    + Capricorn + +

    +
  • +
  • +

    Your goal

    +

    Improve various life areas

    +
  • +
  • +

    Relationship status

    +

    Single

    +
  • +
+
+

+ Exploring aspects of your life requires detailed + answers to personal questions, so the next section aims to understand + your goal better. +

+ +
+ ); +} + +export default ProfileIntro; diff --git a/src/components/ChatsPath/pages/ProfileIntro/styles.module.scss b/src/components/ChatsPath/pages/ProfileIntro/styles.module.scss new file mode 100644 index 0000000..f42747c --- /dev/null +++ b/src/components/ChatsPath/pages/ProfileIntro/styles.module.scss @@ -0,0 +1,222 @@ +.container { + max-width: 360px; + width: 100%; + padding-left: 16px; + padding-right: 16px; + padding-top: 16px; + margin: 0 auto; + text-align: left; +} + +.image { + display: block; + margin: 0 auto 8px; + align-self: center; + color: transparent; +} + +.title { + color: var(--typography-100); + text-align: center; + font-size: 24px; + font-weight: 700; + line-height: 1.3; + margin-bottom: 0; +} + +.subtitle { + margin-top: 8px; + color: var(--primary-100); + text-align: center; + font-size: 16px; + line-height: 1.35; +} + +.text { + margin-top: 32px; + margin-bottom: 7px; + color: var(--typography-100); + text-align: center; + font-size: 14px; + line-height: 1.5; + + & > strong { + font-weight: 700; + } +} + +.button { + margin: 0; + position: fixed; + left: 50%; + transform: translateX(-50%); + bottom: calc(0dvh + 30px); + & > button { + height: 50px; + font-weight: 600; + } + + &.back-button > button { + background: transparent; + } +} + +.summary { + display: flex; + + & > .indicator { + position: relative; + width: 2px; + height: 170px; + margin-left: 6px; + margin-right: 30px; + background-color: var(--secondary-700); + border-radius: 2px; + + & > .progress { + position: absolute; + top: 0; + left: 0; + width: 2px; + transition: 0.5s linear; + transition-property: height; + background: linear-gradient( + 180deg, + rgba(69, 104, 220, 0), + rgba(176, 106, 179, 0.85), + hsla(0, 0%, 98%, 0.85) + ); + filter: blur(1px); + transform: translateZ(0); + + animation: progress 4s linear forwards; + } + + & > .pointer { + position: absolute; + left: 50%; + top: 0; + transform: translateX(-50%) translateY(0); + transition: 0.5s linear; + transition-property: transform; + + animation: pointer 4s linear forwards; + + & > img { + color: transparent; + } + } + } + + .list { + & > .item { + margin-top: 20px; + + @for $i from 1 through 3 { + &:nth-child(#{$i}) > .trait-name { + animation-delay: ($i - 1) * 1s; + } + } + + @for $i from 1 through 3 { + &:nth-child(#{$i}) > .trait-value { + animation-delay: ($i - 1) * 1s; + } + } + + &:first-child { + margin-top: 0; + } + + & > .trait-name { + font-size: 14px; + line-height: 1.35; + transition: 0.5s linear; + transition-property: color; + color: var(--primary-100); + opacity: 0.25; + animation-name: trait-name; + animation-timing-function: linear; + animation-fill-mode: forwards; + animation-duration: 0.5s; + } + + & > .trait-value { + display: flex; + align-items: center; + margin-top: 2px; + font-size: 16px; + font-weight: 700; + line-height: 1.35; + transition: 0.5s linear; + transition-property: color, opacity; + color: var(--primary-100); + opacity: 0; + animation-name: trait-value; + animation-timing-function: linear; + animation-fill-mode: forwards; + animation-duration: 0.5s; + } + } + } +} + +@keyframes progress { + 0% { + height: 0px; + } + 12% { + height: 0px; + } + 25% { + height: 82px; + } + 50% { + height: 82px; + } + 75% { + height: 170px; + } + 100% { + height: 170px; + } +} + +@keyframes pointer { + 0% { + transform: translateX(-50%) translateY(-10px); + } + 12% { + transform: translateX(-50%) translateY(-10px); + } + 25% { + transform: translateX(-50%) translateY(72px); + } + 50% { + transform: translateX(-50%) translateY(72px); + } + 75% { + transform: translateX(-50%) translateY(160px); + } + 100% { + transform: translateX(-50%) translateY(160px); + } +} + +@keyframes trait-name { + 0% { + opacity: 0.25; + } + 100% { + opacity: 1; + } +} + +@keyframes trait-value { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} diff --git a/src/components/ChatsPath/pages/Recognize/index.tsx b/src/components/ChatsPath/pages/Recognize/index.tsx new file mode 100644 index 0000000..c294f2e --- /dev/null +++ b/src/components/ChatsPath/pages/Recognize/index.tsx @@ -0,0 +1,47 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import Button from "../../ui/Button"; +import { images } from "../../data"; + +function Recognize() { + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.chatsQuizYourGoal()); + }; + + return ( +
+ Life goal pic + + Recognizing what is currently missing for you is the first step to + achieve happiness in your life + + + Let's remember why you are here: + +
+ + 💖 + {/* // add goal */} + You want to find out about your ex + +
+

+ To address your needs it is important to understand your intent better, + so let’s get into some details about your goal! +

+ +
+ ); +} + +export default Recognize; diff --git a/src/components/ChatsPath/pages/Recognize/styles.module.scss b/src/components/ChatsPath/pages/Recognize/styles.module.scss new file mode 100644 index 0000000..6c23dc6 --- /dev/null +++ b/src/components/ChatsPath/pages/Recognize/styles.module.scss @@ -0,0 +1,82 @@ +.container { + max-width: 360px; + width: 100%; + padding-left: 16px; + padding-right: 16px; + padding-top: 16px; + margin: 0 auto; + text-align: left; +} + +.image { + display: block; + width: 80px; + height: 80px; + margin-left: auto; + margin-right: auto; + margin-bottom: 24px; + color: transparent; +} + +.title { + color: var(--typography-100); + font-size: 20px; + font-weight: 700; + line-height: 150%; + margin-bottom: 28px; + text-align: left; +} + +.subtitle { + color: var(--primary-100); + font-weight: 600; + line-height: 150%; +} + +.text { + margin-top: 16px; + color: var(--typography-200); + font-size: 14px; + line-height: 150%; +} + +.button { + margin: 0; + position: fixed; + left: 50%; + transform: translateX(-50%); + bottom: calc(0dvh + 30px); + & > button { + height: 50px; + font-weight: 600; + } + + &.back-button > button { + background: transparent; + } +} + +.goal { + display: flex; + align-items: center; + width: 100%; + padding: 10px 14px; + margin-top: 8px; + background: var(--white-with-opacity-5); + border-radius: 8px; + + & > .goal-text { + display: flex; + align-items: center; + margin-left: 8px; + color: var(--typography-100); + font-size: 14px; + font-weight: 700; + line-height: 145%; + + & span:first-of-type { + font-size: 24px; + margin-right: 10px; + } + } +} diff --git a/src/components/ChatsPath/pages/Reviews/index.tsx b/src/components/ChatsPath/pages/Reviews/index.tsx new file mode 100644 index 0000000..1fd182c --- /dev/null +++ b/src/components/ChatsPath/pages/Reviews/index.tsx @@ -0,0 +1,133 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.scss"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import Button from "../../ui/Button"; +import AppStoreReviews from "../../components/AppStoreReviews"; +import Slider from "react-slick"; +import { useRef, useState } from "react"; +import { IReview } from "../../data"; +import Review2 from "../../components/Review2"; + +const reviews: IReview[] = [ + { + avatar: "Customer1.webp", + name: "Leslie, 30", + text: `"These readings have provided insights into my ex and helped me understand what went wrong. That was truly helpful!"`, + date: "01/08/2024", + }, + { + avatar: "Customer9.webp", + name: "Khaly, 24", + text: `"It was a fast and direct reading I felt she connected to my situation and the person I asked about. It felt honest and I would certainly be back or recommend to others."`, + date: "01/16/2024", + }, + { + avatar: "Customer3.webp", + name: "Numich, 32", + text: `"Guidance gave me confidence in next steps and reduced confusions. Helped me to look both ways with my decisions! Told me a lot that helped me trust my intuition and guts!"`, + date: "10/11/2023", + }, + { + avatar: "Customer4.webp", + name: "Heather Camille, 26", + text: `"I’ve been using Aura for a few months now, and have had amazing readings/guidance from a few different advisors."`, + date: "10/09/2023", + }, + { + avatar: "Customer5.webp", + name: "Emersyn, 21", + text: `"I’m happy with my experience in Aura. I like that there is important improvements from time to time, which really helps to use Aura."`, + date: "06/22/2023", + }, + { + avatar: "Customer6.webp", + name: "Rylee, 34", + text: `"Best reading I\`ve had. Thank you for helping understand what is going on in my life. I stand firmly on my feet, I met my soulmate, my love. I fell very inspired."`, + date: "10/14/2023", + }, +]; + +function Reviews() { + const navigate = useNavigate(); + const slider = useRef(null); + const [currentSlide, setCurrentSlide] = useState(0); + + const sliderSettings = { + dots: false, + infinite: false, + speed: 500, + slidesToShow: 1, + slidesToScroll: 1, + // centerMode: true, + arrows: false, + beforeChange: (_current: number, next: number) => { + setCurrentSlide(next); + }, + }; + + const handleNext = () => { + navigate(routes.client.chatsQuizRelationshipStatus()); + }; + + return ( +
+ + + How others achieved their goals + + + {reviews.map((review, index) => ( + + ))} + +
+ + +
+
+

Reviews are from the Aura app

+ +
+
+ ); +} + +export default Reviews; diff --git a/src/components/ChatsPath/pages/Reviews/styles.module.scss b/src/components/ChatsPath/pages/Reviews/styles.module.scss new file mode 100644 index 0000000..42d60f7 --- /dev/null +++ b/src/components/ChatsPath/pages/Reviews/styles.module.scss @@ -0,0 +1,103 @@ +.container { + max-width: 360px; + width: 100%; + padding-left: 16px; + padding-right: 16px; + padding-top: 16px; + margin: 0 auto; +} + +.title { + color: var(--typography-100); + font-size: 20px; + font-weight: 700; + line-height: 135%; + text-align: center; + margin-bottom: 16px; + margin-top: 28px; +} + +.text { + font-size: 16px; + line-height: 1.35; + font-weight: 400; + margin-top: 16px; + + & > span { + color: var(--primary); + } +} + +.image-container { + width: 206px; + height: 168px; + overflow: hidden; + margin: 0px auto; + outline: none; +} + +.button { + margin: 0; + & > button { + height: 50px; + font-weight: 600; + } + + &.back-button > button { + background: transparent; + } +} + +.footer { + position: fixed; + left: 0; + bottom: calc(0dvh + 30px); + display: flex; + flex-direction: column; + width: 100%; + + & > p { + margin-bottom: 24px; + color: var(--typography-200-with-opacity-50); + text-align: center; + font-size: 14px; + line-height: 1.35; + } +} + +.carousel-buttons { + position: relative; + width: 100%; + display: flex; + justify-content: center; + + & > button { + background: transparent; + border: none; + font-size: 32px; + display: flex; + justify-content: center; + align-items: center; + margin-left: 6px; + margin-right: 6px; + + &.disabled { + opacity: 0.5; + } + + & > span { + display: inherit; + align-items: inherit; + justify-content: inherit; + + & > svg { + transition: fill 0.3s ease-in-out, opacity 0.3s ease-in-out; + flex-shrink: 0; + display: inline-block; + width: 1em; + height: 20px; + fill: var(--typography-100); + } + } + } +} diff --git a/src/components/ChatsPath/pages/Welcome/index.tsx b/src/components/ChatsPath/pages/Welcome/index.tsx new file mode 100644 index 0000000..22dd731 --- /dev/null +++ b/src/components/ChatsPath/pages/Welcome/index.tsx @@ -0,0 +1,76 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.scss"; +import { images, sprites } from "../../data"; +import ChooseGender from "../../components/ChooseGender"; +import Partners from "../../components/Partners"; +import Feedback from "../../components/Feedback"; +import HowItWorks from "../../components/HowItWorks"; +import Summary from "../../components/Summary"; +import Astrologers from "../../components/Astrologers"; +import Button from "../../ui/Button"; +import Address from "../../components/Address"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import { useRef } from "react"; + +function Welcome() { + const navigate = useNavigate(); + const genderScrollRef = useRef(null); + + const handleNext = () => { + navigate(routes.client.chatsQuizPsychicReading()); + }; + + const scrollToGender = () => { + genderScrollRef?.current?.scrollIntoView({ + behavior: "smooth", + }); + }; + + return ( +
+ + Accurate and personalized + <br /> readings with top psychics + +

+ Start with our 2-min quiz to match you with a
psychic who meets + your needs +

+
    +
  • + + Guaranteed privacy +
  • +
  • +
    + +
    + Guaranteed privacy +
  • +
+
+ + + + + + +
+ + Join over 60 million people who decided to get answers and get happy + with Aura + + smile people +
+
+ ); +} + +export default Welcome; diff --git a/src/components/ChatsPath/pages/Welcome/styles.module.scss b/src/components/ChatsPath/pages/Welcome/styles.module.scss new file mode 100644 index 0000000..6d5c547 --- /dev/null +++ b/src/components/ChatsPath/pages/Welcome/styles.module.scss @@ -0,0 +1,62 @@ +.title { + font-size: 24px; + font-weight: 700; + line-height: 120%; + margin-bottom: 12px; +} + +.text { + font-size: 14px; + line-height: 135%; + margin-bottom: 24px; +} + +.list { + display: flex; + justify-content: center; + margin-bottom: 36px; + + & > .item { + border-radius: 12px; + background: #393860; + padding: 4px 8px; + display: flex; + justify-content: space-between; + align-items: center; + margin-right: 8px; + + & > svg { + fill: #fafafa; + } + + & > .check-wrapper { + display: flex; + justify-content: center; + align-items: center; + border-radius: 50%; + background: #fafafa; + width: 14px; + height: 14px; + + & > svg { + width: 10px; + } + } + + & > .item-text { + margin-left: 4px; + font-size: 14px; + } + } +} + +.footer { + padding: 50px 0; + background: var(--secondary-800); + + & > img { + color: transparent; + width: 100%; + height: auto; + } +} diff --git a/src/components/ChatsPath/ui/Burger/index.tsx b/src/components/ChatsPath/ui/Burger/index.tsx new file mode 100644 index 0000000..76b7047 --- /dev/null +++ b/src/components/ChatsPath/ui/Burger/index.tsx @@ -0,0 +1,23 @@ +import { sprites } from "../../data"; +import styles from "./styles.module.scss"; + +interface IBurgerProps { + className?: string; + onClick?: () => void; +} + +function Burger({ className = "", onClick }: IBurgerProps) { + return ( + + ); +} + +export default Burger; diff --git a/src/components/ChatsPath/ui/Burger/styles.module.scss b/src/components/ChatsPath/ui/Burger/styles.module.scss new file mode 100644 index 0000000..0499c45 --- /dev/null +++ b/src/components/ChatsPath/ui/Burger/styles.module.scss @@ -0,0 +1,7 @@ +.svg { + fill: #fafafa; + width: 24px; + height: 24px; + flex-shrink: 0; + cursor: pointer; +} diff --git a/src/components/ChatsPath/ui/Button/index.tsx b/src/components/ChatsPath/ui/Button/index.tsx new file mode 100644 index 0000000..983bc79 --- /dev/null +++ b/src/components/ChatsPath/ui/Button/index.tsx @@ -0,0 +1,25 @@ +import styles from "./styles.module.scss"; + +export interface IButtonProps { + children?: React.ReactNode; + classNameContainer?: string; + disabled?: boolean; + onClick?: () => void; +} + +function Button({ + children = "Get started", + classNameContainer = "", + disabled = false, + onClick, +}: IButtonProps) { + return ( +
+ +
+ ); +} + +export default Button; diff --git a/src/components/ChatsPath/ui/Button/styles.module.scss b/src/components/ChatsPath/ui/Button/styles.module.scss new file mode 100644 index 0000000..dea49a1 --- /dev/null +++ b/src/components/ChatsPath/ui/Button/styles.module.scss @@ -0,0 +1,43 @@ +.button-wrapper { + text-align: center; + margin-top: 50px; + margin-bottom: 0; + + & > button { + display: inline-flex; + align-items: center; + justify-content: center; + text-align: center; + text-decoration: none; + vertical-align: middle; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + width: 300px; + padding: 5px 10px; + align-self: center; + border-radius: 30px; + outline: none; + border: none; + color: var(--typography-100); + font-size: 16px; + line-height: 24px; + height: 40px; + background: var(--gradient-pink-base); + transition: all 0.15s ease-in-out 0ms; + + &:disabled { + opacity: 0.5; + } + + &:active { + transform: scale(1.03); + } + + & > .button-label { + display: inherit; + align-items: inherit; + justify-content: inherit; + } + } +} diff --git a/src/components/ChatsPath/ui/Checkbox/index.tsx b/src/components/ChatsPath/ui/Checkbox/index.tsx new file mode 100644 index 0000000..59ec3ef --- /dev/null +++ b/src/components/ChatsPath/ui/Checkbox/index.tsx @@ -0,0 +1,28 @@ +import styles from "./styles.module.scss"; + +interface ICheckboxProps { + id: string; + name: string; + active: boolean; +} + +function Checkbox({ id, name, active }: ICheckboxProps) { + return ( + <> + + + + ); +} + +export default Checkbox; diff --git a/src/components/ChatsPath/ui/Checkbox/styles.module.scss b/src/components/ChatsPath/ui/Checkbox/styles.module.scss new file mode 100644 index 0000000..e34a0bb --- /dev/null +++ b/src/components/ChatsPath/ui/Checkbox/styles.module.scss @@ -0,0 +1,38 @@ +.checkbox-input { + display: none; +} + +.checkbox-label { + display: inline-flex; + align-items: center; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 14px; + + &::before { + content: ""; + display: inline-block; + width: 14px; + height: 14px; + flex-shrink: 0; + flex-grow: 0; + background-color: transparent; + margin-right: 8px; + background-repeat: no-repeat; + background-position: 50%; + border: 2px solid var(--primary); + border-radius: 3px; + } + + &.active::before { + background-color: var(--primary); + background-image: url(/chats/done.svg) !important; + border-radius: 3px; + } + + &.active > .checkbox-content { + display: inline-block; + } +} diff --git a/src/components/ChatsPath/ui/ZodiacIconSVG/index.tsx b/src/components/ChatsPath/ui/ZodiacIconSVG/index.tsx new file mode 100644 index 0000000..62b906d --- /dev/null +++ b/src/components/ChatsPath/ui/ZodiacIconSVG/index.tsx @@ -0,0 +1,88 @@ +import styles from "./styles.module.scss"; + +interface IZodiacIconSVGProps { + zodiac: string; +} + +function ZodiacIconSVG({ zodiac }: IZodiacIconSVGProps) { + return ( + <> + + + {zodiac === "Capricorn" && ( + + )} + {zodiac === "Aquarius" && ( + + )} + {zodiac === "Pisces" && ( + + )} + {zodiac === "Aries" && ( + + )} + {zodiac === "Taurus" && ( + + )} + {zodiac === "Gemini" && ( + + )} + {zodiac === "Cancer" && ( + + )} + {zodiac === "Leo" && ( + + )} + {zodiac === "Virgo" && ( + + )} + {zodiac === "Libra" && ( + + )} + {zodiac === "Scorpio" && ( + + )} + {zodiac === "Sagittarius" && ( + + )} + + + ); +} + +export default ZodiacIconSVG; diff --git a/src/components/ChatsPath/ui/ZodiacIconSVG/styles.module.scss b/src/components/ChatsPath/ui/ZodiacIconSVG/styles.module.scss new file mode 100644 index 0000000..848dd58 --- /dev/null +++ b/src/components/ChatsPath/ui/ZodiacIconSVG/styles.module.scss @@ -0,0 +1,13 @@ +.svg { + min-width: 22px; + min-height: 22px; +} + +.gradient { + position: absolute; + z-index: -9999; + top: 0; + left: 0; + width: 0; + height: 0; +} diff --git a/src/components/ChatsPath/ui/ZodiacWheelSVG/index.tsx b/src/components/ChatsPath/ui/ZodiacWheelSVG/index.tsx new file mode 100644 index 0000000..23168a6 --- /dev/null +++ b/src/components/ChatsPath/ui/ZodiacWheelSVG/index.tsx @@ -0,0 +1,119 @@ +import { SVGProps } from "react"; +import styles from "./styles.module.scss"; + +interface IZodiacWheelSVG { + currentZodiac?: string; +} + +function ZodiacWheelSVG({ + currentZodiac, + ...props +}: SVGProps & IZodiacWheelSVG) { + return ( + + Zodiac Wheel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} + +export default ZodiacWheelSVG; diff --git a/src/components/ChatsPath/ui/ZodiacWheelSVG/styles.module.scss b/src/components/ChatsPath/ui/ZodiacWheelSVG/styles.module.scss new file mode 100644 index 0000000..81cd51a --- /dev/null +++ b/src/components/ChatsPath/ui/ZodiacWheelSVG/styles.module.scss @@ -0,0 +1,12 @@ +.wheel { + transition-duration: 0.4s; + transition-property: transform; +} + +.active { + & > path { + fill: var(--chart) !important; + transition-duration: 0.2s; + transition-delay: 0.3s; + } +} diff --git a/src/components/pages/ABDesign/v1/ui/BackButton/index.tsx b/src/components/pages/ABDesign/v1/ui/BackButton/index.tsx index 3718aa1..819197a 100644 --- a/src/components/pages/ABDesign/v1/ui/BackButton/index.tsx +++ b/src/components/pages/ABDesign/v1/ui/BackButton/index.tsx @@ -2,11 +2,13 @@ import styles from "./styles.module.css"; interface IBackButtonProps { onClick?: () => void; + fillColor?: string; } -function BackButton( - props: IBackButtonProps & React.HTMLAttributes -) { +function BackButton({ + fillColor = "#353E75", + ...props +}: IBackButtonProps & React.HTMLAttributes) { return ( diff --git a/src/index.css b/src/index.css index bbd513a..f097bb7 100644 --- a/src/index.css +++ b/src/index.css @@ -190,6 +190,7 @@ div[class^="divider"] { #root { height: 100%; min-width: 100vw; + overflow: auto; } a, diff --git a/src/locales/index.ts b/src/locales/index.ts index 96dc2a1..a809d68 100644 --- a/src/locales/index.ts +++ b/src/locales/index.ts @@ -9,6 +9,19 @@ import { symbolByCurrency } from './currency.ts' // return navigator.language // } export const getClientLocale = async () => { + const urlParams = new URLSearchParams(document.location.search); + const languageFromUrl = urlParams.get('lg'); + const languageUrlFromStore = localStorage.getItem("languageFromUrl") + + if (languageFromUrl?.length) { + localStorage.setItem("languageFromUrl", languageFromUrl) + return languageFromUrl; + } + + if (languageUrlFromStore?.length) { + return languageUrlFromStore; + } + const api = createApi(); try { const resp = await api.getLocale(undefined) diff --git a/src/routerComponents/Chats/Layouts/Quiz/index.tsx b/src/routerComponents/Chats/Layouts/Quiz/index.tsx new file mode 100644 index 0000000..45865e8 --- /dev/null +++ b/src/routerComponents/Chats/Layouts/Quiz/index.tsx @@ -0,0 +1,24 @@ +import { Outlet } from "react-router-dom"; +import styles from "./styles.module.scss"; +import ProgressBar from "@/components/ChatsPath/components/ProgressBar"; +import { useSelector } from "react-redux"; +import { selectors } from "@/store"; + +function Quiz() { + const currentStep = useSelector(selectors.selectCurrentStep); + + return ( +
+
+ +
+
+
+ +
+
+
+ ); +} + +export default Quiz; diff --git a/src/routerComponents/Chats/Layouts/Quiz/styles.module.scss b/src/routerComponents/Chats/Layouts/Quiz/styles.module.scss new file mode 100644 index 0000000..77246c1 --- /dev/null +++ b/src/routerComponents/Chats/Layouts/Quiz/styles.module.scss @@ -0,0 +1,27 @@ +.container { + width: 100%; + flex-grow: 1; + display: flex; + flex-direction: column; + margin-left: auto; + margin-right: auto; + height: fit-content; + min-height: 100dvh; +} + +.content-wrapper { + padding: 20px 10px; + background: var(--secondary-600); + flex-grow: 1; + border: 1px solid var(--secondary); + border-top-left-radius: 16px; + border-top-right-radius: 16px; + + & > .content { + margin-bottom: 15px; + text-align: center; + max-width: 330px; + margin-left: auto; + margin-right: auto; + } +} diff --git a/src/routerComponents/Chats/Layouts/index.tsx b/src/routerComponents/Chats/Layouts/index.tsx new file mode 100644 index 0000000..089c539 --- /dev/null +++ b/src/routerComponents/Chats/Layouts/index.tsx @@ -0,0 +1,57 @@ +import Header from "@/components/ChatsPath/components/Header"; +import styles from "./styles.module.scss"; +import { Outlet } from "react-router-dom"; +import routes from "@/routes"; +import { images } from "@/components/ChatsPath/data"; +import { useState } from "react"; +import DrawerMenu from "@/components/ChatsPath/components/DrawerMenu"; + +interface IBackgroundPages { + [route: string]: string; +} + +const backgroundPages: IBackgroundPages = { + [routes.client.chatsAnswerHub()]: images("answers_hub_bg.webp"), +}; + +const routesWithoutBackButton = [routes.client.chatsWelcome()]; + +function Layout() { + const bgImage = backgroundPages[window.location.pathname]; + const [open, setOpen] = useState(false); + + const toggleDrawer = (newOpen: boolean) => () => { + setOpen(newOpen); + }; + + const isBackButtonVisible = () => { + for (const route of routesWithoutBackButton) { + if (window.location.pathname.includes(route)) return false; + } + return true; + }; + + return ( +
+ toggleDrawer(false)} /> + {bgImage && ( + <> + background image + + )} +
+
+ +
+
+ ); +} + +export default Layout; diff --git a/src/routerComponents/Chats/Layouts/styles.module.scss b/src/routerComponents/Chats/Layouts/styles.module.scss new file mode 100644 index 0000000..4ac8c3d --- /dev/null +++ b/src/routerComponents/Chats/Layouts/styles.module.scss @@ -0,0 +1,35 @@ +.container { + position: relative; + width: 100%; + min-height: 100dvh; + height: fit-content; + background-color: var(--secondary-800); + color: #fafafa; + text-align: center; +} + +.background-image { + position: absolute; + height: 100%; + width: 100%; + inset: 0px; + object-fit: cover; + color: transparent; + opacity: 0.85; + z-index: 1; +} + +.gradient-overlay { + position: fixed; + left: 0; + right: 0; + top: 0; + bottom: 0; + overflow-y: auto; + background-image: linear-gradient( + 180deg, + rgba(32, 34, 97, 0.35), + rgba(6, 5, 23, 0.8) + ); + z-index: 1; +} diff --git a/src/routerComponents/Chats/index.tsx b/src/routerComponents/Chats/index.tsx new file mode 100644 index 0000000..35da618 --- /dev/null +++ b/src/routerComponents/Chats/index.tsx @@ -0,0 +1,229 @@ +import "./styles.scss"; +import "slick-carousel/slick/slick.css"; +import "slick-carousel/slick/slick-theme.css"; +import { Route, Routes } from "react-router-dom"; +import { useEffect } from "react"; +import { ELocalesPlacement } from "@/locales"; +import Layout from "./Layouts"; +import routes, { chatsPrefix } from "@/routes"; +import Welcome from "@/components/ChatsPath/pages/Welcome"; +import Quiz from "./Layouts/Quiz"; +import PsychicReading from "@/components/ChatsPath/pages/Answers/PsychicReading"; +import Guidance from "@/components/ChatsPath/pages/Guidance"; +import Goal from "@/components/ChatsPath/pages/Answers/Goal"; +import GoalSetup from "@/components/ChatsPath/pages/GoalSetup"; +import Reviews from "@/components/ChatsPath/pages/Reviews"; +import RelationshipStatus from "@/components/ChatsPath/pages/Answers/RelationshipStatus"; +import Date from "@/components/ChatsPath/pages/Answers/Date"; +import ParentStatus from "@/components/ChatsPath/pages/Answers/ParentStatus"; +import ProfileIntro from "@/components/ChatsPath/pages/ProfileIntro"; +import SatisfiedWithLife from "@/components/ChatsPath/pages/Answers/SatisfiedWithLife"; +import WhatEmotion from "@/components/ChatsPath/pages/Answers/WhatEmotion"; +import AnswerHub from "@/components/ChatsPath/pages/AnswerHub"; +import WhatYouWant from "@/components/ChatsPath/pages/Answers/WhatYouWant"; +import MissingInLife from "@/components/ChatsPath/pages/Answers/MissingInLife"; +import Recognize from "@/components/ChatsPath/pages/Recognize"; +import YourGoal from "@/components/ChatsPath/pages/Answers/YourGoal"; +import SomethingWorrying from "@/components/ChatsPath/pages/Answers/SomethingWorrying"; +import ProneToOverthinking from "@/components/ChatsPath/pages/Answers/ProneToOverthinking"; +import WorriesImpact from "@/components/ChatsPath/pages/Answers/WorriesImpact"; +import SensitiveToCriticism from "@/components/ChatsPath/pages/Answers/SensitiveToCriticism"; +import HeadOrHeart from "@/components/ChatsPath/pages/Answers/HeadOrHeart"; +import HowConfident from "@/components/ChatsPath/pages/Answers/HowConfident"; +import NeedGuidance from "@/components/ChatsPath/pages/Answers/NeedGuidance"; +import DecisionGuidance from "@/components/ChatsPath/pages/Answers/DecisionGuidance"; +import ResonateLove from "@/components/ChatsPath/pages/Answers/ResonateLove"; +import ResonateLife from "@/components/ChatsPath/pages/Answers/ResonateLife"; +import ResonateFuture from "@/components/ChatsPath/pages/Answers/ResonateFuture"; +import PreferencesIntro from "@/components/ChatsPath/pages/PreferencesIntro"; +import BelieveInSpirituality from "@/components/ChatsPath/pages/Answers/BelieveInSpirituality"; +import ReadingExperience from "@/components/ChatsPath/pages/Answers/ReadingExperience"; +import InterestedHowLong from "@/components/ChatsPath/pages/Answers/InterestedHowLong"; +import MainReason from "@/components/ChatsPath/pages/Answers/MainReason"; +import WhatToExpect from "@/components/ChatsPath/pages/Answers/WhatToExpect"; +import GuidanceArea from "@/components/ChatsPath/pages/Answers/GuidanceArea"; +import PsychicComfortable from "@/components/ChatsPath/pages/Answers/PsychicComfortable"; +import UserName from "@/components/ChatsPath/pages/Answers/UserName"; +import Processing from "@/components/ChatsPath/pages/Processing"; + +const removePrefix = (path: string) => path.replace(chatsPrefix, ""); +const removePrefixQuiz = (path: string) => + path.replace(`${chatsPrefix}/quiz/`, ""); + +function ChatsRoutes() { + useEffect(() => { + localStorage.setItem("locales-placement", ELocalesPlacement.V1); + }, []); + + return ( + + }> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + > + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + + + + ); +} + +export default ChatsRoutes; diff --git a/src/routerComponents/Chats/styles.scss b/src/routerComponents/Chats/styles.scss new file mode 100644 index 0000000..9eedbb1 --- /dev/null +++ b/src/routerComponents/Chats/styles.scss @@ -0,0 +1,124 @@ +:root { + --primary-100: #e8e8fc; + --primary-200: #d2d1f9; + --primary-300: #bbbaf6; + --primary-400: #a5a3f3; + --primary: #8e8cf0; + --primary-rgb: 142, 140, 240; + --primary-600: #7270c0; + --primary-700: #555490; + --primary-800: #393860; + --primary-900: #1c1c30; + --secondary-100: #b1b1ce; + --secondary-200: #8a8ab5; + --secondary-300: #63639d; + --secondary-400: #505090; + --secondary: #3c3c84; + --secondary-600: #282861; + --secondary-700: #24244f; + --secondary-800: #141333; + --secondary-900: #0c0c1a; + --tertiary-100: #f1e1f7; + --tertiary-200: #e4c4f0; + --tertiary-300: #d6a6e8; + --tertiary-400: #c989e1; + --tertiary: #bb6bd9; + --tertiary-600: #9656ae; + --tertiary-700: #704082; + --tertiary-800: #4b2b57; + --tertiary-900: #25152b; + --success-100: #d3eadd; + --success-200: #a6d5ba; + --success-300: #7ac098; + --success-400: #4dab75; + --success: #219653; + --success-600: #1a7842; + --success-700: #145a32; + --success-800: #0d3c21; + --success-900: #071e11; + --error-100: #facfd0; + --error-200: #f49ea1; + --error-300: #ef6e73; + --error-400: #e93d44; + --error: #e40d15; + --error-600: #b60a11; + --error-700: #89080d; + --error-800: #5b0508; + --error-900: #2e0304; + --warning-100: #fcebdb; + --warning-200: #fad6b7; + --warning-300: #f7c292; + --warning-400: #f5ad6e; + --warning: #f2994a; + --warning-600: #c27a3b; + --warning-700: #915c2c; + --warning-800: #613d1e; + --warning-900: #301f0f; + --typography-100: #fafafa; + --typography-200: #e6e6e6; + --typography-300: #cdcdcd; + --typography-400: #9b9b9b; + --typography: #828282; + --typography-600: #686868; + --typography-700: #4e4e4e; + --typography-800: #343434; + --typography-900: #1a1a1a; + --star-100: #fae9b7; + --star-300: #f6d982; + --star: #f2c94c; + --star-700: #a98d35; + --star-900: #61501e; + --chart-100: #bbebfa; + --chart-300: #89dbf6; + --chart: #56ccf2; + --chart-700: #3c8fa9; + --chart-900: #225261; + --accent: #555bf6; + --white-with-opacity-5: hsla(0, 0%, 100%, 0.05); + --white-with-opacity-15: hsla(0, 0%, 100%, 0.15); + --white-with-opacity-25: hsla(0, 0%, 100%, 0.25); + --white-with-opacity-50: hsla(0, 0%, 100%, 0.5); + --star-with-opacity-70: rgba(242, 201, 76, 0.7); + --secondary-400-with-opacity-80: rgba(60, 60, 132, 0.8); + --secondary-400-with-opacity-40: rgba(60, 60, 132, 0.4); + --secondary-600-with-opacity-70: rgba(40, 40, 97, 0.7); + --primary-with-opacity-30: rgba(142, 140, 240, 0.3); + --primary-with-opacity-50: rgba(142, 140, 240, 0.5); + --primary-400-with-opacity-30: rgba(165, 163, 243, 0.3); + --primary-700-with-opacity-30: rgba(85, 84, 144, 0.3); + --primary-900-with-opacity-40: rgba(28, 28, 48, 0.4); + --warning-with-opacity-20: rgba(242, 153, 74, 0.2); + --shadow: rgba(36, 36, 79, 0.56); + --typography-200-with-opacity-50: hsla(0, 0%, 90%, 0.5); + --gradient-pink-right-part: #f2994a; + --gradient-pink-left-part: #6a4dbc; + --gradient-pink-base: linear-gradient( + 90.6deg, + #6a4dbc 0.47%, + #f2994a 137.94% + ); + --gradient-eclipse: linear-gradient(91deg, #b57ce2 0.47%, #f0aea8 137.94%); + --gradient-tranquil: linear-gradient(83.5deg, #5e6ffd -15.87%, #aa8aca 96.3%); + --gradient-azure: linear-gradient(38.65deg, #4568dc 27.36%, #b06ab3 87.78%); + --gradient-amethyst: linear-gradient( + 180deg, + #141333, + #202261 70.63%, + #3a237a + ); + --primary-page-background: #141333; + --alternative-page-background: #24244f; + --white: #fff; +} + +.chats-answers-title { + font-size: 18px; + line-height: 21px; + font-weight: 700; + margin-bottom: 24px; + color: var(--typography-100); +} + +body * { + font-family: Open Sans, sans-serif; +} diff --git a/src/routes.ts b/src/routes.ts index 5a09f7d..2f30fff 100755 --- a/src/routes.ts +++ b/src/routes.ts @@ -14,6 +14,8 @@ const openAiPrefix = environments.AURA_OPEN_AI_PREFIX; export const palmistryV1Prefix = [host, "v1", "palmistry"].join("/") +export const chatsPrefix = [host, "chats"].join("/") + const routes = { client: { root: () => [host, ""].join("/"), @@ -240,6 +242,46 @@ const routes = { loadingPage: () => [host, "loading-page"].join("/"), notFound: () => [host, "404"].join("/"), + + chatsWelcome: () => [chatsPrefix, "welcome"].join("/"), + chatsQuiz: () => [chatsPrefix, "quiz"].join("/"), + chatsQuizPsychicReading: () => [chatsPrefix, "quiz", "psychicReading"].join("/"), + chatsGuidance: () => [chatsPrefix, "guidance"].join("/"), + chatsQuizGoal: () => [chatsPrefix, "quiz", "goal"].join("/"), + chatsGoalSetup: () => [chatsPrefix, "goalSetup"].join("/"), + chatsReviews: () => [chatsPrefix, "reviews"].join("/"), + chatsQuizRelationshipStatus: () => [chatsPrefix, "quiz", "relationshipStatus"].join("/"), + chatsQuizDate: () => [chatsPrefix, "quiz", "date"].join("/"), + chatsQuizParentStatus: () => [chatsPrefix, "quiz", "parentStatus"].join("/"), + chatsProfileIntro: () => [chatsPrefix, "profileIntro"].join("/"), + chatsQuizSatisfiedWithLife: () => [chatsPrefix, "quiz", "satisfiedWithLife"].join("/"), + chatsQuizWhatEmotion: () => [chatsPrefix, "quiz", "whatEmotion"].join("/"), + chatsAnswerHub: () => [chatsPrefix, "answerHub"].join("/"), + chatsQuizWhatYouWant: () => [chatsPrefix, "quiz", "whatYouWant"].join("/"), + chatsQuizMissingInLife: () => [chatsPrefix, "quiz", "missingInLife"].join("/"), + chatsRecognize: () => [chatsPrefix, "recognize"].join("/"), + chatsQuizYourGoal: () => [chatsPrefix, "quiz", "yourGoal"].join("/"), + chatsQuizSomethingWorrying: () => [chatsPrefix, "quiz", "somethingWorrying"].join("/"), + chatsQuizProneToOverthinking: () => [chatsPrefix, "quiz", "proneToOverthinking"].join("/"), + chatsQuizWorriesImpact: () => [chatsPrefix, "quiz", "worriesImpact"].join("/"), + chatsQuizSensitiveToCriticism: () => [chatsPrefix, "quiz", "sensitiveToCriticism"].join("/"), + chatsQuizHeadOrHeart: () => [chatsPrefix, "quiz", "headOrHeart"].join("/"), + chatsQuizHowConfident: () => [chatsPrefix, "quiz", "howConfident"].join("/"), + chatsQuizNeedGuidance: () => [chatsPrefix, "quiz", "needGuidance"].join("/"), + chatsQuizDecisionGuidance: () => [chatsPrefix, "quiz", "decisionGuidance"].join("/"), + chatsQuizResonateLove: () => [chatsPrefix, "quiz", "resonateLove"].join("/"), + chatsQuizResonateLife: () => [chatsPrefix, "quiz", "resonateLife"].join("/"), + chatsQuizResonateFuture: () => [chatsPrefix, "quiz", "resonateFuture"].join("/"), + chatsPreferencesIntro: () => [chatsPrefix, "preferencesIntro"].join("/"), + chatsQuizBelieveInSpirituality: () => [chatsPrefix, "quiz", "believeInSpirituality"].join("/"), + chatsQuizReadingExperience: () => [chatsPrefix, "quiz", "readingExperience"].join("/"), + chatsQuizInterestedHowLong: () => [chatsPrefix, "quiz", "interestedHowLong"].join("/"), + chatsQuizMainReason: () => [chatsPrefix, "quiz", "mainReason"].join("/"), + chatsQuizWhatToExpect: () => [chatsPrefix, "quiz", "whatToExpect"].join("/"), + chatsQuizGuidanceArea: () => [chatsPrefix, "quiz", "guidanceArea"].join("/"), + chatsQuizPsychicComfortable: () => [chatsPrefix, "quiz", "psychicComfortable"].join("/"), + chatsQuizUserName: () => [chatsPrefix, "quiz", "userName"].join("/"), + chatsQuizProcessing: () => [chatsPrefix, "quiz", "processing"].join("/"), }, server: { userLocale: () => ["https://ipapi.co", "json"].join("/"), diff --git a/src/store/chats.ts b/src/store/chats.ts new file mode 100644 index 0000000..6a381c3 --- /dev/null +++ b/src/store/chats.ts @@ -0,0 +1,108 @@ +import { createSlice, createSelector } from "@reduxjs/toolkit"; +import type { PayloadAction } from "@reduxjs/toolkit"; + +interface IChatsAnswers { + psychicReading: string; + goal: string; + relationshipStatus: string; + satisfiedWithLife: string; + parentStatus: string; + whatEmotion: string; + whatYouWant: string; + missingInLife: string; + yourGoal: string; + somethingWorrying: string; + proneToOverthinking: string; + worriesImpact: string; + sensitiveToCriticism: string; + headOrHeart: string; + howConfident: string; + needGuidance: string; + decisionGuidance: string; + resonateLove: string; + resonateLife: string; + resonateFuture: string; + believeInSpirituality: string; + readingExperience: string; + interestedHowLong: string; + mainReason: string; + whatToExpect: string; + guidanceArea: string[]; + psychicComfortable: string[]; + userName: string; +} + +interface IChats { + currentStep: number; + answers: IChatsAnswers; +} + +const initialState: IChats = { + currentStep: 0, + answers: { + psychicReading: "", + goal: "", + relationshipStatus: "", + satisfiedWithLife: "", + parentStatus: "", + whatEmotion: "", + whatYouWant: "", + missingInLife: "", + yourGoal: "", + somethingWorrying: "", + proneToOverthinking: "", + worriesImpact: "", + sensitiveToCriticism: "", + headOrHeart: "", + howConfident: "", + needGuidance: "", + decisionGuidance: "", + resonateLove: "", + resonateLife: "", + resonateFuture: "", + believeInSpirituality: "", + readingExperience: "", + interestedHowLong: "", + mainReason: "", + whatToExpect: "", + guidanceArea: [], + psychicComfortable: [], + userName: "", + } +}; + +const chatsSlice = createSlice({ + name: "chats", + initialState, + reducers: { + update(state, action: PayloadAction>) { + return { ...state, ...action.payload }; + }, + updateCurrentStep(state, action: PayloadAction) { + return { ...state, currentStep: action.payload }; + }, + updateAnswers(state, action: PayloadAction>) { + return { + ...state, answers: { + ...state.answers, + ...action.payload + } + }; + }, + }, + extraReducers: (builder) => builder.addCase("reset", () => initialState), +}); + +export const { actions } = chatsSlice; + +export const selectCurrentStep = createSelector( + (state: { chats: IChats }) => state.chats.currentStep, + (chats) => chats +); + +export const selectAnswers = createSelector( + (state: { chats: IChats }) => state.chats.answers, + (chats) => chats +); + +export default chatsSlice.reducer; diff --git a/src/store/index.ts b/src/store/index.ts index 97cccd2..c67ee10 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -87,6 +87,7 @@ import palmistry, { 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"; const preloadedState = loadStore(); export const actions = { @@ -111,6 +112,7 @@ export const actions = { palmistry: palmistryActions, privacyPolicy: privacyPolicyActions, personalVideo: personalVideoActions, + chats: chatsActions, reset: createAction("reset"), }; export const selectors = { @@ -158,6 +160,8 @@ export const selectors = { selectCurrency, selectPalmistryFromRedesign, selectPalmistryIsShowPaymentModalV1, + selectCurrentStep, + selectAnswers, ...formSelectors, }; @@ -182,7 +186,8 @@ export const reducer = combineReducers({ palmistry, paywalls, privacyPolicy, - personalVideo + personalVideo, + chats }); export type RootState = ReturnType; diff --git a/src/utils/FBMetaPixel/index.tsx b/src/utils/FBMetaPixel/index.tsx index 067028d..bbca021 100644 --- a/src/utils/FBMetaPixel/index.tsx +++ b/src/utils/FBMetaPixel/index.tsx @@ -88,8 +88,9 @@ fbq('track', 'PageView'); `; )} {locale === "es" && } - {isRouteInclude(window.location.href, routesPalmistry) && - locale === "es" && } + {isRouteInclude(window.location.href, routesPalmistry) && ( + + )} ); };