Questionnaire

This commit is contained in:
Денис Катаев 2023-12-31 00:33:55 +00:00 committed by Victor Ershov
parent 4081f9b41e
commit 37833a888f
89 changed files with 2804 additions and 159 deletions

68
package-lock.json generated
View File

@ -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",

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
public/blue_book.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
public/brain.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
public/broken_heart.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
public/bunch_of_cards.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

BIN
public/cross_mark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
public/fearful_face.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
public/female.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
public/hands_heart.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

BIN
public/heart.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
public/heart_of_couple.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

BIN
public/kiss.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
public/loudspeaker.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

84
public/magnifier.svg Normal file
View File

@ -0,0 +1,84 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 229 220" width="229" height="220"
preserveAspectRatio="xMidYMid slice"
style="width: 100%; height: 100%; transform: translate3d(0px, 0px, 0px); content-visibility: visible;">
<defs>
<clipPath id="__lottie_element_536">
<rect width="229" height="220" x="0" y="0"></rect>
</clipPath>
</defs>
<g clip-path="url(#__lottie_element_536)">
<g transform="matrix(1.100000023841858,0,0,1.100000023841858,146.6999053955078,10.19990062713623)" opacity="1"
style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,11.060999870300293,11.060999870300293)">
<path fill="rgb(222,227,248)" fill-opacity="1"
d=" M9.829000473022461,-0.9829999804496765 C4.934000015258789,-0.9829999804496765 0.9829999804496765,-4.934000015258789 0.9829999804496765,-9.829000473022461 C0.9829999804496765,-10.378999710083008 0.5509999990463257,-10.810999870300293 0.0010000000474974513,-10.810999870300293 C-0.5490000247955322,-10.810999870300293 -0.9829999804496765,-10.378999710083008 -0.9829999804496765,-9.829000473022461 C-0.9829999804496765,-4.934000015258789 -4.934000015258789,-0.9829999804496765 -9.82699966430664,-0.9829999804496765 C-10.376999855041504,-0.9829999804496765 -10.810999870300293,-0.5509999990463257 -10.810999870300293,0 C-10.810999870300293,0.550000011920929 -10.376999855041504,0.9829999804496765 -9.82699966430664,0.9829999804496765 C-4.934000015258789,0.9829999804496765 -0.9829999804496765,4.934000015258789 -0.9829999804496765,9.82800006866455 C-0.9829999804496765,10.378000259399414 -0.5490000247955322,10.810999870300293 0.0010000000474974513,10.810999870300293 C0.5509999990463257,10.810999870300293 0.9829999804496765,10.378000259399414 0.9829999804496765,9.82800006866455 C0.9829999804496765,4.934000015258789 4.934000015258789,0.9829999804496765 9.829000473022461,0.9829999804496765 C10.380000114440918,0.9829999804496765 10.810999870300293,0.550000011920929 10.810999870300293,0 C10.810999870300293,-0.5509999990463257 10.380000114440918,-0.9829999804496765 9.829000473022461,-0.9829999804496765z">
</path>
</g>
</g>
<g transform="matrix(1.0700000524520874,0,0,1.0700000524520874,11.10906982421875,114.61113739013672)"
opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,9.798999786376953,9.79800033569336)">
<path fill="rgb(222,227,248)" fill-opacity="1"
d=" M8.680000305175781,-0.8679999709129333 C4.35699987411499,-0.8679999709129333 0.8679999709129333,-4.355999946594238 0.8679999709129333,-8.680000305175781 C0.8679999709129333,-9.166000366210938 0.4880000054836273,-9.54800033569336 0.0010000000474974513,-9.54800033569336 C-0.48500001430511475,-9.54800033569336 -0.8669999837875366,-9.166000366210938 -0.8669999837875366,-8.680000305175781 C-0.8669999837875366,-4.355999946594238 -4.35699987411499,-0.8679999709129333 -8.680000305175781,-0.8679999709129333 C-9.166000366210938,-0.8679999709129333 -9.54800033569336,-0.4860000014305115 -9.54800033569336,-0.0010000000474974513 C-9.54800033569336,0.4860000014305115 -9.166000366210938,0.8690000176429749 -8.680000305175781,0.8690000176429749 C-4.35699987411499,0.8690000176429749 -0.8669999837875366,4.357999801635742 -0.8669999837875366,8.680999755859375 C-0.8669999837875366,9.166000366210938 -0.48500001430511475,9.54800033569336 0.0010000000474974513,9.54800033569336 C0.4880000054836273,9.54800033569336 0.8679999709129333,9.166000366210938 0.8679999709129333,8.680999755859375 C0.8679999709129333,4.357999801635742 4.35699987411499,0.8690000176429749 8.680000305175781,0.8690000176429749 C9.166000366210938,0.8690000176429749 9.54800033569336,0.4860000014305115 9.54800033569336,-0.0010000000474974513 C9.54800033569336,-0.4860000014305115 9.166000366210938,-0.8679999709129333 8.680000305175781,-0.8679999709129333z">
</path>
</g>
</g>
<g transform="matrix(1.2607799768447876,0,0,1.2607799768447876,32.27836227416992,145.78036499023438)"
opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,8.407999992370605,8.407999992370605)">
<path fill="rgb(222,227,248)" fill-opacity="1"
d=" M7.414999961853027,-0.7419999837875366 C3.7219998836517334,-0.7419999837875366 0.7419999837875366,-3.7209999561309814 0.7419999837875366,-7.415999889373779 C0.7419999837875366,-7.830999851226807 0.41499999165534973,-8.157999992370605 -0.0010000000474974513,-8.157999992370605 C-0.41600000858306885,-8.157999992370605 -0.7419999837875366,-7.830999851226807 -0.7419999837875366,-7.415999889373779 C-0.7419999837875366,-3.7209999561309814 -3.7230000495910645,-0.7419999837875366 -7.416999816894531,-0.7419999837875366 C-7.831999778747559,-0.7419999837875366 -8.157999992370605,-0.41499999165534973 -8.157999992370605,0.0010000000474974513 C-8.157999992370605,0.41499999165534973 -7.831999778747559,0.7400000095367432 -7.416999816894531,0.7400000095367432 C-3.7230000495910645,0.7400000095367432 -0.7419999837875366,3.7219998836517334 -0.7419999837875366,7.415999889373779 C-0.7419999837875366,7.830999851226807 -0.41600000858306885,8.157999992370605 -0.0010000000474974513,8.157999992370605 C0.41499999165534973,8.157999992370605 0.7419999837875366,7.830999851226807 0.7419999837875366,7.415999889373779 C0.7419999837875366,3.7219998836517334 3.7219998836517334,0.7400000095367432 7.414999961853027,0.7400000095367432 C7.830999851226807,0.7400000095367432 8.157999992370605,0.41499999165534973 8.157999992370605,0.0010000000474974513 C8.157999992370605,-0.41499999165534973 7.830999851226807,-0.7419999837875366 7.414999961853027,-0.7419999837875366z">
</path>
</g>
</g>
<g transform="matrix(1.1799999475479126,0,0,1.1799999475479126,80.26554107666016,72.68125915527344)" opacity="1"
style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,9.097000122070312,8.743000030517578)">
<path fill="rgb(155,172,213)" fill-opacity="1"
d=" M0.22699999809265137,-8.493000030517578 C0.22699999809265137,-8.493000030517578 -0.2770000100135803,-8.493000030517578 -0.2770000100135803,-8.493000030517578 C-0.5789999961853027,-8.493000030517578 -0.8289999961853027,-8.276000022888184 -0.8289999961853027,-7.986000061035156 C-1.0800000429153442,-4.578000068664551 -4.800000190734863,-1.0989999771118164 -8.343999862670898,-0.7850000262260437 C-8.619999885559082,-0.7609999775886536 -8.845999717712402,-0.5189999938011169 -8.845999717712402,-0.2529999911785126 C-8.845999717712402,-0.2529999911785126 -8.845999717712402,0.2540000081062317 -8.845999717712402,0.2540000081062317 C-8.845999717712402,0.5440000295639038 -8.619999885559082,0.7609999775886536 -8.317999839782715,0.7860000133514404 C-4.800000190734863,1.027999997138977 -1.2059999704360962,4.531000137329102 -0.8289999961853027,7.938000202178955 C-0.8040000200271606,8.251999855041504 -0.5270000100135803,8.493000030517578 -0.17599999904632568,8.493000030517578 C-0.17599999904632568,8.493000030517578 0.17599999904632568,8.493000030517578 0.17599999904632568,8.493000030517578 C0.5270000100135803,8.493000030517578 0.8040000200271606,8.251999855041504 0.8289999961853027,7.914000034332275 C1.1299999952316284,4.0960001945495605 4.322999954223633,0.9559999704360962 8.293999671936035,0.7609999775886536 C8.621000289916992,0.7379999756813049 8.845999717712402,0.4959999918937683 8.845999717712402,0.18199999630451202 C8.845999717712402,0.18199999630451202 8.845999717712402,-0.2529999911785126 8.845999717712402,-0.2529999911785126 C8.845999717712402,-0.5669999718666077 8.595999717712402,-0.8090000152587891 8.293999671936035,-0.8330000042915344 C4.297999858856201,-1.0260000228881836 1.0800000429153442,-4.190999984741211 0.8289999961853027,-8.057000160217285 C0.7789999842643738,-8.274999618530273 0.527999997138977,-8.493000030517578 0.22699999809265137,-8.493000030517578z">
</path>
</g>
</g>
<g transform="matrix(1.0299999713897705,0,0,1.0299999713897705,99.71749877929688,100.21749877929688)"
opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,17.75,17.75)">
<path fill="rgb(155,171,217)" fill-opacity="1"
d=" M0.5070000290870667,-17.5 C0.5070000290870667,-17.5 -0.5070000290870667,-17.5 -0.5070000290870667,-17.5 C-1.0989999771118164,-17.5 -1.590999960899353,-17.045000076293945 -1.6260000467300415,-16.451000213623047 C-2.115000009536743,-9.42300033569336 -9.458000183105469,-2.2899999618530273 -16.486000061035156,-1.6260000467300415 C-17.045000076293945,-1.590999960899353 -17.5,-1.1009999513626099 -17.5,-0.5070000290870667 C-17.5,-0.5070000290870667 -17.5,0.5419999957084656 -17.5,0.5419999957084656 C-17.5,1.1360000371932983 -17.045000076293945,1.590999960899353 -16.451000213623047,1.6610000133514404 C-9.493000030517578,2.1500000953674316 -2.359999895095825,9.387999534606934 -1.6260000467300415,16.34600067138672 C-1.555999994277954,17.010000228881836 -0.9959999918937683,17.5 -0.367000013589859,17.5 C-0.367000013589859,17.5 0.3319999873638153,17.5 0.3319999873638153,17.5 C0.996999979019165,17.5 1.555999994277954,16.97599983215332 1.6260000467300415,16.31100082397461 C2.2200000286102295,8.444000244140625 8.513999938964844,2.009999990463257 16.381000518798828,1.6260000467300415 C17.010000228881836,1.590999960899353 17.5,1.065999984741211 17.5,0.47200000286102295 C17.5,0.47200000286102295 17.5,-0.4020000100135803 17.5,-0.4020000100135803 C17.5,-1.031000018119812 17.010000228881836,-1.555999994277954 16.381000518798828,-1.555999994277954 C8.479000091552734,-1.940999984741211 2.1519999504089355,-8.444000244140625 1.6260000467300415,-16.381000518798828 C1.590999960899353,-17.045000076293945 1.1009999513626099,-17.5 0.5070000290870667,-17.5z">
</path>
</g>
</g>
<g transform="matrix(0.9999950528144836,0,0,0.9999950528144836,114.4996337890625,109.99948120117188)"
opacity="0.18" style="display: block;">
<g opacity="1" transform="matrix(1.0375900268554688,0,0,1.0375900268554688,-10.25,-13.25)">
<path fill="rgb(222,228,248)" fill-opacity="1"
d=" M0,-50 C27.594999313354492,-50 50,-27.594999313354492 50,0 C50,27.594999313354492 27.594999313354492,50 0,50 C-27.594999313354492,50 -50,27.594999313354492 -50,0 C-50,-27.594999313354492 -27.594999313354492,-50 0,-50z">
</path>
<path stroke-linecap="butt" stroke-linejoin="miter" fill-opacity="0" stroke-miterlimit="4"
stroke="rgb(222,228,248)" stroke-opacity="1" stroke-width="0"
d=" M0,-50 C27.594999313354492,-50 50,-27.594999313354492 50,0 C50,27.594999313354492 27.594999313354492,50 0,50 C-27.594999313354492,50 -50,27.594999313354492 -50,0 C-50,-27.594999313354492 -27.594999313354492,-50 0,-50z">
</path>
</g>
</g>
<g transform="matrix(0.9999950528144836,0,0,0.9999950528144836,114.4996337890625,109.99948120117188)"
opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,0,0)">
<path fill="rgb(222,228,248)" fill-opacity="1"
d=" M34.375,22.5 C34.375,22.5 25.125,30.375 25.125,30.375 C25.125,30.375 48.25,52.5 48.25,52.5 C48.25,52.5 48.125,56 48.75,58.375 C49.19200134277344,60.05400085449219 85.25,96 87.625,97.5 C90,99 90.12300109863281,98.83999633789062 92.375,98.75 C95.5,98.625 97.875,97 99.5,95.5 C101.125,94 102.875,90.5 102.75,87.875 C102.625,85.25 101.875,83.25 101.875,83.25 C101.875,83.25 63.875,45 63.875,45 C63.875,45 62.625,44.5 61.125,44.25 C59.625,44 57.625,44.25 57.625,44.25 C57.625,44.25 34.375,22.5 34.375,22.5z">
</path>
<path stroke-linecap="butt" stroke-linejoin="miter" fill-opacity="0" stroke-miterlimit="4"
stroke="rgb(222,228,248)" stroke-opacity="1" stroke-width="0"
d=" M34.375,22.5 C34.375,22.5 25.125,30.375 25.125,30.375 C25.125,30.375 48.25,52.5 48.25,52.5 C48.25,52.5 48.125,56 48.75,58.375 C49.19200134277344,60.05400085449219 85.25,96 87.625,97.5 C90,99 90.12300109863281,98.83999633789062 92.375,98.75 C95.5,98.625 97.875,97 99.5,95.5 C101.125,94 102.875,90.5 102.75,87.875 C102.625,85.25 101.875,83.25 101.875,83.25 C101.875,83.25 63.875,45 63.875,45 C63.875,45 62.625,44.5 61.125,44.25 C59.625,44 57.625,44.25 57.625,44.25 C57.625,44.25 34.375,22.5 34.375,22.5z">
</path>
</g>
</g>
<g transform="matrix(1.0387400388717651,0,0,1.0387400388717651,114.08413696289062,111.54720306396484)"
opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,-8.625,-14.125)">
<path stroke-linecap="butt" stroke-linejoin="miter" fill-opacity="0" stroke-miterlimit="4"
stroke="rgb(222,228,248)" stroke-opacity="1" stroke-width="6"
d=" M0,-51.625 C28.491836547851562,-51.625 51.625,-28.491836547851562 51.625,0 C51.625,28.491836547851562 28.491836547851562,51.625 0,51.625 C-28.491836547851562,51.625 -51.625,28.491836547851562 -51.625,0 C-51.625,-28.491836547851562 -28.491836547851562,-51.625 0,-51.625z">
</path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

BIN
public/male.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
public/man.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
public/man_student.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
public/microscope.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
public/moon_phases.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
public/mountain.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
public/neutral_face.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
public/paperclip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
public/party_popper.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
public/raising_hands.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
public/red-heart.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
public/ring.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
public/scales.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
public/shield.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
public/sparkles.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
public/star_struck.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

86
public/starry-clock.svg Normal file
View File

@ -0,0 +1,86 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 189 230" width="189" height="230"
preserveAspectRatio="xMidYMid slice"
style="width: 100%; height: 100%; transform: translate3d(0px, 0px, 0px); content-visibility: visible;">
<defs>
<clipPath id="__lottie_element_34">
<rect width="189" height="230" x="0" y="0"></rect>
</clipPath>
</defs>
<g clip-path="url(#__lottie_element_34)">
<g transform="matrix(1,0,0,1,30.179000854492188,34.006004333496094)" opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,80.32099914550781,80.3219985961914)">
<path stroke-linecap="butt" stroke-linejoin="miter" fill-opacity="0" stroke-miterlimit="4"
stroke="rgb(222,227,248)" stroke-opacity="1" stroke-width="6"
d=" M-47.87900161743164,-47.880001068115234 C-21.43600082397461,-74.3219985961914 21.43400001525879,-74.3219985961914 47.87900161743164,-47.880001068115234 C74.32099914550781,-21.437000274658203 74.32099914550781,21.434999465942383 47.87900161743164,47.87900161743164 C21.43400001525879,74.3219985961914 -21.43600082397461,74.3219985961914 -47.87900161743164,47.87900161743164 C-74.32099914550781,21.434999465942383 -74.32099914550781,-21.437000274658203 -47.87900161743164,-47.880001068115234z">
</path>
</g>
</g>
<g transform="matrix(1,0,0,1,159.3090057373047,113.5780029296875)" opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,3.25,2.25)">
<path fill="rgb(155,171,217)" fill-opacity="1"
d=" M-3,2 C-3,2 1,2 1,2 C2.1019999980926514,2 3,1.100000023841858 3,0 C3,-1.100000023841858 2.1019999980926514,-2 1,-2 C1,-2 -3,-2 -3,-2 C-3,-2 -3,2 -3,2z">
</path>
</g>
</g>
<g transform="matrix(1,0,0,1,55.31800079345703,113.5780029296875)" opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,3.25,2.25)">
<path fill="rgb(155,171,217)" fill-opacity="1"
d=" M-1,2 C-1,2 3,2 3,2 C3,2 3,-2 3,-2 C3,-2 -1,-2 -1,-2 C-2.0999999046325684,-2 -3,-1.100000023841858 -3,0 C-3,1.100000023841858 -2.0999999046325684,2 -1,2z">
</path>
</g>
</g>
<g transform="matrix(1,0,0,1,108.25,59.882999420166016)" opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,2.25,3.25)">
<path fill="rgb(155,171,217)" fill-opacity="1"
d=" M2,3 C2,3 2,-1 2,-1 C2,-2.0999999046325684 1.100000023841858,-3 0,-3 C-1.100000023841858,-3 -2,-2.0999999046325684 -2,-1 C-2,-1 -2,3 -2,3 C-2,3 2,3 2,3z">
</path>
</g>
</g>
<g transform="matrix(1,0,0,1,108.25,163.875)" opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,2.25,3.25)">
<path fill="rgb(155,171,217)" fill-opacity="1"
d=" M2,1 C2,1 2,-3 2,-3 C2,-3 -2,-3 -2,-3 C-2,-3 -2,1 -2,1 C-2,2.1010000705718994 -1.100000023841858,3 0,3 C1.100000023841858,3 2,2.1010000705718994 2,1z">
</path>
</g>
</g>
<g transform="matrix(1.0499999523162842,0,0,1.0499999523162842,142.27615356445312,7.604150772094727)"
opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,16.277000427246094,16.277000427246094)">
<path fill="rgb(222,227,248)" fill-opacity="1"
d=" M14.571000099182129,-1.4570000171661377 C7.314000129699707,-1.4570000171661377 1.4579999446868896,-7.314000129699707 1.4579999446868896,-14.571000099182129 C1.4579999446868896,-15.38700008392334 0.8159999847412109,-16.027000427246094 0.0010000000474974513,-16.027000427246094 C-0.8159999847412109,-16.027000427246094 -1.4559999704360962,-15.38700008392334 -1.4559999704360962,-14.571000099182129 C-1.4559999704360962,-7.314000129699707 -7.314000129699707,-1.4570000171661377 -14.569999694824219,-1.4570000171661377 C-15.385000228881836,-1.4570000171661377 -16.027000427246094,-0.8169999718666077 -16.027000427246094,0 C-16.027000427246094,0.8149999976158142 -15.385000228881836,1.4570000171661377 -14.569999694824219,1.4570000171661377 C-7.314000129699707,1.4570000171661377 -1.4559999704360962,7.314000129699707 -1.4559999704360962,14.569999694824219 C-1.4559999704360962,15.38599967956543 -0.8159999847412109,16.027000427246094 0.0010000000474974513,16.027000427246094 C0.8159999847412109,16.027000427246094 1.4579999446868896,15.38599967956543 1.4579999446868896,14.569999694824219 C1.4579999446868896,7.314000129699707 7.314000129699707,1.4570000171661377 14.571000099182129,1.4570000171661377 C15.38700008392334,1.4570000171661377 16.027000427246094,0.8149999976158142 16.027000427246094,0 C16.027000427246094,-0.8169999718666077 15.38700008392334,-1.4570000171661377 14.571000099182129,-1.4570000171661377z">
</path>
</g>
</g>
<g transform="matrix(1.8299963474273682,0,0,1.8299963474273682,1.3078155517578125,168.63299560546875)"
opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,6.986999988555908,6.98799991607666)">
<path fill="rgb(222,227,248)" fill-opacity="1"
d=" M6.125,-0.6140000224113464 C3.075000047683716,-0.6140000224113464 0.6129999756813049,-3.075000047683716 0.6129999756813049,-6.125999927520752 C0.6129999756813049,-6.4679999351501465 0.3440000116825104,-6.73799991607666 0,-6.73799991607666 C-0.34200000762939453,-6.73799991607666 -0.6110000014305115,-6.4679999351501465 -0.6110000014305115,-6.125999927520752 C-0.6110000014305115,-3.075000047683716 -3.075000047683716,-0.6140000224113464 -6.125,-0.6140000224113464 C-6.4679999351501465,-0.6140000224113464 -6.736999988555908,-0.34299999475479126 -6.736999988555908,-0.0010000000474974513 C-6.736999988555908,0.34200000762939453 -6.4679999351501465,0.6129999756813049 -6.125,0.6129999756813049 C-3.075000047683716,0.6129999756813049 -0.6110000014305115,3.0739998817443848 -0.6110000014305115,6.124000072479248 C-0.6110000014305115,6.4670000076293945 -0.34200000762939453,6.73799991607666 0,6.73799991607666 C0.3440000116825104,6.73799991607666 0.6129999756813049,6.4670000076293945 0.6129999756813049,6.124000072479248 C0.6129999756813049,3.0739998817443848 3.075000047683716,0.6129999756813049 6.125,0.6129999756813049 C6.4679999351501465,0.6129999756813049 6.736999988555908,0.34200000762939453 6.736999988555908,-0.0010000000474974513 C6.736999988555908,-0.34299999475479126 6.4679999351501465,-0.6140000224113464 6.125,-0.6140000224113464z">
</path>
</g>
</g>
<g transform="matrix(0.7300000190734863,0,0,0.7300000190734863,29.495201110839844,206.82418823242188)"
opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,8.059000015258789,8.0600004196167)">
<path fill="rgb(155,171,217)" fill-opacity="1"
d=" M7.099999904632568,-0.7099999785423279 C3.563999891281128,-0.7099999785423279 0.7099999785423279,-3.562999963760376 0.7099999785423279,-7.0980000495910645 C0.7099999785423279,-7.495999813079834 0.3970000147819519,-7.809000015258789 -0.0010000000474974513,-7.809000015258789 C-0.39800000190734863,-7.809000015258789 -0.7099999785423279,-7.495999813079834 -0.7099999785423279,-7.0980000495910645 C-0.7099999785423279,-3.562999963760376 -3.563999891281128,-0.7099999785423279 -7.099999904632568,-0.7099999785423279 C-7.498000144958496,-0.7099999785423279 -7.809000015258789,-0.39800000190734863 -7.809000015258789,0.0010000000474974513 C-7.809000015258789,0.3970000147819519 -7.498000144958496,0.7080000042915344 -7.099999904632568,0.7080000042915344 C-3.563999891281128,0.7080000042915344 -0.7099999785423279,3.563999891281128 -0.7099999785423279,7.099999904632568 C-0.7099999785423279,7.498000144958496 -0.39800000190734863,7.809000015258789 -0.0010000000474974513,7.809000015258789 C0.3970000147819519,7.809000015258789 0.7099999785423279,7.498000144958496 0.7099999785423279,7.099999904632568 C0.7099999785423279,3.563999891281128 3.563999891281128,0.7080000042915344 7.099999904632568,0.7080000042915344 C7.497000217437744,0.7080000042915344 7.809000015258789,0.3970000147819519 7.809000015258789,0.0010000000474974513 C7.809000015258789,-0.39800000190734863 7.497000217437744,-0.7099999785423279 7.099999904632568,-0.7099999785423279z">
</path>
</g>
</g>
<g transform="matrix(-1,0,0,-1,114.41899871826172,120.96099853515625)" opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,3.3519999980926514,25.680999755859375)">
<path fill="rgb(155,171,217)" fill-opacity="1"
d=" M-0.0010000000474974513,25.430999755859375 C-1.7139999866485596,25.430999755859375 -3.1029999256134033,24.041000366210938 -3.1029999256134033,22.327999114990234 C-3.1029999256134033,22.327999114990234 -3.1029999256134033,-22.33099937438965 -3.1029999256134033,-22.33099937438965 C-3.1029999256134033,-24.04400062561035 -1.7139999866485596,-25.430999755859375 -0.0010000000474974513,-25.430999755859375 C1.7130000591278076,-25.430999755859375 3.1029999256134033,-24.04400062561035 3.1029999256134033,-22.33099937438965 C3.1029999256134033,-22.33099937438965 3.1029999256134033,22.327999114990234 3.1029999256134033,22.327999114990234 C3.1029999256134033,24.041000366210938 1.7130000591278076,25.430999755859375 -0.0010000000474974513,25.430999755859375z">
</path>
</g>
</g>
<g transform="matrix(0.8987940549850464,0.4383711516857147,-0.4383711516857147,0.8987940549850464,108.76094818115234,88.73240661621094)"
opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,9.63599967956543,14.701000213623047)">
<path fill="rgb(107,121,170)" fill-opacity="1"
d=" M-6.576000213623047,-13.482999801635742 C-4.591000080108643,-14.451000213623047 -2.194000005722046,-13.62600040435791 -1.2259999513626099,-11.640999794006348 C-1.2259999513626099,-11.640999794006348 8.418000221252441,8.131999969482422 8.418000221252441,8.131999969482422 C9.38599967956543,10.116999626159668 8.560999870300293,12.513999938964844 6.576000213623047,13.482000350952148 C4.590000152587891,14.449999809265137 2.194000005722046,13.625 1.2259999513626099,11.640999794006348 C1.2259999513626099,11.640999794006348 -8.416999816894531,-8.135000228881836 -8.416999816894531,-8.135000228881836 C-9.38599967956543,-10.119000434875488 -8.560999870300293,-12.513999938964844 -6.576000213623047,-13.482999801635742z">
</path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

68
public/starry-sky.svg Normal file
View File

@ -0,0 +1,68 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 266 197" width="266" height="197"
preserveAspectRatio="xMidYMid slice"
style="width: 100%; height: 100%; transform: translate3d(0px, 0px, 0px); content-visibility: visible;">
<defs>
<clipPath id="__lottie_element_21">
<rect width="266" height="197" x="0" y="0"></rect>
</clipPath>
<linearGradient id="__lottie_element_25" spreadMethod="pad" gradientUnits="userSpaceOnUse" x1="0" y1="0"
x2="100" y2="0">
<stop offset="0%" stop-color="rgb(255,255,255)"></stop>
<stop offset="50%" stop-color="rgb(206,214,237)"></stop>
<stop offset="100%" stop-color="rgb(157,173,219)"></stop>
</linearGradient>
<linearGradient id="__lottie_element_29" spreadMethod="pad" gradientUnits="userSpaceOnUse" x1="0" y1="0"
x2="100" y2="0">
<stop offset="0%" stop-color="rgb(255,255,255)"></stop>
<stop offset="50%" stop-color="rgb(206,214,237)"></stop>
<stop offset="100%" stop-color="rgb(157,173,219)"></stop>
</linearGradient>
</defs>
<g clip-path="url(#__lottie_element_21)">
<g transform="matrix(1.8899999856948853,0,0,1.8899999856948853,177.87490844726562,133.66526794433594)"
opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,8.59000015258789,8.256999969482422)">
<path fill="rgb(155,172,213)" fill-opacity="1"
d=" M0.21400000154972076,-8.006999969482422 C0.21400000154972076,-8.006999969482422 -0.26100000739097595,-8.006999969482422 -0.26100000739097595,-8.006999969482422 C-0.5460000038146973,-8.006999969482422 -0.7820000052452087,-7.802000045776367 -0.7820000052452087,-7.5279998779296875 C-1.0190000534057617,-4.316999912261963 -4.526000022888184,-1.0360000133514404 -7.867000102996826,-0.7400000095367432 C-8.126999855041504,-0.7179999947547913 -8.34000015258789,-0.49000000953674316 -8.34000015258789,-0.23899999260902405 C-8.34000015258789,-0.23899999260902405 -8.34000015258789,0.23800000548362732 -8.34000015258789,0.23800000548362732 C-8.34000015258789,0.5130000114440918 -8.12600040435791,0.7170000076293945 -7.8420000076293945,0.7400000095367432 C-4.525000095367432,0.9679999947547913 -1.1380000114440918,4.269999980926514 -0.7820000052452087,7.48199987411499 C-0.7590000033378601,7.7789998054504395 -0.49799999594688416,8.006999969482422 -0.16599999368190765,8.006999969482422 C-0.16599999368190765,8.006999969482422 0.16599999368190765,8.006999969482422 0.16599999368190765,8.006999969482422 C0.4970000088214874,8.006999969482422 0.7580000162124634,7.7789998054504395 0.781000018119812,7.460000038146973 C1.065999984741211,3.8610000610351562 4.074999809265137,0.8989999890327454 7.817999839782715,0.7170000076293945 C8.12600040435791,0.6949999928474426 8.34000015258789,0.46700000762939453 8.34000015258789,0.17100000381469727 C8.34000015258789,0.17100000381469727 8.34000015258789,-0.23899999260902405 8.34000015258789,-0.23899999260902405 C8.34000015258789,-0.5350000262260437 8.102999687194824,-0.7639999985694885 7.817999839782715,-0.7860000133514404 C4.051000118255615,-0.968999981880188 1.0190000534057617,-3.9519999027252197 0.781000018119812,-7.5970001220703125 C0.734000027179718,-7.802000045776367 0.49799999594688416,-8.006999969482422 0.21400000154972076,-8.006999969482422z">
</path>
</g>
</g>
<g transform="matrix(0.5600000023841858,0,0,0.5600000023841858,76.72735595703125,42.38835906982422)" opacity="1"
style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,16.518999099731445,16.518999099731445)">
<path fill="rgb(222,227,248)" fill-opacity="1"
d=" M14.789999961853027,-1.4789999723434448 C7.425000190734863,-1.4789999723434448 1.4789999723434448,-7.423999786376953 1.4789999723434448,-14.789999961853027 C1.4789999723434448,-15.618000030517578 0.828000009059906,-16.268999099731445 0,-16.268999099731445 C-0.828000009059906,-16.268999099731445 -1.4789999723434448,-15.618000030517578 -1.4789999723434448,-14.789999961853027 C-1.4789999723434448,-7.423999786376953 -7.425000190734863,-1.4789999723434448 -14.789999961853027,-1.4789999723434448 C-15.618000030517578,-1.4789999723434448 -16.268999099731445,-0.828000009059906 -16.268999099731445,0 C-16.268999099731445,0.828000009059906 -15.618000030517578,1.4800000190734863 -14.789999961853027,1.4800000190734863 C-7.425000190734863,1.4800000190734863 -1.4789999723434448,7.425000190734863 -1.4789999723434448,14.789999961853027 C-1.4789999723434448,15.619000434875488 -0.828000009059906,16.268999099731445 0,16.268999099731445 C0.828000009059906,16.268999099731445 1.4789999723434448,15.619000434875488 1.4789999723434448,14.789999961853027 C1.4789999723434448,7.425000190734863 7.425000190734863,1.4800000190734863 14.789999961853027,1.4800000190734863 C15.619000434875488,1.4800000190734863 16.268999099731445,0.828000009059906 16.268999099731445,0 C16.268999099731445,-0.828000009059906 15.619000434875488,-1.4789999723434448 14.789999961853027,-1.4789999723434448z">
</path>
</g>
</g>
<g transform="matrix(1,0,0,1,167.4199981689453,35.08100128173828)" opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,5.567999839782715,5.568999767303467)">
<path fill="rgb(222,227,248)" fill-opacity="1"
d=" M4.835999965667725,-0.48399999737739563 C2.427999973297119,-0.48399999737739563 0.48399999737739563,-2.427999973297119 0.48399999737739563,-4.835999965667725 C0.48399999737739563,-5.10699987411499 0.2709999978542328,-5.318999767303467 0.0010000000474974513,-5.318999767303467 C-0.27000001072883606,-5.318999767303467 -0.4830000102519989,-5.10699987411499 -0.4830000102519989,-4.835999965667725 C-0.4830000102519989,-2.427999973297119 -2.427000045776367,-0.48399999737739563 -4.835000038146973,-0.48399999737739563 C-5.105999946594238,-0.48399999737739563 -5.317999839782715,-0.2709999978542328 -5.317999839782715,0 C-5.317999839782715,0.27000001072883606 -5.105999946594238,0.4830000102519989 -4.835000038146973,0.4830000102519989 C-2.427000045776367,0.4830000102519989 -0.4830000102519989,2.427000045776367 -0.4830000102519989,4.835000038146973 C-0.4830000102519989,5.105999946594238 -0.27000001072883606,5.318999767303467 0.0010000000474974513,5.318999767303467 C0.2709999978542328,5.318999767303467 0.48399999737739563,5.105999946594238 0.48399999737739563,4.835000038146973 C0.48399999737739563,2.427000045776367 2.427999973297119,0.4830000102519989 4.835999965667725,0.4830000102519989 C5.10699987411499,0.4830000102519989 5.317999839782715,0.27000001072883606 5.317999839782715,0 C5.317999839782715,-0.2709999978542328 5.10699987411499,-0.48399999737739563 4.835999965667725,-0.48399999737739563z">
</path>
</g>
</g>
<g transform="matrix(1,0,0,1,133,98.5)" opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,0,0)">
<path fill="url(#__lottie_element_29)" fill-opacity="1"
d=" M85.75,-36.75 C84.01499938964844,-35.724998474121094 -84.75,76.25 -84.75,76.25 C-84.75,76.25 97.38899993896484,-16.871999740600586 98.75,-18 C100.93800354003906,-19.812999725341797 104,-25.5 100.25,-31.75 C96.5,-38 88.5,-38.375 85.75,-36.75z">
</path>
<path stroke-linecap="butt" stroke-linejoin="miter" fill-opacity="0" stroke-miterlimit="4"
stroke="rgb(255,255,255)" stroke-opacity="1" stroke-width="0"
d=" M85.75,-36.75 C84.01499938964844,-35.724998474121094 -84.75,76.25 -84.75,76.25 C-84.75,76.25 97.38899993896484,-16.871999740600586 98.75,-18 C100.93800354003906,-19.812999725341797 104,-25.5 100.25,-31.75 C96.5,-38 88.5,-38.375 85.75,-36.75z">
</path>
</g>
</g>
<g transform="matrix(1,0,0,1,353.5,-29.5)" opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,0,0)">
<path fill="url(#__lottie_element_25)" fill-opacity="1"
d=" M85.75,-36.75 C84.01499938964844,-35.724998474121094 -84.75,76.25 -84.75,76.25 C-84.75,76.25 97.38899993896484,-16.871999740600586 98.75,-18 C100.93800354003906,-19.812999725341797 104,-25.5 100.25,-31.75 C96.5,-38 88.5,-38.375 85.75,-36.75z">
</path>
<path stroke-linecap="butt" stroke-linejoin="miter" fill-opacity="0" stroke-miterlimit="4"
stroke="rgb(255,255,255)" stroke-opacity="1" stroke-width="0"
d=" M85.75,-36.75 C84.01499938964844,-35.724998474121094 -84.75,76.25 -84.75,76.25 C-84.75,76.25 97.38899993896484,-16.871999740600586 98.75,-18 C100.93800354003906,-19.812999725341797 104,-25.5 100.25,-31.75 C96.5,-38 88.5,-38.375 85.75,-36.75z">
</path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.8 KiB

81
public/starry_key.svg Normal file
View File

@ -0,0 +1,81 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 197 138" width="197" height="138"
preserveAspectRatio="xMidYMid slice"
style="width: 100%; height: 100%; transform: translate3d(0px, 0px, 0px); content-visibility: visible;">
<defs>
<clipPath id="__lottie_element_298">
<rect width="197" height="138" x="0" y="0"></rect>
</clipPath>
</defs>
<g clip-path="url(#__lottie_element_298)">
<g transform="matrix(1,0,0,1,178.375,80.0739974975586)" opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,9.75,16.25)">
<path fill="rgb(155,171,217)" fill-opacity="1"
d=" M0,-16 C5.247000217437744,-16 9.5,-8.836000442504883 9.5,0 C9.5,8.836999893188477 5.247000217437744,16 0,16 C-5.247000217437744,16 -9.5,8.836999893188477 -9.5,0 C-9.5,-8.836000442504883 -5.247000217437744,-16 0,-16z">
</path>
</g>
<g opacity="1" transform="matrix(1,0,0,1,10.25,40.25)">
<path fill="rgb(155,171,217)" fill-opacity="1"
d=" M-5.428999900817871,-17 C-5.428999900817871,-17 4.427000045776367,-17 4.427000045776367,-17 C4.427000045776367,-17 6,17 6,17 C6,17 -6,12 -6,12 C-6,12 -5.428999900817871,-17 -5.428999900817871,-17z">
</path>
</g>
</g>
<g transform="matrix(1.0000094175338745,0,0,1.0000094175338745,141.95191955566406,21.779918670654297)"
opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,8.640999794006348,8.642000198364258)">
<path fill="rgb(222,227,248)" fill-opacity="1"
d=" M7.629000186920166,-0.7639999985694885 C3.8299999237060547,-0.7639999985694885 0.7639999985694885,-3.8299999237060547 0.7639999985694885,-7.629000186920166 C0.7639999985694885,-8.055999755859375 0.42800000309944153,-8.392000198364258 0.0010000000474974513,-8.392000198364258 C-0.4269999861717224,-8.392000198364258 -0.7639999985694885,-8.055999755859375 -0.7639999985694885,-7.629000186920166 C-0.7639999985694885,-3.8299999237060547 -3.8299999237060547,-0.7639999985694885 -7.630000114440918,-0.7639999985694885 C-8.055999755859375,-0.7639999985694885 -8.390999794006348,-0.42899999022483826 -8.390999794006348,-0.0010000000474974513 C-8.390999794006348,0.4259999990463257 -8.055999755859375,0.7620000243186951 -7.630000114440918,0.7620000243186951 C-3.8299999237060547,0.7620000243186951 -0.7639999985694885,3.8299999237060547 -0.7639999985694885,7.629000186920166 C-0.7639999985694885,8.055999755859375 -0.4269999861717224,8.392000198364258 0.0010000000474974513,8.392000198364258 C0.42800000309944153,8.392000198364258 0.7639999985694885,8.055999755859375 0.7639999985694885,7.629000186920166 C0.7639999985694885,3.8299999237060547 3.8299999237060547,0.7620000243186951 7.629000186920166,0.7620000243186951 C8.057000160217285,0.7620000243186951 8.390999794006348,0.4259999990463257 8.390999794006348,-0.0010000000474974513 C8.390999794006348,-0.42899999022483826 8.057000160217285,-0.7639999985694885 7.629000186920166,-0.7639999985694885z">
</path>
</g>
</g>
<g transform="matrix(0.9999973177909851,0,0,0.9999973177909851,65.25801849365234,0.58502197265625)" opacity="1"
style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,8.121000289916992,8.121999740600586)">
<path fill="rgb(155,171,217)" fill-opacity="1"
d=" M7.15500020980835,-0.7160000205039978 C3.5920000076293945,-0.7160000205039978 0.7160000205039978,-3.5929999351501465 0.7160000205039978,-7.156000137329102 C0.7160000205039978,-7.558000087738037 0.4000000059604645,-7.872000217437744 -0.0010000000474974513,-7.872000217437744 C-0.4009999930858612,-7.872000217437744 -0.7160000205039978,-7.558000087738037 -0.7160000205039978,-7.156000137329102 C-0.7160000205039978,-3.5929999351501465 -3.5920000076293945,-0.7160000205039978 -7.156000137329102,-0.7160000205039978 C-7.556000232696533,-0.7160000205039978 -7.870999813079834,-0.4020000100135803 -7.870999813079834,0 C-7.870999813079834,0.4000000059604645 -7.556000232696533,0.7160000205039978 -7.156000137329102,0.7160000205039978 C-3.5920000076293945,0.7160000205039978 -0.7160000205039978,3.5920000076293945 -0.7160000205039978,7.156000137329102 C-0.7160000205039978,7.557000160217285 -0.4009999930858612,7.872000217437744 -0.0010000000474974513,7.872000217437744 C0.4000000059604645,7.872000217437744 0.7160000205039978,7.557000160217285 0.7160000205039978,7.156000137329102 C0.7160000205039978,3.5920000076293945 3.5920000076293945,0.7160000205039978 7.15500020980835,0.7160000205039978 C7.556000232696533,0.7160000205039978 7.870999813079834,0.4000000059604645 7.870999813079834,0 C7.870999813079834,-0.4020000100135803 7.556000232696533,-0.7160000205039978 7.15500020980835,-0.7160000205039978z">
</path>
</g>
</g>
<g transform="matrix(0.9999902844429016,0,0,0.9999902844429016,16.25016212463379,4.074161529541016)" opacity="1"
style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,16.618000030517578,16.618000030517578)">
<path fill="rgb(222,227,248)" fill-opacity="1"
d=" M14.880999565124512,-1.4880000352859497 C7.46999979019165,-1.4880000352859497 1.4880000352859497,-7.46999979019165 1.4880000352859497,-14.880999565124512 C1.4880000352859497,-15.71399974822998 0.8339999914169312,-16.368000030517578 0.0010000000474974513,-16.368000030517578 C-0.8330000042915344,-16.368000030517578 -1.4880000352859497,-15.71399974822998 -1.4880000352859497,-14.880999565124512 C-1.4880000352859497,-7.46999979019165 -7.46999979019165,-1.4880000352859497 -14.880999565124512,-1.4880000352859497 C-15.71399974822998,-1.4880000352859497 -16.368000030517578,-0.8339999914169312 -16.368000030517578,0 C-16.368000030517578,0.8330000042915344 -15.71399974822998,1.4880000352859497 -14.880999565124512,1.4880000352859497 C-7.46999979019165,1.4880000352859497 -1.4880000352859497,7.46999979019165 -1.4880000352859497,14.880000114440918 C-1.4880000352859497,15.713000297546387 -0.8330000042915344,16.368000030517578 0.0010000000474974513,16.368000030517578 C0.8339999914169312,16.368000030517578 1.4880000352859497,15.713000297546387 1.4880000352859497,14.880000114440918 C1.4880000352859497,7.46999979019165 7.46999979019165,1.4880000352859497 14.880999565124512,1.4880000352859497 C15.71399974822998,1.4880000352859497 16.368000030517578,0.8330000042915344 16.368000030517578,0 C16.368000030517578,-0.8339999914169312 15.71399974822998,-1.4880000352859497 14.880999565124512,-1.4880000352859497z">
</path>
</g>
</g>
<g transform="matrix(1,0,0,1,98.5,69)" opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,0,0)">
<path fill="rgb(155,171,217)" fill-opacity="1"
d=" M60.3129997253418,32.625 C60.3129997253418,32.625 27.75,32.9379997253418 27.75,32.9379997253418 C27.75,32.9379997253418 27.575000762939453,40.25400161743164 28,45.25 C28.25,48.1879997253418 29.5,48.625 30.812999725341797,49.9379997253418 C32.125999450683594,51.250999450683594 34.6879997253418,51.75 34.6879997253418,51.75 C34.6879997253418,51.75 34.53099822998047,42.90700149536133 43.625,42.9379997253418 C53,42.970001220703125 53.0629997253418,52.0629997253418 53.0629997253418,52.0629997253418 C53.0629997253418,52.0629997253418 57.3129997253418,50.0629997253418 58.3129997253418,48.6879997253418 C59.3129997253418,47.3129997253418 60.125,46.125 60.125,44.75 C60.125,43.8120002746582 60.3129997253418,32.625 60.3129997253418,32.625z">
</path>
<path stroke-linecap="butt" stroke-linejoin="miter" fill-opacity="0" stroke-miterlimit="4"
stroke="rgb(155,171,217)" stroke-opacity="1" stroke-width="0"
d=" M60.3129997253418,32.625 C60.3129997253418,32.625 27.75,32.9379997253418 27.75,32.9379997253418 C27.75,32.9379997253418 27.575000762939453,40.25400161743164 28,45.25 C28.25,48.1879997253418 29.5,48.625 30.812999725341797,49.9379997253418 C32.125999450683594,51.250999450683594 34.6879997253418,51.75 34.6879997253418,51.75 C34.6879997253418,51.75 34.53099822998047,42.90700149536133 43.625,42.9379997253418 C53,42.970001220703125 53.0629997253418,52.0629997253418 53.0629997253418,52.0629997253418 C53.0629997253418,52.0629997253418 57.3129997253418,50.0629997253418 58.3129997253418,48.6879997253418 C59.3129997253418,47.3129997253418 60.125,46.125 60.125,44.75 C60.125,43.8120002746582 60.3129997253418,32.625 60.3129997253418,32.625z">
</path>
</g>
</g>
<g transform="matrix(1,0,0,1,99.25,69)" opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,0,0)">
<path stroke-linecap="round" stroke-linejoin="miter" fill-opacity="0" stroke-miterlimit="4"
stroke="rgb(222,228,248)" stroke-opacity="1" stroke-width="9"
d=" M-47.5,28.75 C-47.5,28.75 66.25,28.5 66.25,28.5"></path>
</g>
</g>
<g transform="matrix(1,0,0,0.8412700295448303,98.5,73.54364776611328)" opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,0,0)">
<path stroke-linecap="round" stroke-linejoin="miter" fill-opacity="0" stroke-miterlimit="4"
stroke="rgb(155,171,217)" stroke-opacity="1" stroke-width="8"
d=" M-12.25,20.75 C-12.25,20.75 -12.25,36.5 -12.25,36.5"></path>
</g>
</g>
<g transform="matrix(1,0,0,1,98.5,69)" opacity="1" style="display: block;">
<g opacity="1" transform="matrix(0.8959500193595886,0,0,0.8725699782371521,-71.5,28.5)">
<path stroke-linecap="butt" stroke-linejoin="miter" fill-opacity="0" stroke-miterlimit="4"
stroke="rgb(222,228,248)" stroke-opacity="1" stroke-width="8"
d=" M0,-32.75 C14.34939956665039,-32.75 26,-18.074724197387695 26,0 C26,18.074724197387695 14.34939956665039,32.75 0,32.75 C-14.34939956665039,32.75 -26,18.074724197387695 -26,0 C-26,-18.074724197387695 -14.34939956665039,-32.75 0,-32.75z">
</path>
</g>
</g>
<g transform="matrix(1,0,0,1,98.5,69)" opacity="1" style="display: block;"></g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

BIN
public/thinking_face.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
public/thumbs_down.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

BIN
public/thumbs_middle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

BIN
public/thumbs_more_down.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
public/thumbs_up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

BIN
public/two-hearts.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

BIN
public/unamused.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
public/wall_clock.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
public/woman-heart-man.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
public/woman.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -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 (
<div className={styles.container} onClick={onClick}>
<img className={styles.icon} src={answer.icon} alt={answer.id} />
<p className={styles.answer}>{answer.answer}</p>
</div>
);
}
export default Answer;

View File

@ -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;
}

View File

@ -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 (
<Routes>
<Route element={<Layout setIsSpecialOfferOpen={setIsSpecialOfferOpen} />}>
{/* Test Routes Start */}
<Route path={routes.client.notFound()} element={<NotFoundPage />} />
<Route path={routes.client.gender()} element={<GenderPage />} />
<Route
path={routes.client.questionnaire()}
element={<QuestionnairePage />}
>
<Route path=":stepId" element={<QuestionnairePage />}>
<Route path=":question" element={<QuestionnairePage />} />
</Route>
</Route>
<Route path={routes.client.goalSetup()} element={<GoalSetupPage />} />
<Route
path={routes.client.hyperPersonalizedAstrology()}
element={<HyperPersonalizedAstrologyPage />}
/>
<Route path={routes.client.noTime()} element={<NoBirthtimePage />} />
<Route
path={routes.client.loadingInRelationship()}
element={<LoadingInRelationshipPage />}
/>
<Route path={routes.client.worksForUs()} element={<WorksForUsPage />} />
<Route
path={routes.client.relationshipAlmostThere()}
element={<RelationshipAlmostTherePage />}
/>
{/* Test Routes End */}
<Route
path={routes.client.paymentResult()}
element={<PaymentResultPage />}
@ -197,77 +233,71 @@ function App(): JSX.Element {
<Route path=":subPlan" element={<SubscriptionPage />} />
</Route>
</Route>
<Route element={<PrivateOutlet />}>
<Route element={<AuthorizedUserOutlet />}>
{/* <Route
{/* <Route element={<PrivateOutlet />}> */}
<Route element={<AuthorizedUserOutlet />}>
{/* <Route
path={routes.client.subscription()}
element={<SubscriptionPage />}
/> */}
<Route
path={routes.client.paymentMethod()}
element={<PaymentPage />}
/>
<Route
path={routes.client.paymentStripe()}
element={<StripePage />}
/>
</Route>
<Route element={<PrivateSubscriptionOutlet />}>
<Route path={routes.client.home()} element={<HomePage />} />
<Route
path={routes.client.compatibility()}
element={<CompatibilityPage />}
/>
<Route
path={routes.client.compatibilityResult()}
element={<CompatResultPage />}
/>
<Route
path={routes.client.breath()}
element={<BreathPage leoApng={leoApng} />}
/>
<Route
path={routes.client.breathResult()}
element={<UserCallbacksPage />}
/>
<Route
path={routes.client.wallpaper()}
element={<WallpaperPage />}
/>
<Route
path={routes.client.magicBall()}
element={<MagicBallPage />}
/>
<Route
path={routes.client.horoscopeBestiesResult()}
element={<BestiesHoroscopeResult />}
/>
<Route
path={routes.client.predictionMoonResult()}
element={<PredictionMoonResult />}
/>
<Route
path={routes.client.myHoroscopeResult()}
element={<MyHoroscopeResult />}
/>
<Route
path={routes.client.thermalResult()}
element={<ThermalResult />}
/>
<Route
path={routes.client.moonPhaseTracker()}
element={<MoonPhaseTrackerResult />}
/>
<Route
path={routes.client.energyVampirismResult()}
element={<EnergyVampirismResult />}
/>
<Route
path={routes.client.nameHoroscopeResult()}
element={<NameHoroscopeResult />}
/>
</Route>
<Route
path={routes.client.paymentMethod()}
element={<PaymentPage />}
/>
<Route
path={routes.client.paymentStripe()}
element={<StripePage />}
/>
</Route>
{/* <Route element={<PrivateSubscriptionOutlet />}> */}
<Route path={routes.client.home()} element={<HomePage />} />
<Route
path={routes.client.compatibility()}
element={<CompatibilityPage />}
/>
<Route
path={routes.client.compatibilityResult()}
element={<CompatResultPage />}
/>
<Route
path={routes.client.breath()}
element={<BreathPage leoApng={leoApng} />}
/>
<Route
path={routes.client.breathResult()}
element={<UserCallbacksPage />}
/>
<Route path={routes.client.wallpaper()} element={<WallpaperPage />} />
<Route path={routes.client.magicBall()} element={<MagicBallPage />} />
<Route
path={routes.client.horoscopeBestiesResult()}
element={<BestiesHoroscopeResult />}
/>
<Route
path={routes.client.predictionMoonResult()}
element={<PredictionMoonResult />}
/>
<Route
path={routes.client.myHoroscopeResult()}
element={<MyHoroscopeResult />}
/>
<Route
path={routes.client.thermalResult()}
element={<ThermalResult />}
/>
<Route
path={routes.client.moonPhaseTracker()}
element={<MoonPhaseTrackerResult />}
/>
<Route
path={routes.client.energyVampirismResult()}
element={<EnergyVampirismResult />}
/>
<Route
path={routes.client.nameHoroscopeResult()}
element={<NameHoroscopeResult />}
/>
{/* </Route> */}
{/* </Route> */}
<Route path="*" element={<NotFoundPage />} />
</Route>
</Routes>
@ -401,25 +431,25 @@ function AuthorizedUserOutlet(): JSX.Element {
);
}
function PrivateOutlet(): JSX.Element {
const { user } = useAuth();
return user ? (
<Outlet />
) : (
<Navigate to={routes.client.root()} replace={true} />
);
}
// function PrivateOutlet(): JSX.Element {
// const { user } = useAuth();
// return user ? (
// <Outlet />
// ) : (
// <Navigate to={routes.client.root()} replace={true} />
// );
// }
function PrivateSubscriptionOutlet(): JSX.Element {
// const isProduction = import.meta.env.MODE === "production";
const isProduction = false;
const status = useSelector(selectors.selectStatus);
return status === "subscribed" || !isProduction ? (
<Outlet />
) : (
<Navigate to={getRouteBy(status)} replace={true} />
);
}
// function PrivateSubscriptionOutlet(): JSX.Element {
// // const isProduction = import.meta.env.MODE === "production";
// const isProduction = false;
// const status = useSelector(selectors.selectStatus);
// return status === "subscribed" || !isProduction ? (
// <Outlet />
// ) : (
// <Navigate to={getRouteBy(status)} replace={true} />
// );
// }
function getIsShowFullDataModal(dataItems: Array<unknown> = []): boolean {
let hasNoDataItem = false;

View File

@ -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 (
<section className={`${styles.page} page`}>

View File

@ -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 (
<div className='date-picker'>
<div className='date-picker__container'>
<div className="date-picker">
<div className="date-picker__container">
<div className="date-picker__field">
<select
className="date-picker__field-select"
value={hour}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => setHour(e.target.value)}>
onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
setHour(e.target.value)
}
>
{Array.from(Array(12).keys()).map((hour) => (
<option key={hour} value={hour + 1}>{hour + 1}</option>
<option key={hour} value={hour + 1}>
{hour + 1}
</option>
))}
</select>
</div>
@ -33,10 +38,15 @@ export function TimePicker({ value, onChange }: TimePickerProps): JSX.Element {
<select
className="date-picker__field-select"
value={minute}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => setMinute(e.target.value)}>
onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
setMinute(e.target.value)
}
>
{Array.from(Array(60).keys()).map((minute) => {
return (
<option key={minute} value={normalize(minute, 2)}>{normalize(minute, 2)}</option>
<option key={minute} value={normalize(minute, 2)}>
{normalize(minute, 2)}
</option>
);
})}
</select>
@ -45,12 +55,15 @@ export function TimePicker({ value, onChange }: TimePickerProps): JSX.Element {
<select
className="date-picker__field-select"
value={period}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => setPeriod(e.target.value)}>
onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
setPeriod(e.target.value)
}
>
<option value="AM">AM</option>
<option value="PM">PM</option>
</select>
</div>
</div>
</div>
)
);
}

View File

@ -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<HTMLInputElement>) => {
const place = e.target.value;
onChange(place);
};
return (
<div className={styles.container}>
<input
className={styles["full-address"]}
name={name}
type="text"
placeholder="Enter city of birth"
maxLength={maxLength}
value={value}
onChange={handleChange}
/>
</div>
);
}
export default PlacePicker;

View File

@ -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;
}

View File

@ -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 (
<div className={styles.container}>
{steps.map((step, index) => {
return (
<div
className={styles["step-container"]}
style={{ width: `${100 / steps.length}%` }}
key={index}
>
<div
className={styles.circle}
style={{
backgroundColor:
index > currentStep ? "transparent" : step.color,
borderColor: step.color,
color: step.color,
}}
>
{index > currentStep ? getIndexOfStep(step.id) : null}
</div>
<div className={styles["line-container"]}>
<div
className={styles.line}
style={{
width: `${getLinePercent(index)}%`,
backgroundColor: step.color,
}}
></div>
</div>
</div>
);
})}
<div
className={styles.circle}
style={{
backgroundColor:
lastStepIndex >= currentStep ? "transparent" : "#bb6bd9",
borderColor: "#bb6bd9",
color: "#bb6bd9",
}}
>
{lastStepIndex >= currentStep ? lastStepIndex + 1 : null}
</div>
</div>
);
}
export default Stepper;

View File

@ -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;
}

View File

@ -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 (
<section className={`${styles.page} page`}>
<Title variant="h2" className={styles.title}>
Understand Yourself and Improve Relationships With Astrology
</Title>
<span className={styles.description}>1-Minute Personal Assessment</span>
<Title variant="h3" className={styles["title-select"]}>
Select your gender:
</Title>
<div className={styles["genders-container"]}>
{genders.map((gender, index) => (
<div
className={styles["gender"]}
key={index}
onClick={() => {
selectGender(gender);
}}
>
<img
src={gender.img}
className={styles["gender__img"]}
alt={gender.id}
/>
<button
className={styles["gender__button"]}
style={{ background: getButtonBGColor(gender) }}
>
<span>{gender.name}</span>
<div className={styles["button__arrow"]}></div>
</button>
</div>
))}
</div>
</section>
);
}
export default GenderPage;

View File

@ -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);
}

View File

@ -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 (
<section className={`${styles.page} page`}>
<img src="/starry-sky.svg" alt="The starry sky" />
<div>
<Title variant="h1" className={styles.title}>
Great! You just set your first goal!
</Title>
<p className={styles.text}>
Let's keep going so we can get to know you better.
</p>
</div>
<div className={styles["buttons-container"]}>
<MainButton
className={`${styles.button} ${styles["back-button"]}`}
onClick={handleBack}
>
Back
</MainButton>
<MainButton
className={`${styles.button} ${styles["next-button"]}`}
onClick={handleNext}
>
Next
</MainButton>
</div>
</section>
);
}
export default GoalSetupPage;

View File

@ -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;
}

View File

@ -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 (
<section className={`${styles.page} page`}>
<Title variant="h2" className={styles.title}>
What is{" "}
<span className={styles.gradient}>hyper-personalized astrology,</span>{" "}
anyway?
</Title>
<p className={styles.text}>
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!
</p>
<Title variant="h2" className={styles.title}>
So how does it work?
</Title>
<p className={styles.text}>
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. Were going to change your relationship
with astrology.
</p>
<MainButton className={styles.button} onClick={handleNext}>
Next
</MainButton>
</section>
);
}
export default HyperPersonalizedAstrologyPage;

View File

@ -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;
}

View File

@ -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<NodeJS.Timeout>();
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 (
<section className={`${styles.page} page`}>
<div>
<Title variant="h1" className={styles.title}>
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!
</Title>
<p className={styles.text}>*as of 24 February 2023</p>
</div>
{/* <LoadingCircle value={loadingProgress} /> */}
<div style={{ width: 185, height: 185 }}>
<CircularProgressbar
counterClockwise={true}
styles={{
path: { stroke: "#fff" },
trail: { stroke: "#6a3aa2" },
text: { fill: "#fff", fontSize: "16px" },
}}
maxValue={100}
minValue={0}
value={loadingProgress}
text={`${100 - loadingProgress}%`}
strokeWidth={6}
/>
</div>
<p className={styles["loading-text"]}>Connecting database...</p>
</section>
);
}
export default LoadingInRelationshipPage;

View File

@ -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;
}

View File

@ -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 (
<section className={`${styles.page} page`}>
<img src="/starry-clock.svg" alt="The clock" />
<div>
<Title variant="h1" className={styles.title}>
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."}
</Title>
<p className={styles.text}>
Tip: If you find out later, you can adjust this in your
{affiliation === "self" && " profile settings."}
{affiliation === "partner" && " partners profile."}
</p>
</div>
<div className={styles["buttons-container"]}>
<MainButton
className={`${styles.button} ${styles["back-button"]}`}
onClick={handleBack}
>
Back
</MainButton>
<MainButton
className={`${styles.button} ${styles["next-button"]}`}
onClick={handleNext}
>
Next
</MainButton>
</div>
</section>
);
}
export default NoBirthtimePage;

View File

@ -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;
}

View File

@ -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 (
<div className={styles.container}>
<PlacePicker
value={birthPlace}
name="birthPlace"
maxLength={1000}
onChange={handleChange}
/>
{!!birthPlace.length && (
<MainButton className={styles.button} onClick={handleNext}>
{t("next")}
</MainButton>
)}
</div>
);
}
export default BirthPlaceCustomAnswer;

View File

@ -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;
}

View File

@ -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 (
<div className={styles.container}>
<DatePicker
name="birthdate"
value={birthdate}
onValid={handleValid}
onInvalid={() => setIsDisabled(true)}
inputClassName="date-picker-input"
/>
<MainButton
className={styles.button}
onClick={handleNext}
disabled={isDisabled}
>
{t("next")}
</MainButton>
</div>
);
}
export default BirthdateCustomAnswer;

View File

@ -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;
}

View File

@ -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 (
<div className={styles.container}>
<TimePicker value={birthtime} onChange={handleChange} />
<MainButton className={styles.button} onClick={handleNext}>
{t("next")}
</MainButton>
</div>
);
}
export default BirthtimeCustomAnswer;

View File

@ -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;
}

View File

@ -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<number>();
const [currentQuestion, setCurrentQuestion] = useState<IQuestion>();
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 (
<section
className={`${styles.page} page`}
style={{
backgroundImage: `url(${currentQuestion?.backgroundImage || ""})`,
}}
>
{currentQuestion && (!!currentStep || currentStep === 0) && (
<>
<Stepper
steps={steps}
currentStep={currentStep}
currentQuestion={getIndexOfQuestion(currentQuestion.id)}
/>
<span className={styles["current-step"]}>
{steps[currentStep].label}
</span>
<Title className={styles.title} variant="h1">
{currentQuestion.question}
</Title>
{!!currentQuestion.description && (
<p className={styles.description}>{currentQuestion.description}</p>
)}
<div className={styles["answers-container"]}>
{!currentQuestion.answersElement &&
currentQuestion.answers &&
currentQuestion.answers.map((answer) => {
if (!isShowAnswer(answer)) return null;
return (
<Answer
key={answer.id}
answer={answer}
onClick={() => {
answerClickHandler(answer);
}}
/>
);
})}
{!!currentQuestion.answersElement && currentQuestion.answersElement}
</div>
</>
)}
</section>
);
}
export default QuestionnairePage;

View File

@ -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);
}

View File

@ -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 (
<section className={`${styles.page} page`}>
<img src="/magnifier.svg" alt="The magnifier" />
<div>
<Title variant="h1" className={styles.title}>
Almost there! Now let's begin tailoring your plan by understanding
your{" "}
<span className={styles.purple}>
Relationship & Personality Patterns
</span>
.
</Title>
<p className={styles.text}>
Please take your time when answering. Each response is used to craft
the guidance plan for you and your partner.
</p>
</div>
<div className={styles["buttons-container"]}>
<MainButton
className={`${styles.button} ${styles["back-button"]}`}
onClick={handleBack}
>
Back
</MainButton>
<MainButton
className={`${styles.button} ${styles["next-button"]}`}
onClick={handleNext}
>
Next
</MainButton>
</div>
</section>
);
}
export default RelationshipAlmostTherePage;

View File

@ -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;
}

View File

@ -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 (
<section className={`${styles.page} page`}>
<img src="/starry_key.svg" alt="The starry key" />
<div>
{relationshipProblem === "very_unhappy" && (
<Title variant="h1" className={styles.title}>
Weve got you covered! Well start with small, personalized insights
into you and your partners personality traits.
</Title>
)}
{relationshipProblem === "unhappy" && (
<Title variant="h1" className={styles.title}>
Youre probably doing better than you think! Well help you identify
how to improve and stick with it.
</Title>
)}
{relationshipProblem === "happy" && (
<Title variant="h1" className={styles.title}>
Wonderful!
<br /> Let's find out what's working (and what isnt) and go from
there.
</Title>
)}
<p className={styles.text}>
Now, we need some information about{" "}
<span className={styles.blue}>Your Partners Profile</span> to create
the astrological synastry blueprint between you and your partner.
</p>
</div>
<div className={styles["buttons-container"]}>
<MainButton
className={`${styles.button} ${styles["back-button"]}`}
onClick={handleBack}
>
Back
</MainButton>
<MainButton
className={`${styles.button} ${styles["next-button"]}`}
onClick={handleNext}
>
Next
</MainButton>
</div>
</section>
);
}
export default WorksForUsPage;

View File

@ -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;
}

View File

@ -1,16 +0,0 @@
import { IPredictionMoon } from "./components/PredictionMoonsSlider";
export const predictionMoonsPeriods: IPredictionMoon[] = [
{
period: "today",
},
{
period: "week",
},
{
period: "month",
},
{
period: "year",
},
];

656
src/data.tsx Normal file
View File

@ -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: "Whats 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: <BirthdateCustomAnswer />,
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: <BirthtimeCustomAnswer />,
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: <BirthPlaceCustomAnswer />,
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:
"Im very unhappy with how things are going in my relationship",
icon: "/slightly_frowning_face.png",
},
{
id: "unhappy",
answer:
"Im unhappy with parts of my relationship, but some things are working well",
icon: "/neutral_face.png",
},
{
id: "happy",
answer: "Im generally happy in my relationship",
icon: "/slightly_smiling_face.png",
},
],
},
],
},
{
id: "partnerProfile",
label: "Your partner`s profile",
color: "#56ccf2",
questions: [
{
id: "partnerGender",
question: "Whats your partners gender?",
answers: [
{
id: "male",
answer: "Male",
icon: "/man.png",
},
{
id: "female",
answer: "Female",
icon: "/woman.png",
},
],
},
{
id: "partnerBirthdate",
question: "Whats your partners date of birth?",
answersElement: <BirthdateCustomAnswer affiliation="partner" />,
backgroundImage: "/date_of_birth_zodiac_signs.webp",
},
{
id: "partnerIsBirthTime",
question: "Do you know your partners 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: <BirthtimeCustomAnswer affiliation="partner" />,
backgroundImage: "/small_alarm_clock.webp",
},
{
id: "partnerBirthPlace",
question: "Where was your partner born?",
description:
"If you dont know the exact place of birth just type in the country of birth.",
answersElement: <BirthPlaceCustomAnswer affiliation="partner" />,
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 dont 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. Ive struggled before, but Im hopeful.",
icon: "/unamused.png",
},
{
id: "feeling",
answer: "Im feeling a little anxious, honestly.",
icon: "/anxious_face_with_sweat.png",
},
{
id: "not_shure",
answer: "Not sure / Dont 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",
},
],
},
],
},
];

View File

@ -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();

View File

@ -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<typeof reducer>;

View File

@ -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<Partial<IQuestionnaire>>) {
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;

View File

@ -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',