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.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 (
-
-
+
+
) => setHour(e.target.value)}>
+ onChange={(e: React.ChangeEvent) =>
+ setHour(e.target.value)
+ }
+ >
{Array.from(Array(12).keys()).map((hour) => (
- {hour + 1}
+
+ {hour + 1}
+
))}
@@ -33,10 +38,15 @@ export function TimePicker({ value, onChange }: TimePickerProps): JSX.Element {
) => setMinute(e.target.value)}>
+ onChange={(e: React.ChangeEvent) =>
+ setMinute(e.target.value)
+ }
+ >
{Array.from(Array(60).keys()).map((minute) => {
return (
- {normalize(minute, 2)}
+
+ {normalize(minute, 2)}
+
);
})}
@@ -45,12 +55,15 @@ export function TimePicker({ value, onChange }: TimePickerProps): JSX.Element {
) => setPeriod(e.target.value)}>
+ onChange={(e: React.ChangeEvent) =>
+ setPeriod(e.target.value)
+ }
+ >
AM
PM
- )
+ );
}
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.name}
+
+
+
+ ))}
+
+
+ );
+}
+
+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 (
+
+
+
+
+ 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{" "}
+ hyper-personalized astrology, {" "}
+ 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{" "}
+
+ {getZodiacSignByDate(birthdate)}
+ {" "}
+ 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 (
+
+
+
+
+ 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 (
+
+
+
+
+ Almost there! Now let's begin tailoring your plan by understanding
+ your{" "}
+
+ Relationship & Personality Patterns
+
+ .
+
+
+ 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 (
+
+
+
+ {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!
+ 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',