diff --git a/package-lock.json b/package-lock.json index ef5a2a7..a20bded 100644 --- a/package-lock.json +++ b/package-lock.json @@ -352,11 +352,11 @@ } }, "node_modules/@babel/runtime": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", - "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz", + "integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==", "dependencies": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" @@ -1048,9 +1048,9 @@ "dev": true }, "node_modules/@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/react": { "version": "18.2.6", @@ -2591,9 +2591,9 @@ "dev": true }, "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true, "funding": [ { @@ -2757,9 +2757,9 @@ } }, "node_modules/postcss": { - "version": "8.4.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", - "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==", + "version": "8.4.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", + "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==", "dev": true, "funding": [ { @@ -2776,7 +2776,7 @@ } ], "dependencies": { - "nanoid": "^3.3.6", + "nanoid": "^3.3.7", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -2993,9 +2993,9 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" }, "node_modules/reselect": { "version": "4.1.8", @@ -3681,11 +3681,11 @@ } }, "@babel/runtime": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", - "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz", + "integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==", "requires": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" } }, "@babel/template": { @@ -4096,9 +4096,9 @@ "dev": true }, "@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "@types/react": { "version": "18.2.6", @@ -5205,9 +5205,9 @@ "dev": true }, "nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true }, "natural-compare": { @@ -5320,12 +5320,12 @@ "dev": true }, "postcss": { - "version": "8.4.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", - "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==", + "version": "8.4.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", + "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==", "dev": true, "requires": { - "nanoid": "^3.3.6", + "nanoid": "^3.3.7", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } @@ -5458,9 +5458,9 @@ "requires": {} }, "regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" }, "reselect": { "version": "4.1.8", diff --git a/public/anxious_face_with_sweat.png b/public/anxious_face_with_sweat.png new file mode 100644 index 0000000..de72505 Binary files /dev/null and b/public/anxious_face_with_sweat.png differ diff --git a/public/blue_book.png b/public/blue_book.png new file mode 100644 index 0000000..18afa1b Binary files /dev/null and b/public/blue_book.png differ diff --git a/public/brain.png b/public/brain.png new file mode 100644 index 0000000..77598c4 Binary files /dev/null and b/public/brain.png differ diff --git a/public/broken_heart.png b/public/broken_heart.png new file mode 100644 index 0000000..f675240 Binary files /dev/null and b/public/broken_heart.png differ diff --git a/public/bunch_of_cards.webp b/public/bunch_of_cards.webp new file mode 100644 index 0000000..7b445d3 Binary files /dev/null and b/public/bunch_of_cards.webp differ diff --git a/public/check_mark_button.png b/public/check_mark_button.png new file mode 100644 index 0000000..6c3d3db Binary files /dev/null and b/public/check_mark_button.png differ diff --git a/public/couple_holding_hands_1.webp b/public/couple_holding_hands_1.webp new file mode 100644 index 0000000..66ffa37 Binary files /dev/null and b/public/couple_holding_hands_1.webp differ diff --git a/public/cross_mark.png b/public/cross_mark.png new file mode 100644 index 0000000..4cc4dfc Binary files /dev/null and b/public/cross_mark.png differ diff --git a/public/date_of_birth_zodiac_signs.webp b/public/date_of_birth_zodiac_signs.webp new file mode 100644 index 0000000..0f95f49 Binary files /dev/null and b/public/date_of_birth_zodiac_signs.webp differ diff --git a/public/face_with_monocle.png b/public/face_with_monocle.png new file mode 100644 index 0000000..c97c7f6 Binary files /dev/null and b/public/face_with_monocle.png differ diff --git a/public/face_with_raised_eyebrow.png b/public/face_with_raised_eyebrow.png new file mode 100644 index 0000000..44df814 Binary files /dev/null and b/public/face_with_raised_eyebrow.png differ diff --git a/public/fearful_face.png b/public/fearful_face.png new file mode 100644 index 0000000..2ea1cf7 Binary files /dev/null and b/public/fearful_face.png differ diff --git a/public/female.webp b/public/female.webp new file mode 100644 index 0000000..12676f4 Binary files /dev/null and b/public/female.webp differ diff --git a/public/hands_heart.png b/public/hands_heart.png new file mode 100644 index 0000000..6bda045 Binary files /dev/null and b/public/hands_heart.png differ diff --git a/public/heart.png b/public/heart.png new file mode 100644 index 0000000..68cb64e Binary files /dev/null and b/public/heart.png differ diff --git a/public/heart_of_couple.webp b/public/heart_of_couple.webp new file mode 100644 index 0000000..41fff5a Binary files /dev/null and b/public/heart_of_couple.webp differ diff --git a/public/kiss.png b/public/kiss.png new file mode 100644 index 0000000..d5df0b1 Binary files /dev/null and b/public/kiss.png differ diff --git a/public/loudspeaker.png b/public/loudspeaker.png new file mode 100644 index 0000000..b0c356f Binary files /dev/null and b/public/loudspeaker.png differ diff --git a/public/magnifier.svg b/public/magnifier.svg new file mode 100644 index 0000000..efa9595 --- /dev/null +++ b/public/magnifier.svg @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/male.webp b/public/male.webp new file mode 100644 index 0000000..80edacc Binary files /dev/null and b/public/male.webp differ diff --git a/public/man.png b/public/man.png new file mode 100644 index 0000000..5123fba Binary files /dev/null and b/public/man.png differ diff --git a/public/man_student.png b/public/man_student.png new file mode 100644 index 0000000..69fa064 Binary files /dev/null and b/public/man_student.png differ diff --git a/public/microscope.png b/public/microscope.png new file mode 100644 index 0000000..96f7331 Binary files /dev/null and b/public/microscope.png differ diff --git a/public/moon_phases.webp b/public/moon_phases.webp new file mode 100644 index 0000000..2c6bbf8 Binary files /dev/null and b/public/moon_phases.webp differ diff --git a/public/mountain.png b/public/mountain.png new file mode 100644 index 0000000..fd57f38 Binary files /dev/null and b/public/mountain.png differ diff --git a/public/neutral_face.png b/public/neutral_face.png new file mode 100644 index 0000000..8de34a7 Binary files /dev/null and b/public/neutral_face.png differ diff --git a/public/paperclip.png b/public/paperclip.png new file mode 100644 index 0000000..5aa7a46 Binary files /dev/null and b/public/paperclip.png differ diff --git a/public/party_popper.png b/public/party_popper.png new file mode 100644 index 0000000..36ea27d Binary files /dev/null and b/public/party_popper.png differ diff --git a/public/raising_hands.png b/public/raising_hands.png new file mode 100644 index 0000000..2792952 Binary files /dev/null and b/public/raising_hands.png differ diff --git a/public/red-heart.png b/public/red-heart.png new file mode 100644 index 0000000..68cb64e Binary files /dev/null and b/public/red-heart.png differ diff --git a/public/ring.png b/public/ring.png new file mode 100644 index 0000000..81ecd7f Binary files /dev/null and b/public/ring.png differ diff --git a/public/scales.png b/public/scales.png new file mode 100644 index 0000000..056b607 Binary files /dev/null and b/public/scales.png differ diff --git a/public/shield.png b/public/shield.png new file mode 100644 index 0000000..3b35d47 Binary files /dev/null and b/public/shield.png differ diff --git a/public/slightly_frowning_face.png b/public/slightly_frowning_face.png new file mode 100644 index 0000000..1c9a4b2 Binary files /dev/null and b/public/slightly_frowning_face.png differ diff --git a/public/slightly_smiling_face.png b/public/slightly_smiling_face.png new file mode 100644 index 0000000..0ace972 Binary files /dev/null and b/public/slightly_smiling_face.png differ diff --git a/public/small_alarm_clock.webp b/public/small_alarm_clock.webp new file mode 100644 index 0000000..f3adc1b Binary files /dev/null and b/public/small_alarm_clock.webp differ diff --git a/public/sparkles.png b/public/sparkles.png new file mode 100644 index 0000000..f4cb73b Binary files /dev/null and b/public/sparkles.png differ diff --git a/public/star_struck.png b/public/star_struck.png new file mode 100644 index 0000000..12d5a94 Binary files /dev/null and b/public/star_struck.png differ diff --git a/public/starry-clock.svg b/public/starry-clock.svg new file mode 100644 index 0000000..855aece --- /dev/null +++ b/public/starry-clock.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/starry-sky.svg b/public/starry-sky.svg new file mode 100644 index 0000000..d47ecb2 --- /dev/null +++ b/public/starry-sky.svg @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/starry_key.svg b/public/starry_key.svg new file mode 100644 index 0000000..37e9fd8 --- /dev/null +++ b/public/starry_key.svg @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/thinking_face.png b/public/thinking_face.png new file mode 100644 index 0000000..abb9aa1 Binary files /dev/null and b/public/thinking_face.png differ diff --git a/public/thumbs_down.png b/public/thumbs_down.png new file mode 100644 index 0000000..ed957be Binary files /dev/null and b/public/thumbs_down.png differ diff --git a/public/thumbs_middle.png b/public/thumbs_middle.png new file mode 100644 index 0000000..5cce493 Binary files /dev/null and b/public/thumbs_middle.png differ diff --git a/public/thumbs_more_down.png b/public/thumbs_more_down.png new file mode 100644 index 0000000..ab6a099 Binary files /dev/null and b/public/thumbs_more_down.png differ diff --git a/public/thumbs_up.png b/public/thumbs_up.png new file mode 100644 index 0000000..c2660e5 Binary files /dev/null and b/public/thumbs_up.png differ diff --git a/public/two-hearts.png b/public/two-hearts.png new file mode 100644 index 0000000..fde1bf7 Binary files /dev/null and b/public/two-hearts.png differ diff --git a/public/unamused.png b/public/unamused.png new file mode 100644 index 0000000..3d0e885 Binary files /dev/null and b/public/unamused.png differ diff --git a/public/wall_clock.webp b/public/wall_clock.webp new file mode 100644 index 0000000..ebb34cf Binary files /dev/null and b/public/wall_clock.webp differ diff --git a/public/woman-heart-man.png b/public/woman-heart-man.png new file mode 100644 index 0000000..de4135d Binary files /dev/null and b/public/woman-heart-man.png differ diff --git a/public/woman.png b/public/woman.png new file mode 100644 index 0000000..de1b60d Binary files /dev/null and b/public/woman.png differ diff --git a/src/components/Answer/index.tsx b/src/components/Answer/index.tsx new file mode 100644 index 0000000..719175c --- /dev/null +++ b/src/components/Answer/index.tsx @@ -0,0 +1,18 @@ +import { IAnswer } from "@/data"; +import styles from "./styles.module.css"; + +interface IAnswerProps { + answer: IAnswer; + onClick: () => void; +} + +function Answer({ answer, onClick }: IAnswerProps) { + return ( +
+ {answer.id} +

{answer.answer}

+
+ ); +} + +export default Answer; diff --git a/src/components/Answer/styles.module.css b/src/components/Answer/styles.module.css new file mode 100644 index 0000000..361279a --- /dev/null +++ b/src/components/Answer/styles.module.css @@ -0,0 +1,31 @@ +.container { + display: flex; + gap: 12px; + -webkit-box-align: center; + align-items: center; + justify-content: left; + text-align: left; + border: 1px solid rgb(224, 224, 224); + box-sizing: border-box; + border-radius: 10px; + min-height: 64px; + width: 100%; + cursor: pointer; + padding-left: 24px; + padding-right: 24px; + margin-left: auto; + margin-right: auto; + box-shadow: rgba(84, 60, 151, 0.25) 2px 2px 6px; + background: rgb(234, 238, 247); +} + +.icon { + width: 48px; + height: 48px; +} + +.answer { + font-size: 14px; + line-height: 20px; + color: #000; +} diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index 43bc5f1..06cb687 100644 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -60,6 +60,14 @@ import ThermalResult from "../pages/ThermalResult"; import MoonPhaseTrackerResult from "../pages/MoonPhaseTrackerResult"; import EnergyVampirismResult from "../pages/EnergyVampirismResult"; import NameHoroscopeResult from "../pages/NameHoroscopeResult"; +import GenderPage from "../pages/Gender"; +import QuestionnairePage from "../pages/Questionnaire"; +import GoalSetupPage from "../pages/GoalSetup"; +import HyperPersonalizedAstrologyPage from "../pages/HyperPersonalizedAstrologyPage"; +import NoBirthtimePage from "../pages/NoBirthtime"; +import LoadingInRelationshipPage from "../pages/LoadingInRelationship"; +import WorksForUsPage from "../pages/WorksForUs"; +import RelationshipAlmostTherePage from "../pages/RelationshipAlmostThere"; import Modal from "../Modal"; import FullDataModal from "../FullDataModal"; @@ -135,6 +143,34 @@ function App(): JSX.Element { return ( }> + {/* Test Routes Start */} + } /> + } /> + } + > + }> + } /> + + + } /> + } + /> + } /> + } + /> + } /> + } + /> + {/* Test Routes End */} + } @@ -197,77 +233,71 @@ function App(): JSX.Element { } /> - }> - }> - {/* }> */} + }> + {/* } /> */} - } - /> - } - /> - - }> - } /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - + } + /> + } + /> + {/* }> */} + } /> + } + /> + } + /> + } + /> + } + /> + } /> + } /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + {/* */} + {/* */} } /> @@ -401,25 +431,25 @@ function AuthorizedUserOutlet(): JSX.Element { ); } -function PrivateOutlet(): JSX.Element { - const { user } = useAuth(); - return user ? ( - - ) : ( - - ); -} +// function PrivateOutlet(): JSX.Element { +// const { user } = useAuth(); +// return user ? ( +// +// ) : ( +// +// ); +// } -function PrivateSubscriptionOutlet(): JSX.Element { - // const isProduction = import.meta.env.MODE === "production"; - const isProduction = false; - const status = useSelector(selectors.selectStatus); - return status === "subscribed" || !isProduction ? ( - - ) : ( - - ); -} +// function PrivateSubscriptionOutlet(): JSX.Element { +// // const isProduction = import.meta.env.MODE === "production"; +// const isProduction = false; +// const status = useSelector(selectors.selectStatus); +// return status === "subscribed" || !isProduction ? ( +// +// ) : ( +// +// ); +// } function getIsShowFullDataModal(dataItems: Array = []): boolean { let hasNoDataItem = false; diff --git a/src/components/AttentionPage/index.tsx b/src/components/AttentionPage/index.tsx index c8895a8..43b3d6e 100644 --- a/src/components/AttentionPage/index.tsx +++ b/src/components/AttentionPage/index.tsx @@ -17,7 +17,7 @@ function AttentionPage({ }: AttentionPageProps): JSX.Element { const { t } = useTranslation(); const navigate = useNavigate(); - const handleNext = () => navigate(routes.client.priceList()); + const handleNext = () => navigate(routes.client.home()); return (
diff --git a/src/components/DateTimePicker/TimePicker.tsx b/src/components/DateTimePicker/TimePicker.tsx index 923daf6..e0b9e77 100644 --- a/src/components/DateTimePicker/TimePicker.tsx +++ b/src/components/DateTimePicker/TimePicker.tsx @@ -1,31 +1,36 @@ -import { useEffect, useState } from "react" -import { normalize, parse, format } from "./utils" +import { useEffect, useState } from "react"; +import { normalize, parse, format } from "./utils"; type TimePickerProps = { - value: string - onChange: (value: string) => void -} + value: string; + onChange: (value: string) => void; +}; export function TimePicker({ value, onChange }: TimePickerProps): JSX.Element { - const parsedValue = parse(value) - const [hour, setHour] = useState(parsedValue.hour) - const [minute, setMinute] = useState(parsedValue.minute) - const [period, setPeriod] = useState(parsedValue.period) + const parsedValue = parse(value); + const [hour, setHour] = useState(parsedValue.hour); + const [minute, setMinute] = useState(parsedValue.minute); + const [period, setPeriod] = useState(parsedValue.period); useEffect(() => { - onChange(format(hour, minute, period)) - }, [hour, minute, period, onChange]) + onChange(format(hour, minute, period)); + }, [hour, minute, period, onChange]); return ( -
-
+
+
@@ -33,10 +38,15 @@ export function TimePicker({ value, onChange }: TimePickerProps): JSX.Element { @@ -45,12 +55,15 @@ export function TimePicker({ value, onChange }: TimePickerProps): JSX.Element {
- ) + ); } diff --git a/src/components/PlacePicker/index.tsx b/src/components/PlacePicker/index.tsx new file mode 100644 index 0000000..8f3d2b2 --- /dev/null +++ b/src/components/PlacePicker/index.tsx @@ -0,0 +1,31 @@ +import styles from "./styles.module.css"; + +interface IPlacePickerProps { + name: string; + value: string; + maxLength: number; + onChange: (value: string) => void; +} + +function PlacePicker({ name, value, maxLength, onChange }: IPlacePickerProps) { + const handleChange = (e: React.ChangeEvent) => { + const place = e.target.value; + onChange(place); + }; + + return ( +
+ +
+ ); +} + +export default PlacePicker; diff --git a/src/components/PlacePicker/styles.module.css b/src/components/PlacePicker/styles.module.css new file mode 100644 index 0000000..54aa6f8 --- /dev/null +++ b/src/components/PlacePicker/styles.module.css @@ -0,0 +1,13 @@ +.container { + width: 100%; +} + +.full-address { + width: 100%; + background: transparent; + color: rgb(51, 51, 51); + border: 1px solid rgb(51, 51, 51); + border-radius: 25px; + padding: 10px 15px; + line-height: 24px; +} diff --git a/src/components/Stepper/index.tsx b/src/components/Stepper/index.tsx new file mode 100644 index 0000000..77c08c6 --- /dev/null +++ b/src/components/Stepper/index.tsx @@ -0,0 +1,77 @@ +import { IStep } from "@/data"; +import styles from "./styles.module.css"; + +interface IStepperProps { + steps: IStep[]; + currentStep: number; + currentQuestion: number; +} + +function Stepper({ steps, currentStep, currentQuestion }: IStepperProps) { + const lastStepIndex = steps.length - 1; + const getLinePercent = (index: number) => { + if (index < currentStep) { + return 100; + } else if (index === currentStep) { + const percent = (currentQuestion / steps[index].questions.length) * 100; + if (percent > 100) { + return 100; + } + return percent; + } else { + return 0; + } + }; + + const getIndexOfStep = (id: string) => { + return steps.findIndex((item) => item.id === id); + }; + + return ( +
+ {steps.map((step, index) => { + return ( +
+
currentStep ? "transparent" : step.color, + borderColor: step.color, + color: step.color, + }} + > + {index > currentStep ? getIndexOfStep(step.id) : null} +
+
+
+
+
+ ); + })} +
= currentStep ? "transparent" : "#bb6bd9", + borderColor: "#bb6bd9", + color: "#bb6bd9", + }} + > + {lastStepIndex >= currentStep ? lastStepIndex + 1 : null} +
+
+ ); +} + +export default Stepper; diff --git a/src/components/Stepper/styles.module.css b/src/components/Stepper/styles.module.css new file mode 100644 index 0000000..efbdfaa --- /dev/null +++ b/src/components/Stepper/styles.module.css @@ -0,0 +1,40 @@ +.container { + width: 100%; + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + gap: 0; +} + +.step-container { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + gap: 0; +} + +.circle { + width: 16px; + height: 16px; + border-radius: 50%; + border-width: 1px; + border-style: solid; + display: flex; + align-items: center; + justify-content: center; + font-size: 8px; +} + +.line-container { + height: 6px; + width: 100%; + background-color: #d2d1f9; +} + +.line { + height: 100%; + /* width: 0; */ + transition: width 0.4s linear 0s; +} diff --git a/src/components/pages/Gender/index.tsx b/src/components/pages/Gender/index.tsx new file mode 100644 index 0000000..c2a5705 --- /dev/null +++ b/src/components/pages/Gender/index.tsx @@ -0,0 +1,65 @@ +import styles from "./styles.module.css"; +import Title from "@/components/Title"; +import { Gender, genders } from "@/data"; +import { actions } from "@/store"; +import { useDispatch } from "react-redux"; +import { useNavigate } from "react-router-dom"; + +function GenderPage(): JSX.Element { + const dispatch = useDispatch(); + const navigate = useNavigate(); + + const selectGender = (gender: Gender) => { + dispatch(actions.questionnaire.update({ gender: gender.id })); + navigate(`/questionnaire/profile/flowChoice`); + }; + + const getButtonBGColor = (gender: Gender): string => { + const { colorAssociation } = gender; + if (Array.isArray(colorAssociation)) { + return `linear-gradient(125.02deg, ${colorAssociation.join(", ")})`; + } + if (typeof colorAssociation === "string") { + return colorAssociation; + } + return "#f5f5f5"; + }; + + return ( +
+ + Understand Yourself and Improve Relationships With Astrology + + 1-Minute Personal Assessment + + Select your gender: + +
+ {genders.map((gender, index) => ( +
{ + selectGender(gender); + }} + > + {gender.id} + +
+ ))} +
+
+ ); +} + +export default GenderPage; diff --git a/src/components/pages/Gender/styles.module.css b/src/components/pages/Gender/styles.module.css new file mode 100644 index 0000000..696d252 --- /dev/null +++ b/src/components/pages/Gender/styles.module.css @@ -0,0 +1,75 @@ +.page { + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; +} + +.title { + font-size: 22px; + font-weight: 700; + margin: 0; +} + +.title-select { + margin: 0; + font-size: 18px; + font-weight: 700; +} + +.description { + font-size: 14px; + font-weight: 500; +} + +.genders-container { + display: flex; + flex-direction: row; + justify-content: center; + flex-wrap: wrap; + gap: 20px; + width: 100%; +} + +.gender { + display: flex; + flex-direction: column; + align-items: center; + gap: 0; + width: 100%; + max-width: 150px; + cursor: pointer; +} + +.gender__img { + width: 100%; + height: 174px; +} + +.gender__button { + border: none; + width: 100%; + display: flex; + -webkit-box-pack: justify; + justify-content: space-between; + -webkit-box-align: center; + align-items: center; + text-transform: capitalize; + height: 52px; + background: #454895; + border-bottom-left-radius: 16px; + border-bottom-right-radius: 16px; + color: #fbfbff; + padding-left: 16px; + padding-right: 16px; + font-size: 18px; + line-height: 21px; +} + +.button__arrow { + border-right: 2px solid rgb(251, 251, 255); + border-bottom: 2px solid rgb(251, 251, 255); + display: inline-block; + padding: 5px; + transform: rotate(-45deg); +} diff --git a/src/components/pages/GoalSetup/index.tsx b/src/components/pages/GoalSetup/index.tsx new file mode 100644 index 0000000..1db563d --- /dev/null +++ b/src/components/pages/GoalSetup/index.tsx @@ -0,0 +1,47 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.css"; +import MainButton from "@/components/MainButton"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; + +function GoalSetupPage() { + const navigate = useNavigate(); + + const handleBack = () => { + navigate(-1); + }; + + const handleNext = () => { + navigate(`${routes.client.questionnaire()}/profile/parent`); + }; + + return ( +
+ The starry sky +
+ + Great! You just set your first goal! + +

+ Let's keep going so we can get to know you better. +

+
+
+ + Back + + + Next + +
+
+ ); +} + +export default GoalSetupPage; diff --git a/src/components/pages/GoalSetup/styles.module.css b/src/components/pages/GoalSetup/styles.module.css new file mode 100644 index 0000000..ddc199d --- /dev/null +++ b/src/components/pages/GoalSetup/styles.module.css @@ -0,0 +1,57 @@ +.page { + position: relative; + height: fit-content; + min-height: 100vh; + display: flex; + justify-content: start; + align-items: center; + flex-direction: column; + gap: 40px; + background: linear-gradient( + 165.54deg, + rgb(20, 19, 51) -33.39%, + rgb(32, 34, 97) 15.89%, + rgb(84, 60, 151) 55.84%, + rgb(105, 57, 162) 74.96% + ); + color: #fff; + padding-top: 64px; +} + +.title { + font-size: 24px; + line-height: 28px; + max-width: 322px; +} + +.text { + font-size: 14px; + text-align: center; + line-height: 140%; + max-width: 322px; +} + +.buttons-container { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + gap: 10px; +} + +.button { + width: 160px; + min-width: fit-content; + height: 48px; + min-height: fit-content; + border: solid 1px #fff; + border-radius: 16px; + font-size: 18px; + font-weight: 500; + background-color: transparent; +} + +.next-button { + background-color: #fff; + color: #6a3aa2; +} diff --git a/src/components/pages/HyperPersonalizedAstrologyPage/index.tsx b/src/components/pages/HyperPersonalizedAstrologyPage/index.tsx new file mode 100644 index 0000000..420c118 --- /dev/null +++ b/src/components/pages/HyperPersonalizedAstrologyPage/index.tsx @@ -0,0 +1,43 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.css"; +import MainButton from "@/components/MainButton"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; + +function HyperPersonalizedAstrologyPage() { + const navigate = useNavigate(); + + const handleNext = () => { + navigate(`${routes.client.questionnaire()}/profile/birthdate`); + }; + + return ( +
+ + What is{" "} + <span className={styles.gradient}>hyper-personalized astrology,</span>{" "} + anyway? + +

+ Personalized astrology is based on the understanding that everyone has a + unique astrological blueprint. The position of the stars in the sky on + your date of birth, place of birth and time of birth are unique and only + happen in one lifetime. You are more than just your zodiac sign! +

+ + So how does it work? + +

+ We analyze hundreds of data points to create your unique astrological + blueprint. This is combined with AI to tailor-make your astrological + insights, based on your answers. We’re going to change your relationship + with astrology. +

+ + Next + +
+ ); +} + +export default HyperPersonalizedAstrologyPage; diff --git a/src/components/pages/HyperPersonalizedAstrologyPage/styles.module.css b/src/components/pages/HyperPersonalizedAstrologyPage/styles.module.css new file mode 100644 index 0000000..0826b8f --- /dev/null +++ b/src/components/pages/HyperPersonalizedAstrologyPage/styles.module.css @@ -0,0 +1,60 @@ +.page { + position: relative; + height: fit-content; + min-height: 100vh; + display: flex; + justify-content: start; + align-items: center; + flex-direction: column; + gap: 20px; + background: url("/moon_phases.webp"); + background-position-y: bottom; + background-position-x: center; + background-size: cover; + background-repeat: no-repeat; + color: #fff; + padding-top: 64px; +} + +.title { + font-size: 24px; + font-weight: 700; + line-height: 28px; + max-width: 322px; + text-align: center; + margin: 0; +} + +.gradient { + -webkit-text-fill-color: transparent; + background: linear-gradient( + 0deg, + rgba(255, 255, 255, 0.2), + rgba(255, 255, 255, 0.2) + ) + text, + linear-gradient(90.6deg, rgb(106, 77, 188) 0.47%, rgb(242, 153, 74) 137.94%); + background-clip: text; + -webkit-background-clip: text; + color: rgb(187, 108, 217); +} + +.text { + font-size: 14px; + text-align: center; + line-height: 180%; + color: rgb(251, 251, 255); + max-width: 322px; +} + +.button { + max-width: 330px; + width: 100%; + background-color: #fff; + color: #6a3aa2; + height: 49px; + min-height: fit-content; + border-radius: 12px; + font-weight: 400; + margin-top: 30px; +} diff --git a/src/components/pages/LoadingInRelationship/index.tsx b/src/components/pages/LoadingInRelationship/index.tsx new file mode 100644 index 0000000..d7d213b --- /dev/null +++ b/src/components/pages/LoadingInRelationship/index.tsx @@ -0,0 +1,73 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.css"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import { getRandomArbitrary } from "@/services/random-value"; +import { useSelector } from "react-redux"; +import { selectors } from "@/store"; +import { getZodiacSignByDate } from "@/services/zodiac-sign"; +import { useEffect, useMemo, useRef, useState } from "react"; +import { CircularProgressbar } from "react-circular-progressbar"; + +function LoadingInRelationshipPage() { + const navigate = useNavigate(); + const { birthdate, gender } = useSelector(selectors.selectQuestionnaire); + const [loadingProgress, setLoadingProgress] = useState(100); + const intervalRef = useRef(); + const randomValue = useMemo(() => { + return [getRandomArbitrary(300, 995), getRandomArbitrary(3, 995)]; + }, []); + + useEffect(() => { + intervalRef.current = setInterval(() => { + if (loadingProgress <= 0) { + return handleNext(); + } + setLoadingProgress((prev) => prev - 1); + }, 120); + return () => { + if (intervalRef.current) clearInterval(intervalRef.current); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [loadingProgress]); + + const handleNext = () => { + navigate(`${routes.client.questionnaire()}/profile/relationshipProblem`); + }; + + return ( +
+
+ + We've helped {randomValue[0]},{`${randomValue[1]}`.padStart(3, "0")}{" "} + other {gender}s with their Sun in{" "} + <span className={styles.yellow}> + {getZodiacSignByDate(birthdate)} + </span>{" "} + to increase relationship satisfaction and we can't wait to help you + too! + +

*as of 24 February 2023

+
+ {/* */} +
+ +
+

Connecting database...

+
+ ); +} + +export default LoadingInRelationshipPage; diff --git a/src/components/pages/LoadingInRelationship/styles.module.css b/src/components/pages/LoadingInRelationship/styles.module.css new file mode 100644 index 0000000..b528bd3 --- /dev/null +++ b/src/components/pages/LoadingInRelationship/styles.module.css @@ -0,0 +1,61 @@ +.page { + position: relative; + height: fit-content; + min-height: 100vh; + display: flex; + justify-content: start; + align-items: center; + flex-direction: column; + gap: 40px; + background: linear-gradient( + 165.54deg, + rgb(20, 19, 51) -33.39%, + rgb(32, 34, 97) 15.89%, + rgb(84, 60, 151) 55.84%, + rgb(105, 57, 162) 74.96% + ); + color: #fff; + padding-top: 64px; +} + +.title { + font-size: 18px; + line-height: 28px; + max-width: 322px; +} + +.yellow { + color: #f2c94c; +} + +.text { + font-size: 14px; + text-align: center; + line-height: 140%; + max-width: 322px; +} + +.buttons-container { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + gap: 10px; +} + +.button { + width: 160px; + min-width: fit-content; + height: 48px; + min-height: fit-content; + border: solid 1px #fff; + border-radius: 16px; + font-size: 18px; + font-weight: 500; + background-color: transparent; +} + +.next-button { + background-color: #fff; + color: #6a3aa2; +} diff --git a/src/components/pages/NoBirthtime/index.tsx b/src/components/pages/NoBirthtime/index.tsx new file mode 100644 index 0000000..a6ebdfa --- /dev/null +++ b/src/components/pages/NoBirthtime/index.tsx @@ -0,0 +1,62 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.css"; +import MainButton from "@/components/MainButton"; +import { useNavigate, useSearchParams } from "react-router-dom"; +import routes from "@/routes"; + +function NoBirthtimePage() { + const [searchParams] = useSearchParams(); + const affiliation = searchParams.get("affiliation") || "self"; + const navigate = useNavigate(); + + const handleNext = () => { + if (affiliation === "partner") { + navigate( + `${routes.client.questionnaire()}/partnerProfile/partnerBirthPlace` + ); + } + if (affiliation === "self") { + navigate(`${routes.client.questionnaire()}/profile/birthPlace`); + } + }; + + const handleBack = () => { + navigate(-1); + }; + + return ( +
+ The clock +
+ + No problem! You can still find plenty of great insights without + knowing + {affiliation === "self" && " your exact birth time."} + {affiliation === "partner" && + " the exact birth time of your partner."} + +

+ Tip: If you find out later, you can adjust this in your + {affiliation === "self" && " profile settings."} + {affiliation === "partner" && " partner’s profile."} +

+
+
+ + Back + + + Next + +
+
+ ); +} + +export default NoBirthtimePage; diff --git a/src/components/pages/NoBirthtime/styles.module.css b/src/components/pages/NoBirthtime/styles.module.css new file mode 100644 index 0000000..00eb4cc --- /dev/null +++ b/src/components/pages/NoBirthtime/styles.module.css @@ -0,0 +1,57 @@ +.page { + position: relative; + height: fit-content; + min-height: 100vh; + display: flex; + justify-content: start; + align-items: center; + flex-direction: column; + gap: 40px; + background: linear-gradient( + 165.54deg, + rgb(20, 19, 51) -33.39%, + rgb(32, 34, 97) 15.89%, + rgb(84, 60, 151) 55.84%, + rgb(105, 57, 162) 74.96% + ); + color: #fff; + padding-top: 64px; +} + +.title { + font-size: 18px; + line-height: 28px; + max-width: 322px; +} + +.text { + font-size: 14px; + text-align: center; + line-height: 140%; + max-width: 322px; +} + +.buttons-container { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + gap: 10px; +} + +.button { + width: 160px; + min-width: fit-content; + height: 48px; + min-height: fit-content; + border: solid 1px #fff; + border-radius: 16px; + font-size: 18px; + font-weight: 500; + background-color: transparent; +} + +.next-button { + background-color: #fff; + color: #6a3aa2; +} diff --git a/src/components/pages/Questionnaire/CustomAnswers/BirthPlace/index.tsx b/src/components/pages/Questionnaire/CustomAnswers/BirthPlace/index.tsx new file mode 100644 index 0000000..4c4218c --- /dev/null +++ b/src/components/pages/Questionnaire/CustomAnswers/BirthPlace/index.tsx @@ -0,0 +1,62 @@ +import styles from "./styles.module.css"; +import { useDispatch, useSelector } from "react-redux"; +import { actions, selectors } from "@/store"; +import MainButton from "@/components/MainButton"; +import { useTranslation } from "react-i18next"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import PlacePicker from "@/components/PlacePicker"; + +interface IBirthPlaceCustomAnswerProps { + affiliation?: "self" | "partner"; +} + +function BirthPlaceCustomAnswer({ + affiliation = "self", +}: IBirthPlaceCustomAnswerProps) { + const { t } = useTranslation(); + const navigate = useNavigate(); + const dispatch = useDispatch(); + const questionnaire = useSelector(selectors.selectQuestionnaire); + const birthPlace = + affiliation === "self" + ? questionnaire.birthPlace + : questionnaire.partnerBirthPlace; + + const handleChange = (birthPlace: string) => { + if (affiliation === "partner") { + dispatch(actions.questionnaire.update({ partnerBirthPlace: birthPlace })); + } + if (affiliation === "self") { + dispatch(actions.questionnaire.update({ birthPlace })); + } + }; + + const handleNext = () => { + if (affiliation === "self") { + navigate(routes.client.loadingInRelationship()); + } + if (affiliation === "partner") { + navigate(routes.client.relationshipAlmostThere()); + } + }; + + return ( +
+ + + {!!birthPlace.length && ( + + {t("next")} + + )} +
+ ); +} + +export default BirthPlaceCustomAnswer; diff --git a/src/components/pages/Questionnaire/CustomAnswers/BirthPlace/styles.module.css b/src/components/pages/Questionnaire/CustomAnswers/BirthPlace/styles.module.css new file mode 100644 index 0000000..17ce781 --- /dev/null +++ b/src/components/pages/Questionnaire/CustomAnswers/BirthPlace/styles.module.css @@ -0,0 +1,20 @@ +.container { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; +} + +.button { + background: linear-gradient( + 165.54deg, + rgb(20, 19, 51) -33.39%, + rgb(32, 34, 97) 15.89%, + rgb(84, 60, 151) 55.84%, + rgb(105, 57, 162) 74.96% + ); + min-height: 0; + height: 49px; + border-radius: 12px; + margin-top: 26px; +} diff --git a/src/components/pages/Questionnaire/CustomAnswers/Birthdate/index.tsx b/src/components/pages/Questionnaire/CustomAnswers/Birthdate/index.tsx new file mode 100644 index 0000000..d1b7a69 --- /dev/null +++ b/src/components/pages/Questionnaire/CustomAnswers/Birthdate/index.tsx @@ -0,0 +1,69 @@ +import { DatePicker } from "@/components/DateTimePicker"; +import styles from "./styles.module.css"; +import { useDispatch, useSelector } from "react-redux"; +import { actions, selectors } from "@/store"; +import { useState } from "react"; +import MainButton from "@/components/MainButton"; +import { useTranslation } from "react-i18next"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; + +interface IBirthdateCustomAnswerProps { + affiliation?: "self" | "partner"; +} + +function BirthdateCustomAnswer({ + affiliation = "self", +}: IBirthdateCustomAnswerProps) { + const { t } = useTranslation(); + const navigate = useNavigate(); + const dispatch = useDispatch(); + const selfBirthdate = useSelector(selectors.selectBirthdate); + const questionnaire = useSelector(selectors.selectQuestionnaire); + const birthdateFromStore = + affiliation === "self" ? selfBirthdate : questionnaire.partnerBirthdate; + const [birthdate, setBirthdate] = useState(birthdateFromStore); + const [isDisabled, setIsDisabled] = useState(true); + const handleValid = (_birthdate: string) => { + if (affiliation === "self") { + dispatch(actions.form.addDate(birthdate)); + } + setBirthdate(_birthdate); + setIsDisabled(_birthdate === ""); + }; + + const handleNext = () => { + if (affiliation === "self") { + dispatch(actions.questionnaire.update({ birthdate })); + navigate(`${routes.client.questionnaire()}/profile/isBirthTime`); + } + if (affiliation === "partner") { + dispatch(actions.questionnaire.update({ partnerBirthdate: birthdate })); + navigate( + `${routes.client.questionnaire()}/partnerProfile/partnerIsBirthTime` + ); + } + }; + + return ( +
+ setIsDisabled(true)} + inputClassName="date-picker-input" + /> + + + {t("next")} + +
+ ); +} + +export default BirthdateCustomAnswer; diff --git a/src/components/pages/Questionnaire/CustomAnswers/Birthdate/styles.module.css b/src/components/pages/Questionnaire/CustomAnswers/Birthdate/styles.module.css new file mode 100644 index 0000000..4496322 --- /dev/null +++ b/src/components/pages/Questionnaire/CustomAnswers/Birthdate/styles.module.css @@ -0,0 +1,19 @@ +.container { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; +} + +.button { + background: linear-gradient( + 165.54deg, + rgb(20, 19, 51) -33.39%, + rgb(32, 34, 97) 15.89%, + rgb(84, 60, 151) 55.84%, + rgb(105, 57, 162) 74.96% + ); + min-height: 0; + height: 49px; + border-radius: 12px; +} diff --git a/src/components/pages/Questionnaire/CustomAnswers/Birthtime/index.tsx b/src/components/pages/Questionnaire/CustomAnswers/Birthtime/index.tsx new file mode 100644 index 0000000..aabd810 --- /dev/null +++ b/src/components/pages/Questionnaire/CustomAnswers/Birthtime/index.tsx @@ -0,0 +1,58 @@ +import { TimePicker } from "@/components/DateTimePicker"; +import styles from "./styles.module.css"; +import { useDispatch, useSelector } from "react-redux"; +import { actions, selectors } from "@/store"; +import MainButton from "@/components/MainButton"; +import { useTranslation } from "react-i18next"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import { useState } from "react"; + +interface IBirthtimeCustomAnswerProps { + affiliation?: "self" | "partner"; +} + +function BirthtimeCustomAnswer({ + affiliation = "self", +}: IBirthtimeCustomAnswerProps) { + const { t } = useTranslation(); + const navigate = useNavigate(); + const dispatch = useDispatch(); + const selfBirthtime = useSelector(selectors.selectBirthtime); + const questionnaire = useSelector(selectors.selectQuestionnaire); + const birthtimeFromStore = + affiliation === "self" ? selfBirthtime : questionnaire.partnerBirthtime; + const [birthtime, setBirthtime] = useState(birthtimeFromStore); + + const handleChange = (_birthtime: string) => { + setBirthtime(_birthtime); + if (affiliation === "self") { + dispatch(actions.form.addTime(_birthtime)); + } + }; + + const handleNext = () => { + if (affiliation === "self") { + dispatch(actions.questionnaire.update({ birthtime })); + navigate(`${routes.client.questionnaire()}/profile/birthPlace`); + } + if (affiliation === "partner") { + dispatch(actions.questionnaire.update({ partnerBirthtime: birthtime })); + navigate( + `${routes.client.questionnaire()}/partnerProfile/partnerBirthPlace` + ); + } + }; + + return ( +
+ + + + {t("next")} + +
+ ); +} + +export default BirthtimeCustomAnswer; diff --git a/src/components/pages/Questionnaire/CustomAnswers/Birthtime/styles.module.css b/src/components/pages/Questionnaire/CustomAnswers/Birthtime/styles.module.css new file mode 100644 index 0000000..17ce781 --- /dev/null +++ b/src/components/pages/Questionnaire/CustomAnswers/Birthtime/styles.module.css @@ -0,0 +1,20 @@ +.container { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; +} + +.button { + background: linear-gradient( + 165.54deg, + rgb(20, 19, 51) -33.39%, + rgb(32, 34, 97) 15.89%, + rgb(84, 60, 151) 55.84%, + rgb(105, 57, 162) 74.96% + ); + min-height: 0; + height: 49px; + border-radius: 12px; + margin-top: 26px; +} diff --git a/src/components/pages/Questionnaire/index.tsx b/src/components/pages/Questionnaire/index.tsx new file mode 100644 index 0000000..d5d2038 --- /dev/null +++ b/src/components/pages/Questionnaire/index.tsx @@ -0,0 +1,182 @@ +import { useNavigate, useParams } from "react-router-dom"; +import styles from "./styles.module.css"; +import Stepper from "@/components/Stepper"; +import { useEffect, useState } from "react"; +import { IAnswer, IQuestion, stepsQuestionary } from "@/data"; +import Title from "@/components/Title"; +import Answer from "@/components/Answer"; +import routes from "@/routes"; +import { useDispatch, useSelector } from "react-redux"; +import { actions } from "@/store"; +import { IQuestionnaire, selectQuestionnaire } from "@/store/questionnaire"; + +function QuestionnairePage(): JSX.Element { + const { question, stepId } = useParams(); + const navigate = useNavigate(); + const dispatch = useDispatch(); + const [currentStep, setCurrentStep] = useState(); + const [currentQuestion, setCurrentQuestion] = useState(); + const steps = stepsQuestionary.filter((item) => !!item.questions.length); + const questionsAnswers = useSelector(selectQuestionnaire); + + useEffect(() => { + const currentStepIndex = steps.findIndex((item) => item.id === stepId); + if (currentStepIndex === -1) return navigate(routes.client.notFound()); + setCurrentStep(currentStepIndex || 0); + const _currentQuestion = steps[currentStepIndex].questions.find( + (item) => item.id === question + ); + if (!_currentQuestion) return navigate(routes.client.gender()); + setCurrentQuestion(_currentQuestion); + }, [navigate, question, stepId, steps]); + + // useEffect(() => { + // if (!question) { + // navigate(routes.client.gender()); + // } + + // console.log(question); + + // const currentQuestionIndex = questions.findIndex( + // (item) => item.id === question + // ); + + // const _currentQuestion = questions[currentQuestionIndex]; + + // setCurrentQuestion(_currentQuestion); + // console.log(_currentQuestion); + + // if (!_currentQuestion) { + // navigate(routes.client.gender()); + // } + // }, [currentQuestion, navigate, question]); + + const answerClickHandler = (answer: IAnswer) => { + if (!stepId || !question) return; + const questionIndex = getIndexOfQuestion(question); + if (questionIndex === -1) return; + const currentStepIndex = steps.findIndex((item) => item.id === stepId); + + const questionsLength = steps[currentStepIndex].questions.length; + + const currentQuestion = steps[currentStepIndex].questions[questionIndex]; + + dispatch( + actions.questionnaire.update({ + [currentQuestion.id]: answer.id, + }) + ); + + if (answer.navigateToUrl?.length) { + return navigate(answer.navigateToUrl); + } + + if (currentQuestion.navigateToUrl?.length) { + return navigate(currentQuestion.navigateToUrl); + } + + if ( + currentStepIndex >= steps.length - 1 && + questionIndex >= questionsLength - 1 + ) { + return navigate(routes.client.priceList()); + } + + if (questionIndex < questionsLength - 1) { + return navigate( + `${routes.client.questionnaire()}/${steps[currentStepIndex].id}/${ + steps[currentStepIndex].questions[questionIndex + 1].id + }` + ); + } + + if ( + currentStepIndex < steps.length - 1 && + questionIndex >= questionsLength - 1 + ) { + return navigate( + `${routes.client.questionnaire()}/${steps[currentStepIndex + 1].id}/${ + steps[currentStepIndex + 1].questions[0].id + }` + ); + } + }; + + const getIndexOfQuestion = (questionId: string) => { + const currentStepIndex = steps.findIndex((item) => item.id === stepId); + if (currentStepIndex === -1) return -1; + return steps[currentStepIndex].questions.findIndex( + (item) => item.id === questionId + ); + }; + + const getPreviousQuestion = () => { + if (!currentQuestion) return null; + const currentQuestionIndex = getIndexOfQuestion(currentQuestion.id); + const currentStepIndex = steps.findIndex((item) => item.id === stepId); + if (currentQuestionIndex === -1 || currentStepIndex === -1) return null; + if (currentStepIndex === 0 && currentQuestionIndex === 0) return null; + if (currentStepIndex > 0 && currentQuestionIndex === 0) + return steps[currentStepIndex - 1].questions[ + steps[currentStepIndex - 1].questions.length - 1 + ]; + return steps[currentStepIndex].questions[currentQuestionIndex - 1]; + }; + + const isShowAnswer = (answer: IAnswer) => { + const previousQuestion = getPreviousQuestion(); + if (!previousQuestion) return true; + const previousAnswer = + questionsAnswers[previousQuestion.id as keyof IQuestionnaire]; + if (!previousAnswer) return true; + if (!answer.conditionalValues) return true; + return answer.conditionalValues?.includes(previousAnswer); + }; + + return ( +
+ {currentQuestion && (!!currentStep || currentStep === 0) && ( + <> + + + {steps[currentStep].label} + + + {currentQuestion.question} + + {!!currentQuestion.description && ( +

{currentQuestion.description}

+ )} +
+ {!currentQuestion.answersElement && + currentQuestion.answers && + currentQuestion.answers.map((answer) => { + if (!isShowAnswer(answer)) return null; + return ( + { + answerClickHandler(answer); + }} + /> + ); + })} + {!!currentQuestion.answersElement && currentQuestion.answersElement} +
+ + )} +
+ ); +} + +export default QuestionnairePage; diff --git a/src/components/pages/Questionnaire/styles.module.css b/src/components/pages/Questionnaire/styles.module.css new file mode 100644 index 0000000..b323dfa --- /dev/null +++ b/src/components/pages/Questionnaire/styles.module.css @@ -0,0 +1,52 @@ +.page { + position: relative; + height: fit-content; + min-height: calc(100vh - 50px); + display: flex; + justify-content: start; + align-items: center; + flex-direction: column; + background-position-y: bottom; + background-position-x: center; + background-size: cover; + background-repeat: no-repeat; + color: #fff; +} + +.current-step { + font-weight: 600; + font-size: 14px; + text-align: center; + color: rgb(142, 140, 240); + margin-top: 5px; + margin-bottom: 20px; + position: relative; +} + +.title { + font-size: 24px; + line-height: 28px; + align-self: flex-start; + margin-bottom: 30px; + text-align: left; + color: rgb(51, 51, 51); +} + +.answers-container { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; +} + +.description { + font-size: 14px; + line-height: 24px; + font-weight: normal; + margin-top: -20px; + margin-bottom: 30px; + align-self: flex-start; + text-align: left; + color: rgb(79, 79, 79); +} diff --git a/src/components/pages/RelationshipAlmostThere/index.tsx b/src/components/pages/RelationshipAlmostThere/index.tsx new file mode 100644 index 0000000..b07bfa7 --- /dev/null +++ b/src/components/pages/RelationshipAlmostThere/index.tsx @@ -0,0 +1,53 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.css"; +import MainButton from "@/components/MainButton"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; + +function RelationshipAlmostTherePage() { + const navigate = useNavigate(); + + const handleBack = () => { + navigate(-1); + }; + + const handleNext = () => { + navigate(`${routes.client.questionnaire()}/relationships/issueTogether`); + }; + + return ( +
+ The magnifier +
+ + Almost there! Now let's begin tailoring your plan by understanding + your{" "} + <span className={styles.purple}> + Relationship & Personality Patterns + </span> + . + +

+ Please take your time when answering. Each response is used to craft + the guidance plan for you and your partner. +

+
+
+ + Back + + + Next + +
+
+ ); +} + +export default RelationshipAlmostTherePage; diff --git a/src/components/pages/RelationshipAlmostThere/styles.module.css b/src/components/pages/RelationshipAlmostThere/styles.module.css new file mode 100644 index 0000000..44ab5d6 --- /dev/null +++ b/src/components/pages/RelationshipAlmostThere/styles.module.css @@ -0,0 +1,58 @@ +.page { + position: relative; + height: fit-content; + min-height: 100vh; + display: flex; + justify-content: start; + align-items: center; + flex-direction: column; + gap: 40px; + background: url("/heart_of_couple.webp"); + background-position: center; + background-size: cover; + background-repeat: no-repeat; + color: #fff; + padding-top: 64px; +} + +.title { + font-size: 18px; + line-height: 28px; + max-width: 322px; +} + +.purple { + color: #bb6cd9; +} + +.text { + font-size: 14px; + text-align: center; + line-height: 140%; + max-width: 322px; +} + +.buttons-container { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + gap: 10px; +} + +.button { + width: 160px; + min-width: fit-content; + height: 48px; + min-height: fit-content; + border: solid 1px #fff; + border-radius: 16px; + font-size: 18px; + font-weight: 500; + background-color: transparent; +} + +.next-button { + background-color: #fff; + color: #6a3aa2; +} diff --git a/src/components/pages/WorksForUs/index.tsx b/src/components/pages/WorksForUs/index.tsx new file mode 100644 index 0000000..397f040 --- /dev/null +++ b/src/components/pages/WorksForUs/index.tsx @@ -0,0 +1,68 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.css"; +import MainButton from "@/components/MainButton"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import { useSelector } from "react-redux"; +import { selectors } from "@/store"; + +function WorksForUsPage() { + const navigate = useNavigate(); + const { relationshipProblem } = useSelector(selectors.selectQuestionnaire); + + const handleBack = () => { + navigate(-1); + }; + + const handleNext = () => { + navigate(`${routes.client.questionnaire()}/partnerProfile/partnerGender`); + }; + + return ( +
+ The starry key +
+ {relationshipProblem === "very_unhappy" && ( + + We’ve got you covered! We’ll start with small, personalized insights + into you and your partner’s personality traits. + + )} + {relationshipProblem === "unhappy" && ( + + You’re probably doing better than you think! We’ll help you identify + how to improve and stick with it. + + )} + {relationshipProblem === "happy" && ( + + Wonderful! + <br /> Let's find out what's working (and what isn’t) and go from + there. + + )} +

+ Now, we need some information about{" "} + Your Partner’s Profile to create + the astrological synastry blueprint between you and your partner. +

+
+
+ + Back + + + Next + +
+
+ ); +} + +export default WorksForUsPage; diff --git a/src/components/pages/WorksForUs/styles.module.css b/src/components/pages/WorksForUs/styles.module.css new file mode 100644 index 0000000..2b294a6 --- /dev/null +++ b/src/components/pages/WorksForUs/styles.module.css @@ -0,0 +1,59 @@ +.page { + position: relative; + height: fit-content; + min-height: 100vh; + display: flex; + justify-content: start; + align-items: center; + flex-direction: column; + gap: 40px; + background: url("/couple_holding_hands_1.webp"); + background-position-y: bottom; + background-position-x: center; + background-size: cover; + color: #fff; + padding-top: 64px; +} + +.title { + font-size: 16px; + line-height: 28px; + max-width: 322px; +} + +.text { + font-size: 14px; + text-align: center; + line-height: 140%; + max-width: 322px; +} + +.blue { + font-weight: bolder; + color: #56ccf2; +} + +.buttons-container { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + gap: 10px; +} + +.button { + width: 160px; + min-width: fit-content; + height: 48px; + min-height: fit-content; + border: solid 1px #fff; + border-radius: 16px; + font-size: 18px; + font-weight: 500; + background-color: transparent; +} + +.next-button { + background-color: #fff; + color: #6a3aa2; +} diff --git a/src/data.ts b/src/data.ts deleted file mode 100644 index 63d6478..0000000 --- a/src/data.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { IPredictionMoon } from "./components/PredictionMoonsSlider"; - -export const predictionMoonsPeriods: IPredictionMoon[] = [ - { - period: "today", - }, - { - period: "week", - }, - { - period: "month", - }, - { - period: "year", - }, -]; diff --git a/src/data.tsx b/src/data.tsx new file mode 100644 index 0000000..8dd5d24 --- /dev/null +++ b/src/data.tsx @@ -0,0 +1,656 @@ +import { IPredictionMoon } from "./components/PredictionMoonsSlider"; +import routes from "./routes"; +import BirthdateCustomAnswer from "./components/pages/Questionnaire/CustomAnswers/Birthdate"; +import BirthtimeCustomAnswer from "./components/pages/Questionnaire/CustomAnswers/Birthtime"; +import BirthPlaceCustomAnswer from "./components/pages/Questionnaire/CustomAnswers/BirthPlace"; + +export const predictionMoonsPeriods: IPredictionMoon[] = [ + { + period: "today", + }, + { + period: "week", + }, + { + period: "month", + }, + { + period: "year", + }, +]; + +export interface Gender { + id: string; + name: string; + img: string; + colorAssociation: string | string[]; +} + +export const genders: Gender[] = [ + { + id: "male", + name: "Male", + img: "/male.webp", + colorAssociation: "#454895", + }, + { + id: "female", + name: "Female", + img: "/female.webp", + colorAssociation: ["#642b73", "#c6426e"], + }, +]; + +export interface IStep { + id: string; + label: string; + color: string; + questions: IQuestion[]; +} + +export interface IQuestion { + id: string; + question: string; + answers?: IAnswer[]; + answersElement?: JSX.Element; + navigateToUrl?: string; + description?: string; + backgroundImage?: string; +} + +export interface IAnswer { + id: string; + answer: string; + icon: string; + conditionalValues?: string[]; + navigateToUrl?: string; +} + +export const stepsQuestionary: IStep[] = [ + { + id: "profile", + label: "Your profile", + color: "#8e8cf0", + questions: [ + { + id: "flowChoice", + question: + "So we can get to know you better, tell us about your relationship status.", + answers: [ + { + id: "single", + answer: "Single", + icon: "/heart.png", + }, + { + id: "relationship", + answer: "In a relationship", + icon: "/two-hearts.png", + }, + { + id: "married", + answer: "Married", + icon: "/ring.png", + }, + { + id: "complicated", + answer: "Complicated", + icon: "/broken_heart.png", + }, + { + id: "other", + answer: "Unsure / Other", + icon: "/thinking_face.png", + }, + ], + }, + { + id: "goal", + question: "What is your goal?", + navigateToUrl: routes.client.goalSetup(), + answers: [ + { + id: "perfect_partner", + answer: "Find my perfect partner", + icon: "/kiss.png", + conditionalValues: ["single", "complicated", "other"], + }, + { + id: "get_married", + answer: "To get married", + icon: "/ring.png", + conditionalValues: ["single", "complicated", "other"], + }, + { + id: "understand_myself", + answer: "Understand myself better", + icon: "/thinking_face.png", + conditionalValues: ["single", "complicated", "other"], + }, + { + id: "achieve_happiness", + answer: "Achieve happiness", + icon: "/star_struck.png", + conditionalValues: ["single", "complicated", "other"], + }, + { + id: "personal_growth", + answer: "Personal growth", + icon: "/sparkles.png", + conditionalValues: ["single", "complicated", "other"], + }, + { + id: "increase_realtionship", + answer: "Increase relationship satisfaction", + icon: "/two-hearts.png", + conditionalValues: ["relationship", "married"], + }, + { + id: "fix_realtionship", + answer: "Fix relationship problems", + icon: "/broken_heart.png", + conditionalValues: ["relationship", "married"], + }, + { + id: "build_strong", + answer: "Build a strong marriage", + icon: "/kiss.png", + conditionalValues: ["relationship", "married"], + }, + { + id: "check_compatibility", + answer: "Check compatibility", + icon: "/woman-heart-man.png", + conditionalValues: [ + "single", + "relationship", + "married", + "complicated", + "other", + ], + }, + { + id: "all_above", + answer: "All above", + icon: "/hands_heart.png", + conditionalValues: [ + "single", + "relationship", + "married", + "complicated", + "other", + ], + }, + ], + }, + { + id: "parent", + question: "Are you a parent?", + answers: [ + { + id: "yes", + answer: "Yes", + icon: "/check_mark_button.png", + }, + { + id: "no", + answer: "No", + icon: "/cross_mark.png", + }, + ], + }, + { + id: "astrologyKnowledge", + question: "What’s your level of knowledge in astrology?", + description: + "So we can tailor the insights to suit your knowledge level", + navigateToUrl: routes.client.hyperPersonalizedAstrology(), + answers: [ + { + id: "expert", + answer: "An expert", + icon: "/man_student.png", + }, + { + id: "curious", + answer: "Curious", + icon: "/face_with_monocle.png", + }, + { + id: "beginner", + answer: "A beginner", + icon: "/slightly_smiling_face.png", + }, + ], + }, + { + id: "birthdate", + question: "What's your date of birth?", + answersElement: , + backgroundImage: "/date_of_birth_zodiac_signs.webp", + }, + { + id: "isBirthTime", + question: "Do you know your time of birth?", + answers: [ + { + id: "yes", + answer: "Yes", + icon: "/check_mark_button.png", + }, + { + id: "no", + answer: "No", + icon: "/cross_mark.png", + navigateToUrl: routes.client.noTime(), + }, + ], + }, + { + id: "birthtime", + question: "What time were you born?", + description: + "We use NASA data to identify the exact position of the planets in the sky at the time of your birth.", + answersElement: , + backgroundImage: "/small_alarm_clock.webp", + }, + { + id: "birthPlace", + question: "Where were you born?", + description: + "This determines the time zone at the place of your birth.", + answersElement: , + backgroundImage: "/bunch_of_cards.webp", + }, + // TODO: add more questions + { + id: "relationshipProblem", + question: + "Male in their 20s who have children need a slightly different approach to improve their relationship. Which statement best describes you?", + navigateToUrl: routes.client.worksForUs(), + answers: [ + { + id: "very_unhappy", + answer: + "I’m very unhappy with how things are going in my relationship", + icon: "/slightly_frowning_face.png", + }, + { + id: "unhappy", + answer: + "I’m unhappy with parts of my relationship, but some things are working well", + icon: "/neutral_face.png", + }, + { + id: "happy", + answer: "I’m generally happy in my relationship", + icon: "/slightly_smiling_face.png", + }, + ], + }, + ], + }, + { + id: "partnerProfile", + label: "Your partner`s profile", + color: "#56ccf2", + questions: [ + { + id: "partnerGender", + question: "What’s your partner’s gender?", + answers: [ + { + id: "male", + answer: "Male", + icon: "/man.png", + }, + { + id: "female", + answer: "Female", + icon: "/woman.png", + }, + ], + }, + { + id: "partnerBirthdate", + question: "What’s your partner’s date of birth?", + answersElement: , + backgroundImage: "/date_of_birth_zodiac_signs.webp", + }, + { + id: "partnerIsBirthTime", + question: "Do you know your partner’s time of birth?", + backgroundImage: "/wall_clock.webp", + answers: [ + { + id: "yes", + answer: "Yes", + icon: "/check_mark_button.png", + }, + { + id: "no", + answer: "No", + icon: "/cross_mark.png", + navigateToUrl: `${routes.client.noTime()}?affiliation=partner`, + }, + ], + }, + { + id: "partnerBirthtime", + question: "At what time was your partner born?", + description: + "We use NASA data to identify the exactposition of the planets in the sky at the time of your partner's birth.", + answersElement: , + backgroundImage: "/small_alarm_clock.webp", + }, + { + id: "partnerBirthPlace", + question: "Where was your partner born?", + description: + "If you don’t know the exact place of birth just type in the country of birth.", + answersElement: , + backgroundImage: "/bunch_of_cards.webp", + }, + ], + }, + { + id: "relationships", + label: "Relationship & Personality Patterns", + color: "#bb6bd9", + questions: [ + { + id: "issueTogether", + question: "Do you agree with the statement below?", + description: "“My partner and I can talk about any issue together“", + answers: [ + { + id: "strongly_agree", + answer: "Strongly agree", + icon: "/raising_hands.png", + }, + { + id: "agree", + answer: "Agree", + icon: "/thumbs_up.png", + }, + { + id: "neutral", + answer: "Neutral", + icon: "/thumbs_middle.png", + }, + { + id: "disagree", + answer: "Disagree", + icon: "/thumbs_more_down.png", + }, + { + id: "strongly_disagree", + answer: "Strongly disagree", + icon: "/thumbs_down.png", + }, + ], + }, + // TODO: add more questions + { + id: "partnerPriority", + question: "Do you agree with the statement below?", + description: + "“My partner and I make sex a priority in our relationship”", + answers: [ + { + id: "strongly_agree", + answer: "Strongly agree", + icon: "/raising_hands.png", + }, + { + id: "agree", + answer: "Agree", + icon: "/thumbs_up.png", + }, + { + id: "neutral", + answer: "Neutral", + icon: "/thumbs_middle.png", + }, + { + id: "disagree", + answer: "Disagree", + icon: "/thumbs_more_down.png", + }, + { + id: "strongly_disagree", + answer: "Strongly disagree", + icon: "/thumbs_down.png", + }, + ], + }, + { + id: "satisfied", + question: + "Are you satisfied with how you and your partner communicate?", + answers: [ + { + id: "yes", + answer: "Yes", + icon: "/check_mark_button.png", + }, + { + id: "no", + answer: "No", + icon: "/cross_mark.png", + }, + ], + }, + // TODO: add more questions + { + id: "emotionalConnection", + question: "Do you agree with the statement below?", + description: + "“Strengthening our emotional connection is a priority for both my partner and me”", + answers: [ + { + id: "strongly_agree", + answer: "Strongly agree", + icon: "/raising_hands.png", + }, + { + id: "agree", + answer: "Agree", + icon: "/thumbs_up.png", + }, + { + id: "neutral", + answer: "Neutral", + icon: "/thumbs_middle.png", + }, + { + id: "disagree", + answer: "Disagree", + icon: "/thumbs_more_down.png", + }, + { + id: "strongly_disagree", + answer: "Strongly disagree", + icon: "/thumbs_down.png", + }, + ], + }, + // TODO: add more questions + { + id: "bigPicture", + question: + "Would you describe your partner as a detail-oriented or big-picture person?", + answers: [ + { + id: "detailed", + answer: "Detail-oriented", + icon: "/microscope.png", + }, + { + id: "big_picture", + answer: "Big-picture", + icon: "/mountain.png", + }, + { + id: "both", + answer: "A bit of both", + icon: "/paperclip.png", + }, + ], + }, + { + id: "introvertOrExtravert", + question: "Is your partner an introvert or extrovert?", + answers: [ + { + id: "introvert", + answer: "Introvert", + icon: "/blue_book.png", + }, + { + id: "extravert", + answer: "Extravert", + icon: "/party_popper.png", + }, + { + id: "both", + answer: "A bit of both", + icon: "/scales.png", + }, + ], + }, + { + id: "irritated", + question: "Does your partner get angry or irritated easily?", + answers: [ + { + id: "yes", + answer: "Yes", + icon: "/face_with_raised_eyebrow.png", + }, + { + id: "sometimes", + answer: "Sometimes", + icon: "/thinking_face.png", + }, + { + id: "rarely", + answer: "Rarely", + icon: "/neutral_face.png", + }, + { + id: "not_all", + answer: "Not at all", + icon: "/slightly_smiling_face.png", + }, + ], + }, + { + id: "conflict", + question: + "Are you satisfied with the way you and your partner deal with conflict?", + answers: [ + { + id: "yes", + answer: "Yes, I prefer to be honest and direct", + icon: "/loudspeaker.png", + }, + { + id: "depends", + answer: "Depends on the situation and the person", + icon: "/scales.png", + }, + { + id: "no", + answer: "No, I don’t want to get hurt or hurt another person", + icon: "/shield.png", + }, + { + id: "no2", + answer: "No, it makes me nervous", + icon: "/fearful_face.png", + }, + ], + }, + { + id: "aboutGoals", + question: "When you think about your relationship goals, you feel...?", + answers: [ + { + id: "optimistic", + answer: "Optimistic! They are totally doable, with some guidance.", + icon: "/slightly_smiling_face.png", + }, + { + id: "cautious", + answer: "Cautious. I’ve struggled before, but I’m hopeful.", + icon: "/unamused.png", + }, + { + id: "feeling", + answer: "I’m feeling a little anxious, honestly.", + icon: "/anxious_face_with_sweat.png", + }, + { + id: "not_shure", + answer: "Not sure / Don’t know", + icon: "/thinking_face.png", + }, + ], + }, + { + id: "appreciated", + question: "Do you agree with the statement below?", + description: "“My partner makes me feel really appreciated.”", + answers: [ + { + id: "strongly_agree", + answer: "Strongly agree", + icon: "/raising_hands.png", + }, + { + id: "agree", + answer: "Agree", + icon: "/thumbs_up.png", + }, + { + id: "neutral", + answer: "Neutral", + icon: "/thumbs_middle.png", + }, + { + id: "disagree", + answer: "Disagree", + icon: "/thumbs_more_down.png", + }, + { + id: "strongly_disagree", + answer: "Strongly disagree", + icon: "/thumbs_down.png", + }, + ], + }, + { + id: "decisions", + question: "Do you make decisions with your head or your heart?", + answers: [ + { + id: "heart", + answer: "Heart", + icon: "/red-heart.png", + }, + { + id: "head", + answer: "Head", + icon: "/brain.png", + }, + { + id: "both", + answer: "Both", + icon: "/paperclip.png", + }, + ], + }, + ], + }, +]; diff --git a/src/routes.ts b/src/routes.ts index 683d4b8..1a98043 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -41,6 +41,19 @@ const routes = { moonPhaseTracker: () => [host, "moon-phase-tracker"].join("/"), energyVampirismResult: () => [host, "energy-vampirism"].join("/"), nameHoroscopeResult: () => [host, "name-horoscope"].join("/"), + + // test routes + gender: () => [host, "gender"].join("/"), + questionnaire: () => [host, "questionnaire"].join("/"), + goalSetup: () => [host, "goal-setup"].join("/"), + hyperPersonalizedAstrology: () => + [host, "hyper-personalized-astrology"].join("/"), + noTime: () => [host, "no-time"].join("/"), + loadingInRelationship: () => [host, "loading-in-relationship"].join("/"), + worksForUs: () => [host, "works-for-us"].join("/"), + relationshipAlmostThere: () => + [host, "relationship-almost-there"].join("/"), + notFound: () => [host, "404"].join("/"), }, server: { appleAuth: (origin: string) => @@ -162,9 +175,23 @@ export const withoutFooterRoutes = [ routes.client.moonPhaseTracker(), routes.client.energyVampirismResult(), routes.client.nameHoroscopeResult(), + routes.client.goalSetup(), + routes.client.hyperPersonalizedAstrology(), + routes.client.noTime(), + routes.client.loadingInRelationship(), + routes.client.worksForUs(), + routes.client.relationshipAlmostThere(), ]; -export const hasNoFooter = (path: string) => - !withoutFooterRoutes.includes(path); + +export const withoutFooterPartOfRoutes = [routes.client.questionnaire()]; + +export const hasNoFooter = (path: string) => { + const targetRoute = withoutFooterPartOfRoutes.findIndex((route) => + path.includes(route) + ); + + return !withoutFooterRoutes.includes(path) && targetRoute === -1; +}; export const withNavbarFooterRoutes = [ routes.client.home(), @@ -193,6 +220,12 @@ export const withoutHeaderRoutes = [ routes.client.moonPhaseTracker(), routes.client.energyVampirismResult(), routes.client.nameHoroscopeResult(), + routes.client.goalSetup(), + routes.client.hyperPersonalizedAstrology(), + routes.client.noTime(), + routes.client.loadingInRelationship(), + routes.client.worksForUs(), + routes.client.relationshipAlmostThere(), ]; export const hasNoHeader = (path: string) => { return !withoutHeaderRoutes.includes(`/${path.split("/")[1]}`); @@ -206,7 +239,7 @@ export const hasFullDataModal = (path: string) => { export const getRouteBy = (status: UserStatus): string => { switch (status) { case "lead": - return routes.client.birthday(); + return routes.client.gender(); case "registred": case "unsubscribed": return routes.client.subscription(); diff --git a/src/store/index.ts b/src/store/index.ts index e8fa87c..e06ad61 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -4,6 +4,7 @@ import { createAction, } from "@reduxjs/toolkit"; import token, { actions as tokenActions, selectToken } from "./token"; +import questionnaire, { actions as questionnaireActions, selectQuestionnaire } from "./questionnaire"; import user, { actions as userActions, selectUser } from "./user"; import form, { actions as formActions, @@ -66,6 +67,7 @@ export const actions = { payment: paymentActions, userCallbacks: userCallbacksActions, onboardingConfig: onboardingConfigActions, + questionnaire: questionnaireActions, reset: createAction("reset"), }; export const selectors = { @@ -89,6 +91,7 @@ export const selectors = { selectOnboardingBreath, selectOnboardingNavbarFooter, selectCompatibilities, + selectQuestionnaire, ...formSelectors, }; @@ -105,6 +108,7 @@ export const reducer = combineReducers({ userCallbacks, siteConfig, onboardingConfig, + questionnaire }); export type RootState = ReturnType; diff --git a/src/store/questionnaire.ts b/src/store/questionnaire.ts new file mode 100644 index 0000000..a1f3ee4 --- /dev/null +++ b/src/store/questionnaire.ts @@ -0,0 +1,76 @@ +import { createSlice, createSelector } from "@reduxjs/toolkit"; +import type { PayloadAction } from "@reduxjs/toolkit"; + +export interface IQuestionnaire { + gender: string; + flowChoice: string; + goal: string; + parent: string; + astrologyKnowledge: string; + birthdate: string; + isBirthTime: string; + birthtime: string; + birthPlace: string; + relationshipProblem: string; + partnerGender: string; + partnerBirthdate: string; + partnerBirthtime: string; + partnerBirthPlace: string; + issueTogether: string; + partnerPriority: string; + satisfied: string; + emotionalConnection: string; + bigPicture: string; + introvertOrExtravert: string; + irritated: string; + conflict: string; + aboutGoals: string; + appreciated: string; + decisions: string; +} + +const initialState: IQuestionnaire = { + gender: "", + flowChoice: "", + goal: "", + parent: "", + astrologyKnowledge: "", + birthdate: "", + isBirthTime: "", + birthtime: "12:00", + birthPlace: "", + relationshipProblem: "", + partnerGender: "", + partnerBirthdate: "", + partnerBirthtime: "12:00", + partnerBirthPlace: "", + issueTogether: "", + partnerPriority: "", + satisfied: "", + emotionalConnection: "", + bigPicture: "", + introvertOrExtravert: "", + irritated: "", + conflict: "", + aboutGoals: "", + appreciated: "", + decisions: "", +}; + +const questionnaireSlice = createSlice({ + name: "questionnaire", + initialState, + reducers: { + update(state, action: PayloadAction>) { + return { ...state, ...action.payload }; + }, + }, + extraReducers: (builder) => builder.addCase("reset", () => initialState), +}); + +export const { actions } = questionnaireSlice; +export const selectQuestionnaire = createSelector( + (state: { questionnaire: IQuestionnaire }) => state.questionnaire, + (questionnaire) => questionnaire +); +export default questionnaireSlice.reducer; diff --git a/src/store/token.ts b/src/store/token.ts index d9e619c..f5f571e 100644 --- a/src/store/token.ts +++ b/src/store/token.ts @@ -2,7 +2,7 @@ import { createSlice, createSelector } from '@reduxjs/toolkit' import type { PayloadAction } from '@reduxjs/toolkit' import type { AuthToken } from '../api' -const initialState: AuthToken = '' +const initialState: AuthToken = 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI5MjY0LCJpYXQiOjE3MDA3ODcwNjcsImV4cCI6MTcwOTQyNzA2NywianRpIjoiNDJlYzI4M2ItY2M1My00ZGY1LWIxYzctZmFhZjM3OTU2NjY2IiwiZW1haWwiOiJmYmljaGExMjM0QGdtYWlsLmNvbSIsInN0YXRlIjoicHJvdmVuIiwibG9jIjoicnUiLCJ0eiI6MTQ0MDAsInR5cGUiOiJvYXV0aCIsImlzcyI6ImF1cmF3ZWIifQ.kPAN5MImnR1lhaotPPQc78faot2W1ceygEq33qLkfOM' const authTokenSlice = createSlice({ name: 'token',