Compare commits
1274 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b2bffb3b83 | |||
| dd1a2953da | |||
| ef784dc6ed | |||
| 682745c321 | |||
| c63fbfc147 | |||
| 9b0f847bc1 | |||
| c073be1ce6 | |||
| f43e10a75f | |||
| eb41751628 | |||
| fa7a0bd1da | |||
| 52ff30581f | |||
| 858bd7c0f7 | |||
| b995c36a8e | |||
| 2363bc3fd7 | |||
| ca375c4bae | |||
| 3e6e3d3910 | |||
| 747abfc47b | |||
| 520e74308d | |||
| 36c7fdd30d | |||
| 85269b9e56 | |||
| 95a918e01d | |||
| 3267414454 | |||
| 85607d81b8 | |||
| 5a1ea91b77 | |||
| 40b5e92047 | |||
| bc867ee8aa | |||
| 7c430d03bd | |||
| 9125990d70 | |||
| e64728e127 | |||
| d82b454caf | |||
| db423a3f1e | |||
| 4376938217 | |||
| 0411ab82f0 | |||
| c7d5d5533c | |||
| 3f7c673087 | |||
| da389c937e | |||
| c71d901556 | |||
| 804f76100a | |||
| 64f6e55fb6 | |||
| 16119dc332 | |||
| ae08f392ca | |||
| b646f020a5 | |||
| 31b411dcab | |||
| 48d66d263e | |||
| 2a6900f6a9 | |||
| 8b3e1e8923 | |||
| c87657eaef | |||
| 9cccd72512 | |||
| 146e8b383e | |||
| 7bb78772f7 | |||
| 094ba4fde8 | |||
| d31005c1ce | |||
| 3992ab696c | |||
| f1ed5f3a95 | |||
| 65b4c59129 | |||
| d620728651 | |||
| 4499f2d356 | |||
| fa00555a6f | |||
| 00fcb275f1 | |||
| c987ba63ff | |||
| 89797cdb3f | |||
| c719c15b2b | |||
| f3b1c229ea | |||
| 0335edf1dc | |||
| f7db65d527 | |||
| 27dc4090fb | |||
| 7f631190dc | |||
| 6815eea66c | |||
| c8e2ae9efb | |||
| 455248f9db | |||
| fee3376a88 | |||
| 956abc8411 | |||
| 64f3625990 | |||
| 9ec8855ed6 | |||
| 06450808ed | |||
| 7eecd34a5e | |||
| ab3693fc0b | |||
| e1879222b3 | |||
| 22250da988 | |||
| 7e8704d633 | |||
| 99d9a468f6 | |||
| 2ca1c668f5 | |||
| 0bb9528690 | |||
| 78a9c4bf5f | |||
| 0440b36f24 | |||
| de56fb601a | |||
| f286960bed | |||
| a8a090c671 | |||
| 24e2a905d2 | |||
| 19c2500263 | |||
| 909c74b734 | |||
| 0ea988fcea | |||
| 8be4ee52f1 | |||
| db5eb85794 | |||
| fb6a2767bc | |||
| c48ae540cc | |||
| c51693deb5 | |||
| b28d02b2f5 | |||
| 74b395d99e | |||
| 21a2754fc9 | |||
| 19282ad15a | |||
| f48b72b149 | |||
| 72d4af20aa | |||
| e6f5746692 | |||
| d0e7f58d5f | |||
| f4e21cb73e | |||
| 6ad8ed34f5 | |||
| b4bbe03bdd | |||
| 2c54aa36f8 | |||
| 00c83b357f | |||
| 0b7ec73409 | |||
| f58e8834fb | |||
| 1a829789d4 | |||
| 84dccfca50 | |||
| 49e3fc5810 | |||
| e4b6391ed2 | |||
| 3abbdd32eb | |||
| e4a5c2682e | |||
| 21abc93a04 | |||
| d51bbdbc29 | |||
| d081dd73d6 | |||
| 9b9e10efbb | |||
| 07040832d7 | |||
| f928f45615 | |||
| 1b0f6c0b89 | |||
| 8315e226dd | |||
| 13da84099c | |||
| 3b6f2a4ca0 | |||
| bdc67590d1 | |||
| 89d2682eaf | |||
| 41a617a265 | |||
| c72765b38c | |||
| fe3306cb98 | |||
| 13b96a3b8d | |||
| f4c0c5bf15 | |||
| bc2a4340f2 | |||
| a4b85e9c85 | |||
| 6dab5412c7 | |||
| 1bd6064b52 | |||
| 4949bd28aa | |||
| f1ef5e163d | |||
| 2f6f0bf501 | |||
| ddf361b496 | |||
| 9f8b61175e | |||
| 0e850b2222 | |||
| ad1c27a9ef | |||
| 1f97780398 | |||
| 5a97e9a185 | |||
| 7eb26ce88a | |||
| 3876e1440d | |||
| df1a006f13 | |||
| 77ab969f61 | |||
| 6da9b9158d | |||
| 5088561e13 | |||
| 6dd870bb05 | |||
| e5c511bd8f | |||
| ead1be773f | |||
| 2d6c189f57 | |||
| 841dfee7e6 | |||
| 8ac8808348 | |||
| f57f443b1e | |||
| 0f770474af | |||
| 8668c39c6f | |||
| 840abb4dcc | |||
| 9da4ed2282 | |||
| 713c333e96 | |||
| 3b27db4ffe | |||
| 8db2316a30 | |||
| a1072c58c0 | |||
| 5b9c564f96 | |||
| c14d8b0659 | |||
| 43f59e8e84 | |||
| ca53101b55 | |||
| f3b8190418 | |||
| 6a37da92f0 | |||
| 3d382695cd | |||
| 9b0ff4a1e6 | |||
| 7231d97492 | |||
| f880afabb0 | |||
| e9d9dd2395 | |||
| a9c273aa17 | |||
| dddd314412 | |||
| 43f0039d29 | |||
| c9a475b525 | |||
| 74b2a554f1 | |||
| d2a406563a | |||
| d509fb024c | |||
| 4acae3401d | |||
| 05a1dc3663 | |||
| 63eb8b9729 | |||
| a474d42d85 | |||
| dcb820590d | |||
| 614c376c92 | |||
| b589277678 | |||
| 00a70f3574 | |||
| 7859cffd49 | |||
| 3a574d1fd0 | |||
| 7c6a2316a8 | |||
| ef99a8f1f7 | |||
| ba0aac126c | |||
| 05453661ee | |||
| aee1b9e3bb | |||
| 9a0dc0d01a | |||
| a467626fae | |||
| 47932d7301 | |||
| de4de35611 | |||
| b3c2785a4b | |||
| 2719b8426d | |||
| fed2358a45 | |||
| ff129480a5 | |||
| 8cf0c8da89 | |||
| 6aaf682d38 | |||
| 9f77a01bb2 | |||
| 9d79e1c709 | |||
| 78ac5d5b24 | |||
| 75657350a3 | |||
| 171f99d997 | |||
| 25c7cd75c7 | |||
| fd68800b00 | |||
| 33f1515d2c | |||
| 2cc30d6c47 | |||
| cfadb42811 | |||
| 1bb2eb3203 | |||
| cd68861dfa | |||
| 9fb0a65e46 | |||
| 15fce205a6 | |||
| dddf6af401 | |||
| 1a86361fbb | |||
| 4f69786f19 | |||
| 5634c1542b | |||
| f9e3d2aad2 | |||
| 921d1af7f0 | |||
| c98d2e41ef | |||
| ea260fa15a | |||
| b604e0b527 | |||
| 991571b2d2 | |||
| 1f98a3eacb | |||
| 031a2f6680 | |||
| bf22570857 | |||
| 89aa5e0aef | |||
| 680833d5be | |||
| 1e0af67542 | |||
| 406af95861 | |||
| 14f69d4c3b | |||
| 24f915ee55 | |||
| 5da67c4c06 | |||
| a21eaa40f2 | |||
| a00e40dbe9 | |||
| fa51914987 | |||
| c8d40c1630 | |||
| f673fe99ef | |||
| 8d5d0672cc | |||
| 09def50875 | |||
| d6920b320c | |||
| cbfaf1e073 | |||
| 3d59b36850 | |||
| f1d659b273 | |||
| ad49489377 | |||
| 386fc8cb0c | |||
| 0045a791fe | |||
| b48cb48213 | |||
| 856c70628a | |||
| fa40f8f725 | |||
| 8c475a56bb | |||
| 7ca8c23479 | |||
| 688592e1a3 | |||
| d12b949bcc | |||
| 3a219a20bb | |||
| e6bc184747 | |||
| 2a3edcf3be | |||
| a1d96488bf | |||
| 3f17920bd0 | |||
| 4014a84e1a | |||
| 60ed9e7bcf | |||
| 479ea408f6 | |||
| 9ca4ba3199 | |||
| e5fa6544a5 | |||
| f55b7186b9 | |||
| 05515333ba | |||
| 7212ab6cfc | |||
| 020154d51a | |||
| e4aadfb627 | |||
| 6a79c3e56f | |||
| 81707c7bd8 | |||
| e5b36e3f45 | |||
| 6f2fc17090 | |||
| e6392bc433 | |||
| f8e14fe6a0 | |||
| 91a42cfe9d | |||
| 3128a77b46 | |||
| d7d67e4763 | |||
| 388e49467e | |||
| 043718837d | |||
| d0e2ba0aa3 | |||
| a1dc72e5b0 | |||
| 2ab1c960c7 | |||
| 25734882cb | |||
| ae31962cd7 | |||
| 96d775d0ba | |||
| bcd45edb2f | |||
| a5631b6291 | |||
| 2fff427346 | |||
| 6ef445958c | |||
| 66660d98f9 | |||
| 359344772e | |||
| 1533465f8d | |||
| 66b1ff5f92 | |||
| c141ab1ef2 | |||
| 8a7b56068d | |||
| bb5a966249 | |||
| 199dec01fe | |||
| 3775c520ff | |||
| bf19dfe86a | |||
| 4b7c3beb53 | |||
| f032ed21b5 | |||
| cab461bd2e | |||
| a4307310ad | |||
| dda3207573 | |||
| 0dd7e5cd19 | |||
| caaff883f1 | |||
| f4ea8d9197 | |||
| df136b3b30 | |||
| c04b909489 | |||
| 4c208e8a58 | |||
| d5017db2ba | |||
| 78ebed6e55 | |||
| f0c016deb8 | |||
| 4a0cfa03a5 | |||
| 36d8c70fd9 | |||
| 23443a4677 | |||
| 16e5656422 | |||
| 0e42668285 | |||
| 66bd8cf6ec | |||
| 3d7ad25517 | |||
| 2d5c828089 | |||
| e39a8358f7 | |||
| e9c57550a2 | |||
| 27f87ee92d | |||
| edf23352ef | |||
| 002e2fead4 | |||
| 160c302417 | |||
| 44ae966cc1 | |||
| f3b977c624 | |||
| 0c99e416ea | |||
| fd531d7d10 | |||
| ac027a3228 | |||
| 001492eeb5 | |||
| 72fe2cad5f | |||
| eac693eba6 | |||
| d3b1462fe3 | |||
| 748546641d | |||
| 48a50fd47c | |||
| e87cb95b43 | |||
| 7638d68a7d | |||
| 3541363f9f | |||
| 30ce6a7d6e | |||
| 115366672a | |||
| 3cd8b6e574 | |||
| 9850cdd392 | |||
| 6d98141c39 | |||
| 5fe5ccbd4d | |||
| 76c0994eb0 | |||
| a1bc6db381 | |||
| 6f5d72e033 | |||
| 762de4c23e | |||
| 2a8b7ba6ec | |||
| 50e44dab43 | |||
| 7649a90c47 | |||
| 3c2c46e293 | |||
| 8dc634d900 | |||
| 3a9cb4667e | |||
| 5f4b032f68 | |||
| 8ab3e9ae50 | |||
| 01b5fba75b | |||
| 66b8c96592 | |||
| 616352e1ac | |||
| acc4417835 | |||
| 7da693f298 | |||
| b0423c665c | |||
| 7089b8f14b | |||
| 2c2e2b0ca5 | |||
| ba3dd91d81 | |||
| 3f04c9f9f8 | |||
| 781f5cc5a6 | |||
| 58097d8b57 | |||
| 630ccefa51 | |||
| ed9f2dec0e | |||
| d2ed29c6a6 | |||
| 4e81156d72 | |||
| e402c02c1f | |||
| 5907b5d872 | |||
| 042cc4110c | |||
| 944fd134f6 | |||
| 5e6b208513 | |||
| 762601a5c3 | |||
| 1e28a0e15b | |||
| a910ab177f | |||
| 4e741f587c | |||
| f779529cc6 | |||
| 44cedf2f65 | |||
| fbcba191b0 | |||
| c64d372193 | |||
| abff42e0a8 | |||
| d5c342a57a | |||
| 60d6629526 | |||
| b1fbf89f10 | |||
| ae346d5ac5 | |||
| 75b5102766 | |||
| 9b12ffe0cd | |||
| 408165e718 | |||
| f7a0594447 | |||
| c733b006fb | |||
| 5a6b60578e | |||
| cdd998235e | |||
| 6e9efd7f43 | |||
| 07e9520774 | |||
| c1600a2a13 | |||
| 58e1745ac5 | |||
| 35db4fe536 | |||
| dfdbf404a5 | |||
| 985afa3c7b | |||
| 70d82d89b3 | |||
| 7f5eccb3b7 | |||
| 6729b780bd | |||
| 06224f121a | |||
| dc91649114 | |||
| 22f6eb436d | |||
| f2ab0cd6c9 | |||
| a2819786ae | |||
| 6cd92f6372 | |||
| 7173901c9b | |||
| 380d014964 | |||
| 9032b36b13 | |||
| f291382786 | |||
| 69dcee859d | |||
| fe295dc775 | |||
| 044c8edf7d | |||
| c22cffd167 | |||
| 6d77bfa1b0 | |||
| 60cc6f375e | |||
| e6684c56fd | |||
| 4f675b30ef | |||
| 00c7f65092 | |||
| 9a978b1913 | |||
| 23f8346734 | |||
| 585632c1e1 | |||
| 11ee1195c2 | |||
| c44f456cc1 | |||
| b769e4a4ba | |||
| a6ff06e2b4 | |||
| 0f801b2408 | |||
| c26f2b725a | |||
| ee94cbc92c | |||
| dccbe76c5b | |||
| 735d13b440 | |||
| 7f83cd5cc6 | |||
| 71ee75072d | |||
| 265f2b7655 | |||
| 4d264fa18e | |||
| cd6ab8b504 | |||
| 8c81073443 | |||
| 14566de037 | |||
| 69d711eddc | |||
| 159623eb69 | |||
| da26d5c24a | |||
| 40850b7342 | |||
| 28098169b9 | |||
| 2ff6ed777f | |||
| 723a2a09ab | |||
| 68482c7956 | |||
| 225e3ae34c | |||
| 251d5abf10 | |||
| 22314a61c5 | |||
| a9cf3c9d22 | |||
| 01bf8a4c52 | |||
| 68ab094bf6 | |||
| d938202f7a | |||
| c9f66bdacb | |||
| 5854ad194a | |||
| 0f25a92b88 | |||
| 9d7bcd91f4 | |||
| 68115e79fa | |||
| de379c2bbc | |||
| 2c11a0755d | |||
| f4ed892c5c | |||
| 30403f27c5 | |||
| cf2df7529d | |||
| b3695324b3 | |||
| cf8f32ed64 | |||
| bd59f26146 | |||
| 3a397aad86 | |||
| 0f548e216d | |||
| 50fd9711e0 | |||
| f4d9eb65c6 | |||
| 774224ba6d | |||
| 9eae733755 | |||
| 0aee3b9d6f | |||
| b676a2a4f3 | |||
| 0baacb3057 | |||
| 9737c02d45 | |||
| 1048e51ddf | |||
| 6545c32326 | |||
| 6ea9078848 | |||
| 735cc0b296 | |||
| 29e058828b | |||
| 5d5542c221 | |||
| b59f92c89f | |||
| e01bfa369b | |||
| 3d150f7a6b | |||
| bbd100d04e | |||
| fcb340007c | |||
| 95a10cf795 | |||
| 5b5a083987 | |||
| 1564f29a4c | |||
| 2b73191741 | |||
| fee5c20fe2 | |||
| 2d2b184291 | |||
| 5abd3665d1 | |||
| a603a9eaff | |||
| 5bd74b3ca4 | |||
| 60cc290004 | |||
| 12f30ec1e8 | |||
| 2521fbc1d8 | |||
| 29812e9265 | |||
| 271180932c | |||
| 0a2e291013 | |||
| 8be09a9f9f | |||
| 78aa4fe58b | |||
| 154ea29504 | |||
| 4f670fa3ba | |||
| 8d48435705 | |||
| 76109dc458 | |||
| 05a7b3ec12 | |||
| 0a3805ddf8 | |||
| 059fdaf294 | |||
| 353c372284 | |||
| 26e5248a0f | |||
| ae6a677b25 | |||
| cab5debfb7 | |||
| c4c1bf6ca1 | |||
| fc2a78dde7 | |||
| 1249685c41 | |||
| 3c422d9036 | |||
| 264511dfb2 | |||
| d8c5b3ff07 | |||
| 624f97df8d | |||
| 4dfb442a80 | |||
| 50f675e82b | |||
| a0584a26fe | |||
| 0d3025c4d0 | |||
| ed24fea513 | |||
| e6d83be4d9 | |||
| 36e3154933 | |||
| 5d59ff1b30 | |||
| 33832fdd96 | |||
| 9f02395214 | |||
| 9cc88eebf6 | |||
| 2390670d8c | |||
| d908b1e10e | |||
| d91a3bf9f0 | |||
| 880c223834 | |||
| e7bf07d09e | |||
| e1de701ea6 | |||
| 3403210fe8 | |||
| 03a897829c | |||
| d884b2a43d | |||
| 3b86c6cd0e | |||
| 2b5de9c95f | |||
| 3a8a980660 | |||
| 06186b3c0f | |||
| bddbe6ceb4 | |||
| dd802ab22e | |||
| 8c363765ae | |||
| f597c207fa | |||
| dc07cff959 | |||
| 38766c9cb7 | |||
| fc04855d3f | |||
| 56cb956482 | |||
| 2f5abc8931 | |||
| 026dbb1a0a | |||
| efd464ba8a | |||
| 8c400c7ce1 | |||
| d3d2b3cb5a | |||
| 3054a5eb9a | |||
| 670f4bbf1a | |||
| ae73f10c42 | |||
| de477f32ed | |||
| 2c6e36aea9 | |||
| dc3aa1470e | |||
| 9029953432 | |||
| fa47de7292 | |||
| d0a2b804b9 | |||
| aa48529dca | |||
| ad2745dfce | |||
| b6ab3a6ee7 | |||
| f968cc5a50 | |||
| 1ddb2fd903 | |||
| 70f6ac4e24 | |||
| 3d30481852 | |||
| 63c0b07f61 | |||
| 60568c42e8 | |||
| 77ac52820d | |||
| 240e075305 | |||
| bea41d8181 | |||
| 6268d68b67 | |||
| f96b16b373 | |||
| 9fb6a4db86 | |||
| 1aa3c79666 | |||
| ecc2360dc4 | |||
| ca9bb1c211 | |||
| 2f756d189a | |||
| d7acea769c | |||
| 7ff5e2b6e0 | |||
| 2f90c4a6c2 | |||
| 29e0345e1c | |||
| 129cdc8cba | |||
| 9d42ebebab | |||
| 6193f0b492 | |||
| 1d86465812 | |||
| 7a6f43ad20 | |||
| 37b94a68ca | |||
| a1b63c5d0c | |||
| e5162a2aaf | |||
| 6ee9c7e7d8 | |||
| 5928ddb3c1 | |||
| 06c1e339b1 | |||
| 29cec58122 | |||
| d258158a13 | |||
| 1c47fa283a | |||
| d1b07e6e66 | |||
| 648f228e45 | |||
| 551a302ede | |||
| 108c82b2f8 | |||
| f46713ef00 | |||
| 992993b710 | |||
| 617df4200e | |||
| a47e398e87 | |||
| 281c4c7ab7 | |||
| 3c901e5d0d | |||
| 3bcbaae4c3 | |||
| 17e972d603 | |||
| dbc821a804 | |||
| 0e4b1af1ce | |||
| ec88f304ab | |||
| 8d795a29b4 | |||
| da12f5905c | |||
| 99d4301588 | |||
| 8139fbb090 | |||
| 926837c656 | |||
| 14c894da6c | |||
| dbdc028ed4 | |||
| c3a5a2fe34 | |||
| eed2e62f62 | |||
| 824f46fd9f | |||
| ff5a73bec7 | |||
| ad37885445 | |||
| 0c3425a97a | |||
| 92ca50e02f | |||
| 4eed8abac1 | |||
| a6627555d9 | |||
| e127c79df2 | |||
| 00278e32b6 | |||
| 255da58588 | |||
| 0464025eff | |||
| c300d0d7f4 | |||
| 47ae14bc7a | |||
| 185ca14750 | |||
| 1ef92207fb | |||
| 0b8cf50088 | |||
| 57be599bb5 | |||
| 9ec512777e | |||
| 9dde87277c | |||
| a176e8e6d5 | |||
| 8106f6a049 | |||
| aa26a63fcf | |||
| 3fbcfe5797 | |||
| 510545bf82 | |||
| 7a149b87bd | |||
| 391f6e0abd | |||
| 057691b2f9 | |||
| d085636843 | |||
| 0150caf4bb | |||
| dd580cadfd | |||
| a59588d4a7 | |||
| 393b4e7b37 | |||
| b2411285bc | |||
| 091faec9bd | |||
| 15fc2e6c9b | |||
| 3ef68adf7e | |||
| 71f987cbff | |||
| e8c3dca731 | |||
| 85d15ac2f1 | |||
| 236dfeae2c | |||
| 734acd9dd5 | |||
| 3f9534b968 | |||
| 13d69efbaf | |||
| 151aa4ba0c | |||
| 4985256c3a | |||
| 5c552fe006 | |||
| b14272f040 | |||
| 5e4887c01c | |||
| f6e55718bb | |||
| 98ddc5aaae | |||
| 53d8b0f411 | |||
| b3d33f87cf | |||
| 5922064c42 | |||
| eae8dc43ec | |||
| 34e6322126 | |||
| b3db82000b | |||
| fa565437f0 | |||
| 59f407ba26 | |||
| e7afc12334 | |||
| 5f81c0b847 | |||
| 0756747143 | |||
| 99eb1591a2 | |||
| 85b9aab229 | |||
| 67a0a34288 | |||
| 814e4c9693 | |||
| e74eb38caf | |||
| 67db1a72bf | |||
| 41e46d8030 | |||
| 8707411dda | |||
| 327a4a42ae | |||
| 455f4001f7 | |||
| 775bcd5005 | |||
| 492bda021f | |||
| eacfae19f0 | |||
| 376cf44a9c | |||
| 1aab0c2910 | |||
| 1f5fb8c7c3 | |||
| a303b24b53 | |||
| 322927045c | |||
| 3cf1dc7166 | |||
| 8ed331e909 | |||
| 2428923f73 | |||
| 139f87c919 | |||
| c24fbedf2c | |||
| 1a817e723e | |||
| c023911cd4 | |||
| 907dc298ab | |||
| 8095006386 | |||
| d9d28791da | |||
| a98d967ba4 | |||
| 59a5e84ee2 | |||
| 35ed1d48a3 | |||
| f9d385dfec | |||
| 033af03221 | |||
| b3afb94030 | |||
| 0b1aa4e7d9 | |||
| 18c4f31322 | |||
| 97e3344953 | |||
| 9565ca0d35 | |||
| 51cc4edc1d | |||
| d12a1fd579 | |||
| 21f1173e66 | |||
| cf5ae81918 | |||
| 235bb7d667 | |||
| 18a319a437 | |||
| d3e2cc6744 | |||
| a08d8feb7d | |||
| 7cb5cc558b | |||
| 36025ade56 | |||
| b80c21358a | |||
| f5ad68f7bb | |||
| 27cba1ac68 | |||
| dbb21d8a08 | |||
| a4597599b7 | |||
| 894f986574 | |||
| e42a358da6 | |||
| 23c2e840c2 | |||
| 7e7176ae5c | |||
| 306fa1300d | |||
| 7b3178bd1a | |||
| 5e94ddee48 | |||
| 32171ae3ce | |||
| 2c99fedd8c | |||
| 7e926cc7bc | |||
| 587bcaa411 | |||
| 756628ee1a | |||
| 575710a807 | |||
| c77d8e5693 | |||
| 7e9d734e6f | |||
| 9ddb127bd3 | |||
| a85e5fdb91 | |||
| 09ad8a94ca | |||
| 0c1db6b4b5 | |||
| 6ddffdf2e6 | |||
| 5043540abb | |||
| 5f39accdd6 | |||
| b5aeaf59a4 | |||
| f3e63d2ef6 | |||
| 44a055e76b | |||
| 67c1b2aaa0 | |||
| 313cfc1f28 | |||
| 59a7f110be | |||
| 52e8447f6a | |||
| c60e28928a | |||
| 58357fd501 | |||
| 5402980d6c | |||
| 32c7b3d513 | |||
| a30b22170d | |||
| e3314b0460 | |||
| 86eb1f16bb | |||
| 5660d74e75 | |||
| 612016784d | |||
| 988aadfb7e | |||
| 54851b5f77 | |||
| 91f3b92138 | |||
| f48de9d65f | |||
| c920c35a9c | |||
| 7bcaead120 | |||
| 828f56ed84 | |||
| 07118c10a8 | |||
| ca5923a7f8 | |||
| 4f0d432176 | |||
| dd3f9d99f3 | |||
| 8807b671ad | |||
| 7020e6d4dc | |||
| d66093a2ad | |||
| b79eb6b158 | |||
| a759daaf90 | |||
| 600aec62cf | |||
| 1612bf11ce | |||
| f4e261eb6c | |||
| b622398b6a | |||
| e60957e6be | |||
| 6a2082d732 | |||
| 452c6bf8a1 | |||
| 9f89376aa9 | |||
| 4e91e47978 | |||
| fcaa485b17 | |||
| e4526652d3 | |||
| 64056bb2a4 | |||
| e49c4d66f8 | |||
| 8fdb939b72 | |||
| 79325450f3 | |||
| 7849a027b4 | |||
| 38432a6d50 | |||
| 83a54ff3ef | |||
| 5e0fdffa1e | |||
| 11d2cb3e3a | |||
| 93ac55b44b | |||
| 237ce13a6c | |||
| 4253174494 | |||
| da0ed0364b | |||
| 466175c49d | |||
| ed148ce267 | |||
| 6de795c07b | |||
| 436498bef9 | |||
| 086b1202a4 | |||
| a81ccdc4d7 | |||
| 33abbbcd2b | |||
| 04844af733 | |||
| 46d919090d | |||
| 8e67892f16 | |||
| a67d2b7bb4 | |||
| 99c0c24489 | |||
| 1a1d59a8c7 | |||
| 31dcfcfd0b | |||
| e9aa58f2f5 | |||
| 55fe2bf6d2 | |||
| 738eb1589e | |||
| 139e0c2827 | |||
| 30642bba14 | |||
| f5921612b8 | |||
| 38afece043 | |||
| d44447c6b3 | |||
| d942c6641a | |||
| beed565ba0 | |||
| 329e27b83d | |||
| 3145656d80 | |||
| 5098a45bd5 | |||
| 9e65a6e7d5 | |||
| 83ac1087f3 | |||
| 55b2bccdf0 | |||
| 0c51474dd2 | |||
| 8c7ffb52a5 | |||
| 6c698bc399 | |||
| 540ad6f9ad | |||
| 11342c32c6 | |||
| 356c11d029 | |||
| 934d95e822 | |||
| 0aa49b49a9 | |||
| be52792271 | |||
| c23e61e06b | |||
| 24b9a0e348 | |||
| fcb154ba49 | |||
| c0065ed569 | |||
| 05a2ebec61 | |||
| 63f7deaa2b | |||
| d762ef42e8 | |||
| 3e34c81789 | |||
| a2340af314 | |||
| 2a445fd2d4 | |||
| b5e52fb34e | |||
| 87512bbc23 | |||
| 1e59059394 | |||
| e59c83d216 | |||
| 395569dab5 | |||
| 25a537c5bc | |||
| 5244a2875e | |||
| 54560b3fec | |||
| 078d26317f | |||
| 8dbf638c7f | |||
| a68af7c3a4 | |||
| 905d48ceb7 | |||
| 1e5dac0104 | |||
| 11e52a02f6 | |||
| 4e74198ae5 | |||
| 5d673a630c | |||
| adcb33764b | |||
| 305bff1167 | |||
| 1ebe9fe12b | |||
| 3fbaf6b78a | |||
| 421a24c185 | |||
| 6386fbcda6 | |||
| 2e09d77597 | |||
| 10dae9193c | |||
| 3f487337f4 | |||
| 7eabee8855 | |||
| 360f0500a9 | |||
| 9b6c5b72ad | |||
| afc5e25cfc | |||
| 58fe5eb82c | |||
| 2f3fdc0695 | |||
| 0a465fceb0 | |||
| 5e968db2f5 | |||
| 1916bc1a65 | |||
| 1103127cae | |||
| 751369071c | |||
| 4cc8f27c14 | |||
| aab455c2c3 | |||
| 21843c4bc7 | |||
| 8702728ffa | |||
| 79dcd0f2b5 | |||
| 47b25f3dfe | |||
| 89925a6af9 | |||
| 3c0f951b6e | |||
| ffbfb1da35 | |||
| a8416a8433 | |||
| 70c9d1778c | |||
| 930559c96b | |||
| c4af2dfcc8 | |||
| b186549b8d | |||
| ab191b6a72 | |||
| d130687cf9 | |||
| 5e9a442eac | |||
| 1093c25207 | |||
| 0623227807 | |||
| 3a05790125 | |||
| 85b0456011 | |||
| 6ddd16ee24 | |||
| d034f9be45 | |||
| 2f3940f99c | |||
| 5e998e5e42 | |||
| e113f40c5c | |||
| 42a3df2d65 | |||
| 3fb996887b | |||
| 6d2794dd2f | |||
| 8e683f12a2 | |||
| 1910ea2bb6 | |||
| 5f6471a16e | |||
| 98a4baddab | |||
| 67f8de325f | |||
| 594d2a4224 | |||
| edd48e72ec | |||
| 47c9e1bb6e | |||
| 2fe80ecbe3 | |||
| 1640f25d9d | |||
| 28f3bbcad1 | |||
| c4eca264b1 | |||
| 89a9e77380 | |||
| 349b524151 | |||
| 084370b641 | |||
| c2a6cff3eb | |||
| d45e533d91 | |||
| c89de2559a | |||
| a5a267927a | |||
| 557e0acba4 | |||
| 3e4dfadb41 | |||
| b480d49096 | |||
| ece7bf41d3 | |||
| 250dd0b171 | |||
| f2475ddd88 | |||
| f302ca80d7 | |||
| 11b96e56da | |||
| daad9d18ec | |||
| 3c842f6606 | |||
| 23ef007bb1 | |||
| a9b9a17381 | |||
| d5e66618aa | |||
| 2e89f07ee2 | |||
| 1a51bcf0b5 | |||
| f1ee5150a9 | |||
| 9db7f5c985 | |||
| d56363276b | |||
| 5a9b49559b | |||
| fbc8228977 | |||
| a1140f7006 | |||
| f3561ff0fb | |||
| 42b792ab9d | |||
| 1e3a166172 | |||
| e1c6cb357e | |||
| 1aa64fba1f | |||
| 4f0a6f67c3 | |||
| 4f863f7b1d | |||
| b66f9d7ced | |||
| 493f209162 | |||
| 0aa109e280 | |||
| b0a287c6a8 | |||
| 8c00b157ad | |||
| 85bbd25bbb | |||
| 4d7e42fba8 | |||
| f91e8e9910 | |||
| 9e9b0b5557 | |||
| bfcfcdbf16 | |||
| 7e99e7ccab | |||
| fd9adb1c08 | |||
| 7f2448efff | |||
| 82ec224d66 | |||
| 35ea200de5 | |||
| 7cdd387045 | |||
| 6b568ff56c | |||
| 8808a2f81c | |||
| 1991bab675 | |||
| f650097db2 | |||
| c427521ac3 | |||
| 2412059fd0 | |||
| 34dc467e8b | |||
| 9fa16278ab | |||
| cae02d1dc6 | |||
| abbd7b3993 | |||
| 5523511524 | |||
| 35db8ca7ec | |||
| 51e0482a16 | |||
| a615e25fcb | |||
| addede388e | |||
| 76474bb3b5 | |||
| 6337c82374 | |||
| a970411719 | |||
| 10967acf9e | |||
| fb6831d44f | |||
| 7dcae39320 | |||
| a0ba60a2bc | |||
| f377326b48 | |||
| feb8bd718d | |||
| a2a2dbfc24 | |||
| 1c0cb6c97f | |||
| 41c9c60fd1 | |||
| ba5646fe2c | |||
| 1f9ab45206 | |||
| 0ffa1123d2 | |||
| 9420a201e4 | |||
| 1b7ea7321e | |||
| b3e273d712 | |||
| 7fa74d6fd3 | |||
| 02c195500a | |||
| ca8e56c6dd | |||
| c265e9db33 | |||
| 2861473ea3 | |||
| a598aa3898 | |||
| 9d190916a8 | |||
| eca9455f0f | |||
| a1bf0bad0f | |||
| e236ad20f7 | |||
| 330f47baa7 | |||
| 5088aa3ead | |||
| 07a443d082 | |||
| 59a370d763 | |||
| 68e709f34b | |||
| b1bb730c7d | |||
| 20a86f4802 | |||
| 2d918517f8 | |||
| a0c0cbdc98 | |||
| ed309007e5 | |||
| 594c072806 | |||
| 4b9289cb8e | |||
| 5b39e75119 | |||
| e61b2c8f43 | |||
| 4c6952c4b3 | |||
| 6a5cebed5b | |||
| 663e3e8bb7 | |||
| aaa5b9e8ff | |||
| 90ec033b34 | |||
| c3c359cfc8 | |||
| 68b4031752 | |||
| 8a2559571f | |||
| ccae5000ee | |||
| 5f01cb14f9 | |||
| 9f62345a2e | |||
| b9096117bc | |||
| f70659901c | |||
| 451e4624b1 | |||
| 1557ba1040 | |||
| 7133ad8de3 | |||
| 9fd8944987 | |||
| 874276dcba | |||
| be1454f1b8 | |||
| 6a34ca6c18 | |||
| fc09771b8d | |||
| cab5ed0ece | |||
| 8d3dca96b4 | |||
| e71a25630d | |||
| cf79a15837 | |||
| 042e8c2c17 | |||
| 46d286e8f3 | |||
| c2bfcc81ea | |||
| 654ed3741c | |||
| 6cccd1c372 | |||
| 1e6be76449 | |||
| 476ca04f5f | |||
| ce41db474d | |||
| 7ace7e5b5d | |||
| 51e829f7b4 | |||
| 173b2adc66 | |||
| 31cb7a521d | |||
| ad4f68b252 | |||
| 10abf35d4f | |||
| ce767086fd | |||
| 0f44616767 | |||
| bce00b5c0e | |||
| 312cd54f87 | |||
| a0c3437eae | |||
| 711226f913 | |||
| f46c6232b0 | |||
| 172f0ccbce | |||
| a2047cc2de | |||
| 6ea52e6481 | |||
| a7bbcfdc1b | |||
| ff28be3e70 | |||
| e91b4a4424 | |||
| 9960033b72 | |||
| ef135f1a9b | |||
| 1df6380c4a | |||
| fc8cf551e5 | |||
| b1feb0438a | |||
| a89649f774 | |||
| b96e8a3ed5 | |||
| f3226a6cfc | |||
| ff4c503100 | |||
| f543a2d893 | |||
| 41badd52be | |||
| eeddd4e0a5 | |||
| ee4d136834 | |||
| 283efa42b3 | |||
| 5cbab4933c | |||
| 4de2181c18 | |||
| c8f0161a29 | |||
| 60222b6d88 | |||
| 9ea3963239 | |||
| a87592623b | |||
| bfcf53f763 | |||
| df4489c6f2 | |||
| 37185812b4 | |||
| eb3e78244d | |||
| b302d7ba57 | |||
| d6c16169d9 | |||
| 57129da0bd | |||
| 9eaf7123d4 | |||
| 096da29149 | |||
| c8331c51cf | |||
| 3b7618702b | |||
| 84968b4435 | |||
| 98f11a3d80 | |||
| 98d734e869 | |||
| 47004fec8c | |||
| 48ce89489e | |||
| 1ce05a3be3 | |||
| 28ab1116e9 | |||
| 994060d929 | |||
| a5c62564b7 | |||
| 22e61d2b41 | |||
| 6ab5eae0c0 | |||
| 3fbb47ee82 | |||
| 3327b2b0df | |||
| ec204d0389 | |||
| cb1259d2c8 | |||
| 706cf141e7 | |||
| 2229ebb9a0 | |||
| 05022c29b2 | |||
| 9718cfc574 | |||
| aef082ac60 | |||
| 754340fcba | |||
| 16afd4f90c | |||
| b69e2ff53b | |||
| 4ac799f8c9 | |||
| c93d3b61a6 | |||
| 4fb6dbf30f | |||
| 11dc8fc659 | |||
| 4876ba80c1 | |||
| 71f799d157 | |||
| 77c538ca79 | |||
| 6b473b5dc6 | |||
| 6aa11793a5 | |||
| e098eb4626 | |||
| 4f8edc3998 | |||
| 7dd805b804 | |||
| 2aa1219ea9 | |||
| c1a17949f7 | |||
| 24302c7435 | |||
| 27f4fda129 | |||
| 7ddef6d52d | |||
| 187ac61396 | |||
| 31297efb5b | |||
| f8d6475ff8 | |||
| 22a45ac15e | |||
| 0489be5e69 | |||
| 0f8ef167bb | |||
| aa6e3f4b94 | |||
| 68beda891b | |||
| 61bef08a24 | |||
| a6409a037f | |||
| f3ab8241a3 | |||
| f3defdca85 | |||
| f3b1a42819 | |||
| e65d538709 | |||
| 98aef302de | |||
| b3bbf11f0a | |||
| 973517215f | |||
| a3782e2dfc | |||
| 25830d5bf3 | |||
| 1615a7ac8a | |||
| 232211a297 | |||
| eda3d76d4c | |||
| 87f1a1e3e8 | |||
| 5257f89acb | |||
| d4cf7419bf | |||
| 1ffb732bfa | |||
| 9007463f6d | |||
| a4b6b9e493 | |||
| ccf820da7c | |||
| 7c51896bbf | |||
| aa80bab930 | |||
| 1704fc60b4 | |||
| c3e6c90c49 | |||
| 1a65b1daa3 | |||
| ba2c009896 | |||
| bc2b71ecda | |||
| 1d315018a4 | |||
| 56f8b75525 | |||
| 59531df377 | |||
| 06a7386211 | |||
| 4bb3a11261 | |||
| f308eeca8d | |||
| 8e562ed1a5 | |||
| 23dd7571a3 | |||
| 8530b2d1a0 | |||
| acdbddbc79 | |||
| 15fc5f4f14 | |||
| 2ba3b01646 | |||
| 4e960a2f53 | |||
| ab700edcf2 | |||
| 42e80c7a11 | |||
| d4472a881a | |||
| 5d12ab4f62 | |||
| 8b3c586456 | |||
| e456b55e16 | |||
| 89c5936212 | |||
| 7bedf76945 | |||
| 54bf020c55 | |||
| 78145eee77 | |||
| d75b6ee26c | |||
| bf5c9d4671 | |||
| d2db38ba21 | |||
| eecbca6b0e | |||
| dd1430a350 | |||
| 0eca0c52ce | |||
| c2c7ad7bb4 | |||
| 98ccbce4c0 | |||
| 6484640e1a | |||
| ba3c4e1918 | |||
| fa4fe35bdf | |||
| fb7913c563 | |||
| feb301c3c0 |
@@ -14,6 +14,10 @@ REACT_APP_APPSITE="https://myfitapp.mermsemr.com"
|
||||
|
||||
REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
||||
REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
||||
REACT_APP_ENDPOINT_KEY="WRENCH-BOARD-2024"
|
||||
|
||||
#SOCKETS ENDS
|
||||
REACT_APP_PRIMARY_SOCKET="https://socket-dev.wrenchboard.com"
|
||||
|
||||
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
|
||||
|
||||
@@ -24,7 +28,6 @@ REACT_APP_SESSION_EXPIRE_CHECKER=60000
|
||||
REACT_APP_LOGIN_ERROR_TIMEOUT=7000
|
||||
REACT_APP_SIGNUP_ERROR_TIMEOUT=7000
|
||||
|
||||
REACT_APP_FLUTTERWAVE_APIKEY=FLWPUBK_TEST-54c90141b028789d671067bd72f781a9-X
|
||||
|
||||
# Had to change the error time to 3sec cause it took too long
|
||||
REACT_APP_RESET_START_ERROR_TIMEOUT=3000
|
||||
@@ -46,7 +49,7 @@ REACT_APP_GOOGLE_REDIRECT_URL=http://localhost:9082/login/auth/
|
||||
REACT_APP_FACEBOOK_CLIENT_ID2=390204307987009
|
||||
REACT_APP_FACEBOOK_CLIENT_SECRET2=19f778e312f2ab96d147bacb612910c2
|
||||
|
||||
#developenet Account
|
||||
#development Account Social
|
||||
REACT_APP_FACEBOOK_CLIENT_ID=677857427521030
|
||||
REACT_APP_FACEBOOK_CLIENT_SECRET=4801375f22072d8a75f64483fdd89829
|
||||
|
||||
@@ -64,10 +67,65 @@ REACT_APP_APPLE_REDIRECT_URL='http://localhost:9082/login/auth/apple'
|
||||
# /* 'client_id' => */ 'com.wrenchboard.users.client',
|
||||
# /* 'client_secret' => */ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6Ilc1V1RXQzlEVEoifQ.eyJpc3MiOiJKUjM2M0ZFWThSIiwiaWF0IjoxNjU0MDgzODQxLCJleHAiOjE2NTkyNjc4NDEsImF1ZCI6Imh0dHBzOi8vYXBwbGVpZC5hcHBsZS5jb20iLCJzdWIiOiJjb20ud3JlbmNoYm9hcmQudXNlcnMuY2xpZW50In0.TIPMwjS2MgSysqEuw3yu1nrOcrH-6omzerDhx0CadjWn2yCO8wZhQiAlhIFs7F-WPektIJ6h-2BT62yGrILiTA',
|
||||
# /* 'redirect_uri' => */ site_url('login/auth/apple')
|
||||
#SOCIALS Links Display
|
||||
REACT_APP_APPLE_SOCIAL_LOGIN=0
|
||||
REACT_APP_LINKEDIN_SOCIAL_LOGIN=0
|
||||
|
||||
REACT_APP_MAX_FILE_SIZE=1000000
|
||||
#File Handling
|
||||
REACT_APP_MAX_FILE_SIZE=1048576
|
||||
REACT_APP_MAX_VIDEO_FILE_SIZE=31457280
|
||||
REACT_APP_TOTAL_NUM_FILE=4
|
||||
|
||||
#Auth Text(s)
|
||||
REACT_APP_LOGOUT_TEXT="Sign Out"
|
||||
|
||||
#apigate.lotus.g1.wrenchboard.com:76.209.103.227
|
||||
#apigate.orion.g1.wrenchboard.com:76.209.103.227
|
||||
|
||||
#Cards Handling
|
||||
REACT_APP_MAX_CREDIT_CARDS=4
|
||||
REACT_APP_MAX_CREDIT_BANK_ACCOUNT=4
|
||||
|
||||
#Family
|
||||
REACT_APP_MAX_FAMILY_MEMBERS=8
|
||||
|
||||
REACT_APP_SHOW_OFFER_GROUP_JOB=0
|
||||
|
||||
#UPLOAD PROFILE PICTURE
|
||||
REACT_APP_SHOW_UPLOAD_PROFILE_PICTURE=0
|
||||
|
||||
#GOOGLE RECAPTCHA SITEKEY
|
||||
REACT_APP_GOOGLE_RECAPTCHA_SITEKEY=6Ld_qKooAAAAADNL1TPzRLmcBA8vlpvx__39Rj39
|
||||
#6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
|
||||
|
||||
#FAMILY MEMBER MINIMUM AGE
|
||||
REACT_APP_FAMILY_MINIMUM_AGE=4
|
||||
REACT_APP_FAMILY_MAXIMUM_AGE=18
|
||||
|
||||
#CHANGE LOGIN LAYOUT
|
||||
REACT_APP_NEW_LOGIN_LAYOUT=1
|
||||
|
||||
#APP DOWNLOAD LINKS
|
||||
REACT_APP_ANDROID_APP='https://play.google.com/store/apps/details?id=com.wrenchboard.users'
|
||||
REACT_APP_APPLE_APP='https://itunes.apple.com/us/app/wrenchboard/id1435718367?ls=1&mt=8'
|
||||
|
||||
# Displays the new family dashboard with boxes
|
||||
REACT_APP_SHOW_NEW_FAMILY_DASH=1
|
||||
|
||||
# Displays the account dashboard
|
||||
REACT_APP_SHOW_ACCOUNT_DASH=1
|
||||
|
||||
# Displays the slider banners
|
||||
REACT_APP_SHOW_SLIDER_BANNERS=0
|
||||
|
||||
# FOR MEDIA LINK
|
||||
REACT_APP_MEDIA_LINK='https://dev-media.wrenchboard.com'
|
||||
|
||||
# FOR FAMILY GAME LINK
|
||||
REACT_APP_FAM_GAME_LINK='https://games.wrenchboard.com'
|
||||
|
||||
# REACT APP CUSTOMTIMER
|
||||
REACT_APP_CUSTOMTIMER=90
|
||||
|
||||
#SHOW OR HIDE MY PAGE LINK ROUTE
|
||||
REACT_APP_SHOW_USER_PAGE=1
|
||||
@@ -14,6 +14,10 @@ REACT_APP_APPSITE="https://myfitapp.mermsemr.com"
|
||||
|
||||
REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
||||
REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
||||
REACT_APP_ENDPOINT_KEY="WRENCH-BOARD-2024"
|
||||
|
||||
#SOCKETS ENDS
|
||||
REACT_APP_PRIMARY_SOCKET="https://socket-dev.wrenchboard.com"
|
||||
|
||||
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
|
||||
|
||||
@@ -24,7 +28,6 @@ REACT_APP_SESSION_EXPIRE_CHECKER=60000
|
||||
REACT_APP_LOGIN_ERROR_TIMEOUT=7000
|
||||
REACT_APP_SIGNUP_ERROR_TIMEOUT=7000
|
||||
|
||||
REACT_APP_FLUTTERWAVE_APIKEY=FLWPUBK_TEST-54c90141b028789d671067bd72f781a9-X
|
||||
|
||||
# Had to change the error time to 3sec cause it took too long
|
||||
REACT_APP_RESET_START_ERROR_TIMEOUT=3000
|
||||
@@ -40,5 +43,58 @@ REACT_APP_GOOGLE_CLIENT_SECRET=aozK_2G8UjaCmLgPPkv9abIm
|
||||
REACT_APP_GOOGLE_CLIENT_SCOPE="https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile"
|
||||
REACT_APP_GOOGLE_REDIRECT_URL=http://localhost:9082/login/auth/
|
||||
|
||||
REACT_APP_MAX_FILE_SIZE=1000000
|
||||
REACT_APP_TOTAL_NUM_FILE=4
|
||||
#File Handling
|
||||
REACT_APP_MAX_FILE_SIZE=1048576
|
||||
REACT_APP_MAX_VIDEO_FILE_SIZE=31457280
|
||||
REACT_APP_TOTAL_NUM_FILE=4
|
||||
|
||||
REACT_APP_LOGOUT_TEXT="Sign Out"
|
||||
|
||||
REACT_APP_APPLE_SOCIAL_LOGIN=0
|
||||
REACT_APP_LINKEDIN_SOCIAL_LOGIN=0
|
||||
|
||||
REACT_APP_MAX_CREDIT_CARDS=4
|
||||
REACT_APP_MAX_CREDIT_BANK_ACCOUNT=4
|
||||
|
||||
REACT_APP_MAX_FAMILY_MEMBERS=8
|
||||
|
||||
REACT_APP_SHOW_OFFER_GROUP_JOB=0
|
||||
|
||||
#UPLOAD PROFILE PICTURE
|
||||
REACT_APP_SHOW_UPLOAD_PROFILE_PICTURE=0
|
||||
|
||||
#GOOGLE RECAPTCHA SITEKEY
|
||||
REACT_APP_GOOGLE_RECAPTCHA_SITEKEY=6Ld_qKooAAAAADNL1TPzRLmcBA8vlpvx__39Rj39
|
||||
#6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
|
||||
|
||||
#FAMILY MEMBER MINIMUM AGE
|
||||
REACT_APP_FAMILY_MINIMUM_AGE=4
|
||||
REACT_APP_FAMILY_MAXIMUM_AGE=18
|
||||
|
||||
#CHANGE LOGIN LAYOUT
|
||||
REACT_APP_NEW_LOGIN_LAYOUT=1
|
||||
|
||||
#APP DOWNLOAD LINKS
|
||||
REACT_APP_ANDROID_APP='https://play.google.com/store/apps/details?id=com.wrenchboard.users'
|
||||
REACT_APP_APPLE_APP='https://itunes.apple.com/us/app/wrenchboard/id1435718367?ls=1&mt=8'
|
||||
|
||||
# Displays the new family dashboard with boxes
|
||||
REACT_APP_SHOW_NEW_FAMILY_DASH=1
|
||||
|
||||
# Displays the account dashboard
|
||||
REACT_APP_SHOW_ACCOUNT_DASH=1
|
||||
|
||||
# Displays the slider banners
|
||||
REACT_APP_SHOW_SLIDER_BANNERS=0
|
||||
|
||||
# FOR MEDIA LINK
|
||||
REACT_APP_MEDIA_LINK='https://dev-media.wrenchboard.com'
|
||||
|
||||
# FOR FAMILY GAME LINK
|
||||
REACT_APP_FAM_GAME_LINK='https://games.wrenchboard.com'
|
||||
|
||||
# REACT APP CUSTOMTIMER
|
||||
REACT_APP_CUSTOMTIMER=90
|
||||
|
||||
#SHOW OR HIDE MY PAGE LINK ROUTE
|
||||
REACT_APP_SHOW_USER_PAGE=1
|
||||
@@ -14,6 +14,10 @@ REACT_APP_APPSITE="https://myfitapp.mermsemr.com"
|
||||
|
||||
REACT_APP_AUX_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api/v1"
|
||||
REACT_APP_USERS_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api/v1"
|
||||
REACT_APP_ENDPOINT_KEY="WRENCH-BOARD-2024"
|
||||
|
||||
#SOCKETS ENDS
|
||||
REACT_APP_PRIMARY_SOCKET="https://socket.wrenchboard.com"
|
||||
|
||||
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
|
||||
|
||||
@@ -24,7 +28,6 @@ REACT_APP_SESSION_EXPIRE_CHECKER=60000
|
||||
REACT_APP_LOGIN_ERROR_TIMEOUT=7000
|
||||
REACT_APP_SIGNUP_ERROR_TIMEOUT=7000
|
||||
|
||||
REACT_APP_FLUTTERWAVE_APIKEY=FLWPUBK_TEST-54c90141b028789d671067bd72f781a9-X
|
||||
|
||||
# Had to change the error time to 3sec cause it took too long
|
||||
REACT_APP_RESET_START_ERROR_TIMEOUT=3000
|
||||
@@ -47,5 +50,57 @@ REACT_APP_FACEBOOK_REDIRECT_URL="https://users.wrenchboard.com/login/auth/flogin
|
||||
|
||||
DISABLE_ESLINT_PLUGIN=true
|
||||
|
||||
REACT_APP_MAX_FILE_SIZE=1000000
|
||||
REACT_APP_TOTAL_NUM_FILE=4
|
||||
#File Handling
|
||||
REACT_APP_MAX_FILE_SIZE=1048576
|
||||
REACT_APP_MAX_VIDEO_FILE_SIZE=31457280
|
||||
REACT_APP_TOTAL_NUM_FILE=4
|
||||
|
||||
REACT_APP_LOGOUT_TEXT="Sign Out"
|
||||
REACT_APP_APPLE_SOCIAL_LOGIN=0
|
||||
REACT_APP_LINKEDIN_SOCIAL_LOGIN=0
|
||||
|
||||
REACT_APP_MAX_CREDIT_CARDS=4
|
||||
REACT_APP_MAX_CREDIT_BANK_ACCOUNT=4
|
||||
|
||||
REACT_APP_MAX_FAMILY_MEMBERS=8
|
||||
|
||||
REACT_APP_SHOW_OFFER_GROUP_JOB=0
|
||||
|
||||
#UPLOAD PROFILE PICTURE
|
||||
REACT_APP_SHOW_UPLOAD_PROFILE_PICTURE=0
|
||||
|
||||
#GOOGLE RECAPTCHA SITEKEY
|
||||
REACT_APP_GOOGLE_RECAPTCHA_SITEKEY=6Ld_qKooAAAAADNL1TPzRLmcBA8vlpvx__39Rj39
|
||||
#6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
|
||||
|
||||
#FAMILY MEMBER MINIMUM AGE
|
||||
REACT_APP_FAMILY_MINIMUM_AGE=4
|
||||
REACT_APP_FAMILY_MAXIMUM_AGE=18
|
||||
|
||||
#CHANGE LOGIN LAYOUT
|
||||
REACT_APP_NEW_LOGIN_LAYOUT=1
|
||||
|
||||
#APP DOWNLOAD LINKS
|
||||
REACT_APP_ANDROID_APP='https://play.google.com/store/apps/details?id=com.wrenchboard.users'
|
||||
REACT_APP_APPLE_APP='https://itunes.apple.com/us/app/wrenchboard/id1435718367?ls=1&mt=8'
|
||||
|
||||
# Displays the new family dashboard with boxes
|
||||
REACT_APP_SHOW_NEW_FAMILY_DASH=1
|
||||
|
||||
# Displays the account dashboard
|
||||
REACT_APP_SHOW_ACCOUNT_DASH=1
|
||||
|
||||
# Displays the slider banners
|
||||
REACT_APP_SHOW_SLIDER_BANNERS=0
|
||||
|
||||
# FOR MEDIA LINK
|
||||
REACT_APP_MEDIA_LINK='https://media.wrenchboard.com'
|
||||
|
||||
# FOR FAMILY GAME LINK
|
||||
REACT_APP_FAM_GAME_LINK='https://games.wrenchboard.com'
|
||||
|
||||
# REACT APP CUSTOMTIMER
|
||||
REACT_APP_CUSTOMTIMER=90
|
||||
|
||||
#SHOW OR HIDE MY PAGE LINK ROUTE
|
||||
REACT_APP_SHOW_USER_PAGE=0
|
||||
@@ -19,6 +19,8 @@
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
#package-lock.json
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
@@ -21,5 +21,14 @@
|
||||
"emmet.triggerExpansionOnTab": true,
|
||||
"emmet.includeLanguages": {
|
||||
"javascript": "javascriptreact"
|
||||
}
|
||||
},
|
||||
"cSpell.words": [
|
||||
"completesignuplink",
|
||||
"MOBILEUSER",
|
||||
"MYFILES",
|
||||
"mynotifications",
|
||||
"PASSWORDRESET",
|
||||
"TRANSFERSTART",
|
||||
"WRENCHBOARD"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -21,9 +21,10 @@ services:
|
||||
- backend.wrenchboard.api.live:10.10.33.15
|
||||
- backend.wrenchboard.api.test:10.10.33.15
|
||||
- apigate.lotus.g1.wrenchboard.com:10.10.33.15
|
||||
- apigate.nebula.g1.wrenchboard.com:10.10.33.15
|
||||
- apigate.orion.g1.wrenchboard.com:10.10.33.15
|
||||
# #- backend.wrenchboard.api.live:172.31.4.27
|
||||
# #- backend.wrenchboard.api.test:10.20.30.27
|
||||
- socket-dev.wrenchboard.com:10.10.33.15
|
||||
- socket.wrenchboard.com:10.10.33.15
|
||||
- apigateway.wrenchboard.app.dev.fluxtra.net:10.20.30.19
|
||||
- apigateway.wrenchboard.app.lotus.fluxtra.net:172.31.4.19
|
||||
environment:
|
||||
|
||||
@@ -22,13 +22,17 @@
|
||||
"flutterwave-react-v3": "^1.3.0",
|
||||
"formik": "^2.2.9",
|
||||
"react": "^18.2.0",
|
||||
"react-apple-login": "^1.1.6",
|
||||
"react-chartjs-2": "^4.1.0",
|
||||
"react-countup": "^6.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-google-recaptcha": "^3.1.0",
|
||||
"react-qr-code": "^2.0.11",
|
||||
"react-redux": "^8.0.5",
|
||||
"react-router-dom": "^6.0.2",
|
||||
"react-scripts": "5.0.1",
|
||||
"react-slick": "^0.29.0",
|
||||
"react-to-print": "^2.14.12",
|
||||
"react-toastify": "^9.0.1",
|
||||
"redux": "^4.2.0",
|
||||
"slick-carousel": "^1.8.1",
|
||||
@@ -14801,6 +14805,11 @@
|
||||
"teleport": ">=0.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/qr.js": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/qr.js/-/qr.js-0.0.0.tgz",
|
||||
"integrity": "sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ=="
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.11.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
|
||||
@@ -14944,6 +14953,32 @@
|
||||
"url": "https://opencollective.com/core-js"
|
||||
}
|
||||
},
|
||||
"node_modules/react-apple-login": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/react-apple-login/-/react-apple-login-1.1.6.tgz",
|
||||
"integrity": "sha512-ySV6ax0aB+ksA7lKzhr4MvsgjwSH068VtdHJXS+7rL380IJnNQNl14SszR31k3UqB8q8C1H1oyjJFGq4MyO6tw==",
|
||||
"engines": {
|
||||
"node": ">=8",
|
||||
"npm": ">=5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"prop-types": "^15.5.4",
|
||||
"react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
|
||||
"react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-async-script": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-async-script/-/react-async-script-1.2.0.tgz",
|
||||
"integrity": "sha512-bCpkbm9JiAuMGhkqoAiC0lLkb40DJ0HOEJIku+9JDjxX3Rcs+ztEOG13wbrOskt3n2DTrjshhaQ/iay+SnGg5Q==",
|
||||
"dependencies": {
|
||||
"hoist-non-react-statics": "^3.3.0",
|
||||
"prop-types": "^15.5.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-chartjs-2": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-4.3.1.tgz",
|
||||
@@ -15044,11 +15079,41 @@
|
||||
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz",
|
||||
"integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw=="
|
||||
},
|
||||
"node_modules/react-google-recaptcha": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-google-recaptcha/-/react-google-recaptcha-3.1.0.tgz",
|
||||
"integrity": "sha512-cYW2/DWas8nEKZGD7SCu9BSuVz8iOcOLHChHyi7upUuVhkpkhYG/6N3KDiTQ3XAiZ2UAZkfvYKMfAHOzBOcGEg==",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.5.0",
|
||||
"react-async-script": "^1.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"node_modules/react-qr-code": {
|
||||
"version": "2.0.12",
|
||||
"resolved": "https://registry.npmjs.org/react-qr-code/-/react-qr-code-2.0.12.tgz",
|
||||
"integrity": "sha512-k+pzP5CKLEGBRwZsDPp98/CAJeXlsYRHM2iZn1Sd5Th/HnKhIZCSg27PXO58zk8z02RaEryg+60xa4vyywMJwg==",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.8.1",
|
||||
"qr.js": "0.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.x || ^17.x || ^18.x",
|
||||
"react-native-svg": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react-native-svg": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-redux": {
|
||||
"version": "8.0.5",
|
||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz",
|
||||
@@ -15218,6 +15283,15 @@
|
||||
"react-dom": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-to-print": {
|
||||
"version": "2.14.15",
|
||||
"resolved": "https://registry.npmjs.org/react-to-print/-/react-to-print-2.14.15.tgz",
|
||||
"integrity": "sha512-SKnwOzU2cJ8eaAkoJO7+gNhvfEDmm+Y34IdcHsjtHioUevUPhprqbVtvNJlZ2JkGJ8ExK2QNWM9pXECTDR5D8w==",
|
||||
"peerDependencies": {
|
||||
"react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
|
||||
"react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-toastify": {
|
||||
"version": "9.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.1.tgz",
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"react-chartjs-2": "^4.1.0",
|
||||
"react-countup": "^6.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-google-recaptcha": "^3.1.0",
|
||||
"react-qr-code": "^2.0.11",
|
||||
"react-redux": "^8.0.5",
|
||||
"react-router-dom": "^6.0.2",
|
||||
@@ -29,6 +30,7 @@
|
||||
"react-to-print": "^2.14.12",
|
||||
"react-toastify": "^9.0.1",
|
||||
"redux": "^4.2.0",
|
||||
"socket.io-client": "^4.4.1",
|
||||
"slick-carousel": "^1.8.1",
|
||||
"web-vitals": "^1.0.1",
|
||||
"yup": "^1.1.1"
|
||||
|
||||
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 713 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1 @@
|
||||
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
||||
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 31 KiB |
@@ -6,9 +6,18 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
|
||||
|
||||
<meta name="description" content="wrenchboard.com is an online marketplace to make money from your skills, find, buy and sell professional services. Connect with freelancers to get work done faster. Trade your freelance services."/>
|
||||
<meta name="title" content="WrenchBoard: Find a Freelancer | Sell Professional Services"/><meta name="keywords" content="Online Jobs, Online Workers, work online Nigeria, hire a freelancer, hire freelancers, freelance marketplace, freelancer hire, freelance service, freelance professional services, How to make money online, find workers online, Online Services, digital services, freelancers community in Ghana, freelancers community in Nigeria, freelancer site in Africa, Best freelance website in Africa, Freelance Designers, Photographers, Writers in Nigeria, freelancers, freelance outsourcing in Nigeria, freelance IT services in Nigeria, hire freelancers online in Nigeria, freelance services online in Nigeria, freelance contractor in Nigeria, freelance sites in Nigeria, freelance jobs in Nigeria, freelance projects in Nigeria, freelance jobs online in Nigeria, professional freelancers in Nigeria, buy professional services in Nigeria, professional services jobs, professional business services, professional service providers in Nigeria, freelancing services, freelancing sites in Nigeria, freelancers for hire in Nigeria, freelancer search in Nigeria, search freelancer in Nigeria, find freelancers in Nigeria, Find workers US. Outsource from US to Nigeria, find a freelancer in Nigeria, freelancing projects in Nigeria, web freelancing in Nigeria, outsourcing sites freelancers in Nigeria, website for freelancers in Nigeria, marketplace for freelancers "/>
|
||||
<meta
|
||||
name="description"
|
||||
content="WrenchBoard.com is the place to set family goals and reward achievements. Find tasks to earn from, or send tasks for others to perform for you."
|
||||
/>
|
||||
<meta
|
||||
name="title"
|
||||
content="WrenchBoard: Reward Accomplishments | Get Family Engaged"
|
||||
/>
|
||||
<meta
|
||||
name="keywords"
|
||||
content="Empower families to reward accomplishment, set goals, and encourage kids to understand goals, earning, and the benefit of savings – in one app experience."
|
||||
/>
|
||||
<link rel="manifest" href="/manifest.json"/>
|
||||
<script>
|
||||
!function(e,a,t,n,g,c,o){e.GoogleAnalyticsObject=g,e.ga=e.ga||function(){(e.ga.q=e.ga.q||[]).push(arguments)},e.ga.l=1*new Date,c=a.createElement(t),o=a.getElementsByTagName(t)[0],c.async=1,c.src="https://www.google-analytics.com/analytics.js",o.parentNode.insertBefore(c,o)}(window,document,"script",0,"ga"),ga("create","UA-54829827-4","auto"),ga("send","pageview")</script><script defer="defer" src="/static/js/main.787e423f.js"></script><link href="/static/css/main.418eaf65.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body><script>var LHC_API=LHC_API||{};LHC_API.args={mode:"widget",lhc_base_url:"//chat.live.wrenchboard.com/",wheight:450,wwidth:350,pheight:520,pwidth:500,leaveamessage:!0,check_messages:!1},function(){var e=document.createElement("script");e.type="text/javascript",e.setAttribute("crossorigin","anonymous"),e.async=!0;var t=new Date;e.src="//chat.live.wrenchboard.com/design/defaulttheme/js/widgetv2/index.js?"+t.getFullYear()+t.getMonth()+t.getDate();var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(e,a)}()
|
||||
@@ -17,6 +26,9 @@
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<title>WrenchBoard</title>
|
||||
|
||||
<!-- FONT AWESOME -->
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v6.5.1/css/all.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
||||
@@ -1,15 +1,24 @@
|
||||
import Toaster from "./components/Helpers/Toaster";
|
||||
import { Navigate, useLocation } from "react-router-dom";
|
||||
import Routers from "./Routers";
|
||||
import Toaster from "./components/Helpers/Toaster";
|
||||
import Default from "./components/Partials/Default";
|
||||
import SocketIOContextProvider from "./components/Contexts/SocketIOContext";
|
||||
|
||||
function App() {
|
||||
const { pathname } = useLocation();
|
||||
return (
|
||||
<Default>
|
||||
<>
|
||||
<Routers />
|
||||
<Toaster />
|
||||
</>
|
||||
</Default>
|
||||
<Default>
|
||||
<SocketIOContextProvider>
|
||||
<>
|
||||
{pathname.startsWith("/@") ? (
|
||||
<Navigate to="/app" replace={true} />
|
||||
) : (
|
||||
<Routers />
|
||||
)}
|
||||
<Toaster />
|
||||
</>
|
||||
</SocketIOContextProvider>
|
||||
</Default>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,78 +1,128 @@
|
||||
import { Route, Routes } from "react-router-dom";
|
||||
import FourZeroFour from "./components/FourZeroFour";
|
||||
import ScrollToTop from "./components/Helpers/ScrollToTop";
|
||||
import MyCollection from "./components/MyCollection";
|
||||
import StartJob from "./components/MyJobs/StartJob";
|
||||
import Notification from "./components/Notification";
|
||||
import AuthRoute from "./middleware/AuthRoute";
|
||||
import AcitveBidsPage from "./views/AcitveBidsPage";
|
||||
import AppDownloadPage from "./views/AppDownloadPage";
|
||||
import AppleRedirectPage from "./views/AppleRedirectPage";
|
||||
import AuthProfilePage from "./views/AuthProfilePage";
|
||||
import AuthRedirect from "./views/AuthRedirect";
|
||||
import BlogPage from "./views/BlogPage";
|
||||
import CalendarPage from "./views/CalendarPage";
|
||||
import CollectionItemPage from "./views/CollectionItemPage";
|
||||
import FacebookRedirect from "./views/FacebookRedirect";
|
||||
import FamilyAccPage from "./views/FamilyAccPage";
|
||||
import FamilyManagePage from "./views/FamilyManagePage";
|
||||
import FamilyMarketPage from "./views/FamilyMarketPage";
|
||||
import FamilySettingsPage from "./views/FamilySettingsPage";
|
||||
import ForgotPasswordPages from "./views/ForgotPasswordPages";
|
||||
import ForgotPasswordPagesTwo from "./views/ForgotPasswordPagesTwo";
|
||||
import HistoryPage from "./views/HistoryPage";
|
||||
import HomePages from "./views/HomePages";
|
||||
import JobGroupsPage from "./views/JobGroupsPage";
|
||||
import LndPage from "./views/LndPage";
|
||||
import LoginPage from "./views/LoginPage";
|
||||
import LoginPageTwo from "./views/LoginPageTwo";
|
||||
import ManageActiveJobs from "./views/ManageActiveJobs";
|
||||
import ManageInterestOfferPage from "./views/ManageInterestOfferPage";
|
||||
import MarketPlacePage from "./views/MarketPlacePage";
|
||||
import MyActiveJobsPage from "./views/MyActiveJobsPage";
|
||||
import MyCouponPage from "./views/MyCouponPage";
|
||||
import MyJobsPage from "./views/MyJobsPage";
|
||||
import MyOffersPage from "./views/MyOffersPage";
|
||||
import MyPastDueJobsPage from "./views/MyPastDueJobsPage";
|
||||
import MyReviewDueJobsPage from "./views/MyReviewDueJobsPage";
|
||||
import MyTaskPage from "./views/MyTaskPage";
|
||||
import MyWaitingJobsPage from "./views/MyWaitingJobsPage";
|
||||
import MyWalletPage from "./views/MyWalletPage";
|
||||
import OffersInterestPage from "./views/OffersInterestPage";
|
||||
import ReferralPage from "./views/ReferralPage";
|
||||
import RemindersPage from "./views/RemindersPage";
|
||||
import ResourcePage from "./views/ResourcePage";
|
||||
import SavedPage from "./views/SavedPage";
|
||||
import SellPage from "./views/SellPage";
|
||||
import SettingsPage from "./views/SettingsPage";
|
||||
import ShopDetailsPage from "./views/ShopDetailsPage";
|
||||
import SignupPage from "./views/SignupPage";
|
||||
import SignupPageTwo from "./views/SignupPageTwo";
|
||||
import TrackingPage from "./views/TrackingPage";
|
||||
import UpdatePasswordPages from "./views/UpdatePasswordPages";
|
||||
import UpdatePasswordPagesTwo from "./views/UpdatePasswordPagesTwo";
|
||||
import UploadProductPage from "./views/UploadProductPage";
|
||||
import UserProfilePage from "./views/UserProfilePage";
|
||||
import VerifyYouPages from "./views/VerifyYouPages";
|
||||
import VerifyPasswordPages from "./views/VerifyPasswordPages";
|
||||
import RemindersPage from './views/RemindersPage';
|
||||
import TrackingPage from "./views/TrackingPage";
|
||||
import CalendarPage from "./views/CalendarPage";
|
||||
import ResourcePage from "./views/ResourcePage";
|
||||
import MyTaskPage from "./views/MyTaskPage";
|
||||
import MyJobsPage from "./views/MyJobsPage";
|
||||
import ReferralPage from "./views/ReferralPage";
|
||||
import VerifyLinkPages from "./views/VerifyLinkPages";
|
||||
import MyActiveJobsPage from "./views/MyActiveJobsPage";
|
||||
import FamilyAccPage from "./views/FamilyAccPage";
|
||||
import StartJob from "./components/MyJobs/StartJob";
|
||||
import AddJobPage from "./views/AddJobPage";
|
||||
import MyPendingJobsPage from "./views/MyPendingJobsPage";
|
||||
import ManageActiveJobs from "./views/ManageActiveJobs";
|
||||
import FamilyManagePage from "./views/FamilyManagePage";
|
||||
import MyCouponPage from "./views/MyCouponPage";
|
||||
import AuthRedirect from "./views/AuthRedirect";
|
||||
import MyPastDueJobsPage from "./views/MyPastDueJobsPage";
|
||||
import BlogPage from "./views/BlogPage";
|
||||
import MyReviewDueJobsPage from "./views/MyReviewDueJobsPage";
|
||||
import OffersInterestPage from "./views/OffersInterestPage";
|
||||
import ManageInterestOfferPage from './views/ManageInterestOfferPage'
|
||||
import MyWaitingJobsPage from "./views/MyWaitingJobsPage";
|
||||
import FamilyMarketPage from "./views/FamilyMarketPage";
|
||||
import FacebookRedirect from "./views/FacebookRedirect";
|
||||
import AppleRedirectPage from "./views/AppleRedirectPage";
|
||||
import VerifyLinkPagesTwo from "./views/VerifyLinkPagesTwo";
|
||||
import VerifyPasswordPages from "./views/VerifyPasswordPages";
|
||||
import VerifyPasswordPagesTwo from "./views/VerifyPasswordPagesTwo";
|
||||
import VerifyYouPages from "./views/VerifyYouPages";
|
||||
import VerifyYouPagesTwo from "./views/VerifyYouPagesTwo";
|
||||
import YourPages from "./views/YourPage_";
|
||||
import ParentWaitingPage from "./views/ParentWaitingPage";
|
||||
import FamilyPendingOfferPage from "./views/FamilyPendingOfferPage";
|
||||
import FamBlogPage from "./views/FamBlogPage"
|
||||
import FamAIQuestionPage from "./views/FamAIQuestionPage"
|
||||
import FamMyFilesPage from "./views/FamMyFilesPage"
|
||||
import FamWorkInProgressPage from "./views/FamWorkInProgressPage";
|
||||
import MyPastDueTasksPage from "./views/MyPastDueTasksPage";
|
||||
import FamilyWalletPage from "./views/FamilyWalletPage";
|
||||
import FamilyActivitiesPage from "./views/FamilyActivitiesPage";
|
||||
import FamGamesPage from "./views/FamGamesPage";
|
||||
import FamilyRoutesPage from "./views/FamilyRoutesPage";
|
||||
import PromoPage from "./views/PromoPage";
|
||||
import LearnMorePage from "./views/LearnMorePage";
|
||||
|
||||
export default function Routers() {
|
||||
return (
|
||||
<ScrollToTop>
|
||||
<Routes>
|
||||
{/* guest routes */}
|
||||
<Route exact path="/login" element={<LoginPage />} />
|
||||
<Route exact path="/signup" element={<SignupPage />} />
|
||||
{process.env.REACT_APP_NEW_LOGIN_LAYOUT == 1 ? (
|
||||
<>
|
||||
<Route exact path="/login" element={<LoginPageTwo />} />
|
||||
<Route exact path="/signup" element={<SignupPageTwo />} />
|
||||
<Route
|
||||
exact
|
||||
path="/forgot-password"
|
||||
element={<ForgotPasswordPagesTwo />}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path="/update-password"
|
||||
element={<UpdatePasswordPagesTwo />}
|
||||
/>
|
||||
<Route path="/vemail" element={<VerifyLinkPagesTwo />} />
|
||||
<Route path="/complereset" element={<VerifyPasswordPagesTwo />} />
|
||||
<Route exact path="/outmessage" element={<VerifyYouPagesTwo />} />
|
||||
<Route exact path="/eoffer" element={<LoginPageTwo />} />
|
||||
<Route exact path="/invite" element={<LoginPageTwo />} />
|
||||
<Route exact path="/promo/:name/:id" element={<PromoPage />} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Route exact path="/login" element={<LoginPage />} />
|
||||
<Route exact path="/signup" element={<SignupPage />} />
|
||||
<Route
|
||||
exact
|
||||
path="/forgot-password"
|
||||
element={<ForgotPasswordPages />}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path="/update-password"
|
||||
element={<UpdatePasswordPages />}
|
||||
/>
|
||||
<Route path="/vemail" element={<VerifyLinkPages />} />
|
||||
<Route path="/complereset" element={<VerifyPasswordPages />} />
|
||||
<Route exact path="/outmessage" element={<VerifyYouPages />} />
|
||||
<Route exact path="/eoffer" element={<LoginPage />} />
|
||||
<Route exact path="/invite" element={<LoginPage />} />
|
||||
</>
|
||||
)}
|
||||
<Route exact path="/login/auth" element={<AuthRedirect />} />
|
||||
<Route exact path="/login/auth/flogin" element={<FacebookRedirect />} />
|
||||
<Route exact path="/login/auth/apple" element={<AppleRedirectPage />} />
|
||||
<Route
|
||||
exact
|
||||
path="/forgot-password"
|
||||
element={<ForgotPasswordPages />}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path="/update-password"
|
||||
element={<UpdatePasswordPages />}
|
||||
/>
|
||||
<Route path="/vemail" element={<VerifyLinkPages />} />
|
||||
<Route path="/complereset" element={<VerifyPasswordPages />} />
|
||||
<Route exact path="/outmessage" element={<VerifyYouPages />} />
|
||||
<Route exact path="/lnd/*" element={<LndPage />} />
|
||||
<Route exact path="/app" element={<AppDownloadPage />} />
|
||||
|
||||
{/* private route */}
|
||||
<Route element={<AuthRoute />}>
|
||||
@@ -81,35 +131,70 @@ export default function Routers() {
|
||||
<Route exact path="/notification" element={<Notification />} />
|
||||
<Route exact path="/market-place" element={<MarketPlacePage />} />
|
||||
<Route exact path="/shop-details" element={<ShopDetailsPage />} />
|
||||
<Route exact path="/my-wallet" element={<MyWalletPage />} />
|
||||
<Route exact path="/my-collection" element={<MyCollection />} />*/}
|
||||
<Route exact path="/my-collection" element={<MyCollection />} />*/}
|
||||
<Route exact path="/reminders" element={<RemindersPage />} />
|
||||
<Route exact path="/tracking" element={<TrackingPage />} />
|
||||
<Route exact path="/calendar" element={<CalendarPage />} />
|
||||
<Route exact path="/resources" element={<ResourcePage />} />
|
||||
<Route exact path="/my-wallet/*" element={<MyWalletPage />} />
|
||||
<Route exact path="/family-wallet" element={<FamilyWalletPage />} />
|
||||
<Route exact path="/my-coupon" element={<MyCouponPage />} />
|
||||
<Route exact path="/notification" element={<Notification />} />
|
||||
<Route exact path="/market-place" element={<MarketPlacePage />} />
|
||||
<Route exact path="/market" element={<MarketPlacePage />} />
|
||||
<Route exact path="/familymarket" element={<FamilyMarketPage />} />
|
||||
<Route exact path="/suggested" element={<ParentWaitingPage />} />
|
||||
<Route exact path="/pending" element={<FamilyPendingOfferPage />} />
|
||||
<Route exact path="/fam-blog" element={<FamBlogPage />} />
|
||||
<Route exact path="/ai-question" element={<FamAIQuestionPage />} />
|
||||
<Route exact path="/myfiles" element={<FamMyFilesPage />} />
|
||||
<Route exact path="/ai-lab" element={<FamAIQuestionPage />} />
|
||||
<Route exact path="/fam-games" element={<FamGamesPage />} />
|
||||
<Route exact path="/work-in-progress" element={<FamWorkInProgressPage />} />
|
||||
|
||||
<Route exact path="/pastdue" element={<MyPastDueTasksPage />} />
|
||||
<Route exact path="/notification" element={<Notification />} />
|
||||
<Route exact path="/mytask" element={<MyTaskPage />} />
|
||||
<Route exact path="/myjobs" element={<MyJobsPage />} />
|
||||
{/* <Route exact path="/add-job" element={<AddJobPage />} /> */}
|
||||
<Route exact path="/my-active-jobs" element={<MyActiveJobsPage />} />
|
||||
<Route exact path="/my-pastdue-jobs" element={<MyPastDueJobsPage />} />
|
||||
<Route exact path="/my-pending-jobs" element={<MyPendingJobsPage />} />
|
||||
<Route exact path="/pend-interest" element={<MyWaitingJobsPage />} />
|
||||
<Route exact path="/my-review-jobs" element={<MyReviewDueJobsPage />} />
|
||||
<Route exact path="/acc-family" element={<FamilyAccPage />} />
|
||||
<Route exact path="/manage-family" element={<FamilyManagePage />} />
|
||||
<Route exact path="/start-job" element={<StartJob />} />
|
||||
<Route exact path="/manage-active-job" element={<ManageActiveJobs />} />
|
||||
<Route exact path="/blog-page" element={<BlogPage />} />
|
||||
<Route exact path="/offer-interest" element={<OffersInterestPage />} />
|
||||
<Route exact path="/manage-offer" element={<ManageInterestOfferPage />} />
|
||||
<Route exact path="/my-active-jobs" element={<MyActiveJobsPage />} />
|
||||
<Route
|
||||
exact
|
||||
path="/my-pastdue-jobs"
|
||||
element={<MyPastDueJobsPage />}
|
||||
/>
|
||||
<Route exact path="/my-offers" element={<MyOffersPage />} />
|
||||
<Route exact path="/pend-interest" element={<MyWaitingJobsPage />} />
|
||||
<Route
|
||||
exact
|
||||
path="/my-review-jobs"
|
||||
element={<MyReviewDueJobsPage />}
|
||||
/>
|
||||
|
||||
{/* <Route exact path='/acc-family' element={<FamilyAccPage />} />
|
||||
<Route exact path="/acc-family/activities" element={<FamilyActivitiesPage />} />
|
||||
<Route exact path="/acc-family/familysettings" element={<FamilySettingsPage />} /> */}
|
||||
<Route path='/acc-family/*' element={<FamilyRoutesPage />} />
|
||||
|
||||
<Route exact path="/manage-family" element={<FamilyManagePage />} />
|
||||
<Route exact path="/start-job" element={<StartJob />} />
|
||||
<Route exact path="/yourpage" element={<YourPages />} />
|
||||
<Route
|
||||
exact
|
||||
path="/manage-active-job"
|
||||
element={<ManageActiveJobs />}
|
||||
/>
|
||||
<Route exact path="/blog-page" element={<BlogPage />} />
|
||||
<Route
|
||||
exact
|
||||
path="/offer-interest"
|
||||
element={<OffersInterestPage />}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path="/manage-offer"
|
||||
element={<ManageInterestOfferPage />}
|
||||
/>
|
||||
|
||||
<Route
|
||||
exact
|
||||
@@ -119,11 +204,14 @@ export default function Routers() {
|
||||
<Route exact path="/sell" element={<SellPage />} />
|
||||
<Route exact path="/saved" element={<SavedPage />} />
|
||||
<Route exact path="/history" element={<HistoryPage />} />
|
||||
<Route exact path="/upload-product" element={<UploadProductPage />} />
|
||||
<Route exact path="/learnmore" element={<LearnMorePage />} />
|
||||
{/*<Route exact path="/upload-product" element={<UploadProductPage />} />*/}
|
||||
<Route exact path="/my-uploads" element={<UploadProductPage />} />
|
||||
<Route exact path="/profile" element={<AuthProfilePage />} />
|
||||
<Route exact path="/user-profile" element={<UserProfilePage />} />
|
||||
<Route exact path="/settings" element={<SettingsPage />} />
|
||||
<Route exact path="/referral" element={<ReferralPage />} />
|
||||
<Route exact path="/job-groups" element={<JobGroupsPage />} />
|
||||
</Route>
|
||||
<Route path="*" element={<FourZeroFour />} />
|
||||
</Routes>
|
||||
|
||||
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 172 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 11 KiB |
@@ -1,4 +1,4 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.5 0H2.5C1.12125 0 0 1.12125 0 2.5V17.5C0 18.8787 1.12125 20 2.5 20H17.5C18.8787 20 20 18.8787 20 17.5V2.5C20 1.12125 18.8787 0 17.5 0Z" fill="#1976D2"/>
|
||||
<path d="M16.875 10H13.75V7.5C13.75 6.81 14.31 6.875 15 6.875H16.25V3.75H13.75C11.6788 3.75 10 5.42875 10 7.5V10H7.5V13.125H10V20H13.75V13.125H15.625L16.875 10Z" fill="#FAFAFA"/>
|
||||
</svg>
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.5 0H2.5C1.12125 0 0 1.12125 0 2.5V17.5C0 18.8787 1.12125 20 2.5 20H17.5C18.8787 20 20 18.8787 20 17.5V2.5C20 1.12125 18.8787 0 17.5 0Z" fill="#1976D2"/>
|
||||
<path d="M16.875 10H13.75V7.5C13.75 6.81 14.31 6.875 15 6.875H16.25V3.75H13.75C11.6788 3.75 10 5.42875 10 7.5V10H7.5V13.125H10V20H13.75V13.125H15.625L16.875 10Z" fill="#FAFAFA"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 452 B After Width: | Height: | Size: 448 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1792 1792" id="Bank"><path d="m896 78.526 896 358.4v119.466h-119.467q0 24.267-19.133 42-19.133 17.734-45.267 17.734H183.867q-26.134 0-45.267-17.734-19.133-17.733-19.133-42H0V436.926ZM238.933 675.859h238.934v716.8h119.466v-716.8h238.934v716.8h119.466v-716.8h238.934v716.8h119.466v-716.8h238.934v716.8h55.066q26.134 0 45.267 17.733 19.133 17.734 19.133 42v59.734H119.467v-59.734q0-24.266 19.133-42 19.133-17.733 45.267-17.733h55.066v-716.8zm1488.667 896q26.133 0 45.267 17.733 19.133 17.734 19.133 42v119.467H0v-119.467q0-24.266 19.133-42 19.134-17.733 45.267-17.733h1663.2z" fill="#4687ba" class="color000000 svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 684 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" id="DownloadArrow"><g fill="#4687ba" class="color9a7baa svgShape"><path d="M30.179 3.525V1.857c0-1.551-1.784-2.415-3.011-1.449L24 2.907 20.824.402c-1.216-.959-3.002-.093-3.002 1.456v1.668a1 1 0 0 0 1 1h10.357c.552-.001 1-.449 1-1.001zM30.179 25.172v-2.524a1 1 0 0 0-1-1H18.822a1 1 0 0 0-1 1v2.524a1 1 0 0 0 1 1h10.357a1 1 0 0 0 1-1zM30.179 10.74V8.217a1 1 0 0 0-1-1H18.822a1 1 0 0 0-1 1v2.524a1 1 0 0 0 1 1h10.357c.552-.001 1-.448 1-1.001zM30.179 17.956v-2.524a1 1 0 0 0-1-1H18.822a1 1 0 0 0-1 1v2.524a1 1 0 0 0 1 1h10.357a1 1 0 0 0 1-1zM25.748 47.029l9.336-15.018c.852-1.371-.133-3.145-1.748-3.145H14.664c-1.614 0-2.6 1.774-1.748 3.145l9.336 15.018a2.058 2.058 0 0 0 3.496 0z" fill="#000000" class="color000000 svgShape"></path></g></svg>
|
||||
|
After Width: | Height: | Size: 799 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" id="error"><path fill="#ff1d25" d="M29.75,25.73,18.68,3.59a3,3,0,0,0-4-1.33,3.05,3.05,0,0,0-1.33,1.33L2.25,25.73a3,3,0,0,0,2.68,4.34H27.07a3,3,0,0,0,3-3A2.88,2.88,0,0,0,29.75,25.73ZM16,25.38a.94.94,0,1,1,.94-.94A.94.94,0,0,1,16,25.38Zm.94-4.69a.94.94,0,1,1-1.88,0V11.31a.94.94,0,1,1,1.88,0Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 365 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 32 28" viewBox="0 0 32 28" id="List"><circle cx="2" cy="2" r="2" fill="#767fad" class="color4e4e50 svgShape"></circle><path fill="#767fad" d="M8 0h24v4H8z" class="color4e4e50 svgShape"></path><circle cx="10" cy="10" r="2" fill="#767fad" class="color4e4e50 svgShape"></circle><path fill="#767fad" d="M16 8h16v4H16z" class="color4e4e50 svgShape"></path><circle cx="10" cy="26" r="2" fill="#767fad" class="color4e4e50 svgShape"></circle><path fill="#767fad" d="M16 24h16v4H16z" class="color4e4e50 svgShape"></path><circle cx="18" cy="18" r="2" fill="#767fad" class="color4e4e50 svgShape"></circle><path fill="#767fad" d="M24 16h8v4h-8z" class="color4e4e50 svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 743 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" id="Group" x="0" y="0" version="1.1" viewBox="0 0 52 52" xml:space="preserve"><path d="M26.003 13.05c2.44 0 4.43-1.99 4.43-4.43a4.44 4.44 0 0 0-4.43-4.44c-2.45 0-4.44 1.99-4.44 4.44a4.44 4.44 0 0 0 4.44 4.43zM11.293 38.77c2.44 0 4.43-1.99 4.43-4.43a4.44 4.44 0 0 0-4.43-4.44c-2.45 0-4.43 1.99-4.43 4.44 0 2.44 1.98 4.43 4.43 4.43z" fill="#4687ba" class="color000000 svgShape"></path><path d="M49.493 41.93a10.091 10.091 0 0 0-3.643-3.739 6.418 6.418 0 0 1-5.138 2.58 6.392 6.392 0 0 1-4.371-1.737.975.975 0 0 0-.158-.258l-9.184-9.903V22.1h4.344c1.41 0 2.68-.73 3.4-1.94.72-1.23.73-2.7.04-3.95a10.09 10.09 0 0 0-3.643-3.739 6.418 6.418 0 0 1-5.138 2.579 6.43 6.43 0 0 1-5.144-2.58 10.085 10.085 0 0 0-3.645 3.74c-.69 1.25-.67 2.72.05 3.95a3.9 3.9 0 0 0 3.39 1.94h4.346v6.624c-.01.022-.016.044-.025.066l-9.22 9.941a.978.978 0 0 0-.22.42 6.378 6.378 0 0 1-4.242 1.62 6.417 6.417 0 0 1-5.14-2.584 10.086 10.086 0 0 0-3.65 3.743c-.69 1.25-.67 2.72.05 3.95a3.9 3.9 0 0 0 3.39 1.94h10.69c1.41 0 2.68-.73 3.4-1.94.72-1.23.73-2.7.04-3.95a10.03 10.03 0 0 0-2.134-2.612l8.01-8.636 8.055 8.685c-.815.73-1.53 1.58-2.08 2.563-.69 1.25-.67 2.72.05 3.95a3.9 3.9 0 0 0 3.39 1.94h10.69c1.41 0 2.68-.73 3.4-1.94.72-1.23.73-2.7.04-3.95z" fill="#4687ba" class="color000000 svgShape"></path><path d="M40.713 38.77c2.44 0 4.43-1.99 4.43-4.43a4.44 4.44 0 0 0-4.43-4.44c-2.45 0-4.44 1.99-4.44 4.44a4.44 4.44 0 0 0 4.44 4.43z" fill="#4687ba" class="color000000 svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" id="List"><switch><g fill="#767fad" class="color000000 svgShape"><g fill="#4687ba" class="color0ac5ab svgShape"><path d="M20 0H8a8 8 0 00-8 8v12a8 8 0 008 8h12a8 8 0 008-8V8a8 8 0 00-8-8zM56 0H44a8 8 0 00-8 8v12a8 8 0 008 8h12a8 8 0 008-8V8a8 8 0 00-8-8zM20 36H8a8 8 0 00-8 8v12a8 8 0 008 8h12a8 8 0 008-8V44a8 8 0 00-8-8zM56 36H44a8 8 0 00-8 8v12a8 8 0 008 8h12a8 8 0 008-8V44a8 8 0 00-8-8z" fill="#767fad" class="color000000 svgShape"></path></g></g></switch></svg>
|
||||
|
After Width: | Height: | Size: 527 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 8" id="List"><path d="M0 0v3h3V0H0zm4 0v1h4V0H4zm0 2v1h3V2H4zM0 4v3h3V4H0zm4 0v1h4V4H4zm0 2v1h3V6H4z" fill="#b22b7d" class="color000000 svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 214 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" id="List"><path d="M9 3a6 6 0 1 0 6 6A6 6 0 0 0 9 3zM9 13a4 4 0 1 1 4-4A4 4 0 0 1 9 13zM17 9H28a1 1 0 0 0 0-2H17a1 1 0 0 0 0 2zM17 13h6a1 1 0 0 0 0-2H17a1 1 0 0 0 0 2zM9 17a6 6 0 1 0 6 6A6 6 0 0 0 9 17zM9 27a4 4 0 1 1 4-4A4 4 0 0 1 9 27zM28 21H17a1 1 0 0 0 0 2H28a1 1 0 0 0 0-2zM23 25H17a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2z" fill="#4687ba" class="color000000 svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 437 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 50" id="Page"><path fill-rule="evenodd" d="M0 13V2a2 2 0 0 1 2-2h64a2 2 0 0 1 2 2v11H0Zm0 4v31a2 2 0 0 0 2 2h20V17H0Zm26 33h40a2 2 0 0 0 2-2V17H26v33Z" fill="#767fad" class="color000000 svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 265 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 64 64" id="delete"><path d="M44.41 19.59a2 2 0 0 0-2.83 0L32 29.18l-9.59-9.59a2 2 0 0 0-2.83 2.83L29.17 32l-9.59 9.59a2 2 0 1 0 2.83 2.83L32 34.83l9.59 9.59a2 2 0 0 0 2.83-2.83L34.83 32l9.59-9.59a2 2 0 0 0-.01-2.82Z" fill="#b22b7d" class="color000000 svgShape"></path><path d="M32 3a29 29 0 1 0 29 29A29 29 0 0 0 32 3Zm0 54a25 25 0 1 1 25-25 25 25 0 0 1-25 25Z" fill="#b22b7d" class="color000000 svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 492 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" id="success"><path fill="#80af52" d="M256 26c127.03 0 230 102.97 230 230S383.03 486 256 486 26 383.03 26 256 128.97 26 256 26z"></path><path fill="#fff" d="M215.999 386a9.998 9.998 0 0 1-7.525-3.415l-70-80c-3.637-4.156-3.215-10.474.941-14.11s10.475-3.217 14.111.94l60.961 69.67 142.938-238.23c2.842-4.736 8.983-6.273 13.72-3.43 4.736 2.841 6.271 8.984 3.431 13.72l-150 250a9.998 9.998 0 0 1-8.577 4.855z"></path></svg>
|
||||
|
After Width: | Height: | Size: 483 B |
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 64 64" viewBox="0 0 64 64" id="wallet"><path d="M60.94,33.76H59.6V19.85c0-1.69-1.37-3.06-3.06-3.06h-1.61l-0.47-6.54c-0.12-1.67-1.57-2.94-3.27-2.84l-7.3,0.52
|
||||
l-0.18-2.48c-0.12-1.67-1.57-2.95-3.27-2.84L7.83,4.93c-0.82,0.06-1.56,0.43-2.1,1.05C5.19,6.6,4.93,7.39,4.99,8.2l0.61,8.59H3.06
|
||||
C1.37,16.79,0,18.17,0,19.85v38.48c0,1.69,1.37,3.06,3.06,3.06h53.48c1.69,0,3.06-1.37,3.06-3.06V44.43h1.33
|
||||
c1.69,0,3.06-1.37,3.06-3.06v-4.55C64,35.13,62.63,33.76,60.94,33.76z M51.42,9.94c0.27,0,0.51,0.22,0.53,0.49l0.45,6.36H18.55
|
||||
l-0.28-3.97c-0.01-0.19,0.07-0.32,0.13-0.38c0.05-0.06,0.17-0.17,0.36-0.18L51.42,9.94z M7.65,7.64C7.7,7.58,7.82,7.47,8.01,7.46
|
||||
l32.66-2.32c0.27,0,0.51,0.22,0.53,0.49l0.18,2.48L18.58,9.73c-0.82,0.06-1.56,0.43-2.1,1.05c-0.54,0.62-0.8,1.41-0.74,2.22
|
||||
l0.27,3.79H8.14L7.52,8.02C7.5,7.83,7.59,7.7,7.65,7.64z M57.07,58.34c0,0.28-0.24,0.53-0.53,0.53H3.06
|
||||
c-0.28,0-0.53-0.24-0.53-0.53V19.85c0-0.29,0.24-0.53,0.53-0.53h53.48c0.28,0,0.53,0.24,0.53,0.53v13.91h-4.43
|
||||
c-1.69,0-3.06,1.37-3.06,3.06v4.55c0,1.69,1.37,3.06,3.06,3.06h4.43V58.34z M61.47,41.37c0,0.28-0.24,0.53-0.53,0.53h-8.3
|
||||
c-0.28,0-0.53-0.24-0.53-0.53v-4.55c0-0.28,0.24-0.53,0.53-0.53h8.3c0.29,0,0.53,0.24,0.53,0.53V41.37z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 235 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" id="files"><circle cx="64" cy="64" r="64" fill="#EF4C45"></circle><path fill="#CD2E30" d="M128 64v-2L92.4 26.5l-63.1 74 27.2 27c2.4.3 4.9.4 7.4.4C99.3 128 128 99.3 128 64z"></path><path fill="#E5E8EC" d="M93.5 78.4V29c0-1.9-1.5-3.4-3.4-3.4H41.8c-1.9 0-3.4 1.5-3.4 3.4v49.4h55.1z"></path><path fill="#FFF" d="M89.5 78.4V44.6H78.1c-1.9 0-3.4-1.5-3.4-3.4V29.9H37.8c-1.9 0-3.4 1.5-3.4 3.4v45.1h55.1z"></path><path fill="#FFCC04" d="m79.3 65.9-1.5 4c-.5 1.2-1.6 2-2.9 2H53.1c-1.3 0-2.4-.8-2.9-2l-1.5-4c-.5-1.3-1.7-2.2-3.1-2.2H30.9c-1.9 0-3.4 1.5-3.4 3.4v28.8c0 3.5 2.9 6.4 6.4 6.4H94c3.5 0 6.4-2.9 6.4-6.4V67.1c0-1.9-1.5-3.4-3.4-3.4H82.5c-1.4 0-2.7.9-3.2 2.2z"></path><path fill="#CED4DF" d="m74.9 45.8-.1-.1.1.1z"></path><path fill="#22D2FC" d="M74.7 29.9v11.4c0 1.9 1.5 3.4 3.4 3.4h11.4L74.7 29.9z"></path><path fill="#FFF" d="M74.1 81.6H53.9c-2 0-3.7 1.6-3.7 3.7 0 2 1.6 3.7 3.7 3.7h20.2c2 0 3.7-1.6 3.7-3.7 0-2-1.7-3.7-3.7-3.7z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1003 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 51 51" id="jpg"><circle cx="25.5" cy="25.5" r="24" fill="#FED000"></circle><path fill="#F39F03" d="M37.462 16.607v4.741a.924.924 0 0 1-.877.924v16.361c0 1.027-.84 1.867-1.867 1.867H18.282a1.866 1.866 0 0 1-1.867-1.867V22.272a.924.924 0 0 1-.877-.924v-4.741c0-.495.392-.906.877-.924v-1.316a1.86 1.86 0 0 1 1.867-1.867h16.436c1.027 0 1.867.83 1.867 1.867v1.316c.485.018.877.43.877.924z"></path><path fill="#FFF" d="M35.585 13.367v24.266c0 1.031-.836 1.867-1.867 1.867H17.282a1.867 1.867 0 0 1-1.867-1.867V13.367c0-1.031.836-1.867 1.867-1.867h16.436c1.03 0 1.867.836 1.867 1.867z" opacity=".96"></path><path fill="#33ACFE" d="M18.143 25.5h14.715v9.894H18.143z"></path><path fill="#273E56" d="M32.859 35.394h-7.622l3.959-4.357z"></path><path fill="#334861" d="M29.048 35.394H18.143l5.664-7.357z"></path><circle cx="27.697" cy="28.037" r="1.094" fill="#FED000"></circle><path fill="#EB4B33" d="M35.462 21.28H15.538a1 1 0 0 1-1-1v-4.604a1 1 0 0 1 1-1h19.924a1 1 0 0 1 1 1v4.605a1 1 0 0 1-1 1z"></path><path fill="#FFF" d="M22.511 18.797c0 .57-.155 1.499-1.475 1.499-.737 0-1.456-.403-1.456-1.37v-.384h.88v.199c0 .427.105.737.564.737.514 0 .514-.409.514-.725v-2.987h.973v3.03zm.857-3.031h1.996c1.109 0 1.53.7 1.53 1.42 0 .718-.421 1.418-1.53 1.418H24.34v1.587h-.973v-4.425zm.973 2.082h.756c.446 0 .855-.099.855-.663 0-.564-.409-.663-.855-.663h-.756v1.326zm6.36 1.84a1.49 1.49 0 0 1-1.214.608c-1.364 0-2.176-1.023-2.176-2.299 0-1.314.812-2.336 2.176-2.336.905 0 1.766.552 1.865 1.561h-.93c-.117-.496-.47-.743-.935-.743-.874 0-1.202.743-1.202 1.518 0 .738.328 1.48 1.202 1.48.638 0 .997-.334 1.053-.953h-.98V17.8h1.86v2.392h-.62l-.099-.502z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" viewBox="0 0 512 512" id="mp4-file"><circle cx="256" cy="256" r="256" fill="#8ABE4F"></circle><path fill="#7BA840" d="M511.9 262.5 346.6 96.8c-1.1-1.1-3.1-1.1-4.3 0l-37.4 43.4c-.6.6-.8 1.2-.7 1.9l-3.4-6.1H159.2c-13.1 0-23.7 10.6-23.7 23.7v145.6l7.9 5.9h-16.2v66.6l8.3 7.9v6.6c0 7.6 3.5 14.3 9 18.6.7.9 58.1 58.3 100.6 100.9 3.6.1 7.2.2 10.8.2 139.3 0 252.5-111.1 256-249.5z"></path><g fill="#FFF"><path d="M169.1 193.7h145.4V206H169.1zM169.1 213.5h145.4v12.3H169.1zM169.1 233.4h145.4v12.3H169.1zM169.1 253.3h145.4v12.3H169.1zM169.1 273.1H282v12.3H169.1zM384.1 140.2l-37.4-43.4c-1.1-1.1-3.1-1.1-4.3 0L305 140.2c-1.7 1.6-.4 4.3 2.1 4.3h17.6v34h39.8v-34h17.6c2.3 0 3.6-2.6 2-4.3zM324.6 184.7h39.8v15.5h-39.8zM324.6 212c0 1.4 1.3 2.6 2.9 2.6h34c1.6 0 2.9-1.1 2.9-2.6v-5.7h-39.8v5.7z"></path><path d="M339.7 389.3c0 10.1-8.2 18.3-18.3 18.3H162.2c-10.1 0-18.3-8.2-18.3-18.3v-5.6h-8.4v8.6c0 13.1 10.6 23.7 23.7 23.7h165.2c13.1 0 23.7-10.6 23.7-23.7V220.4h-8.4v168.9zM143.9 162.7c0-10.1 8.2-18.3 18.3-18.3h136.4c-.9-2.8-.2-6 1.9-8.2l.2-.3H159.2c-13.1 0-23.7 10.6-23.7 23.7v145.6h8.4V162.7z"></path><path d="M313.2 344.5c0-18.4-14.9-33.3-33.3-33.3H127.2v66.6h152.7c18.4 0 33.3-14.9 33.3-33.3zm-109 19.2h-6.4v-27.6h-.2L187 363.7h-4.4l-10.8-28.1-.2.1v28.1h-6.4v-38.4h8.4l11 29.5h.2l11.1-29.5h8.2v38.3zm34.4-17.8c-2.4 2.2-5.7 3.3-10 3.3h-8.3v14.6h-6.4v-38.4h14.7c4.2 0 7.6 1.1 10 3.3 2.4 2.2 3.6 5.1 3.6 8.6s-1.2 6.4-3.6 8.6zm36.5 9.3h-4.9v8.5h-6.4v-8.5h-16.1l-.2-3.9 16-26h6.6V350h4.9v5.2z"></path><path d="m263.1 335.8-9.2 14.2h9.9v-15.7h-.1zM228.6 330.4h-8.3V344h8.3c2.4 0 4.2-.6 5.4-1.9 1.2-1.3 1.8-2.9 1.8-4.8s-.6-3.6-1.8-4.9c-1.2-1.3-3-2-5.4-2z"></path></g></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 90 90" viewBox="0 0 90 90" id="pdf"><circle cx="45" cy="45" r="44.5" fill="#84D2ED"></circle><polygon fill="#EFC41C" stroke="#010101" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="1.978" points="35.6 18.8 35.6 31.9 22.5 31.9 22.5 71.2 62.8 71.2 62.8 18.8"></polygon><polygon fill="#8CC749" stroke="#010101" stroke-miterlimit="10" stroke-width="1.978" points="22.5 31.9 22.5 31.9 22.5 31.9"></polygon><polygon fill="#EB665F" stroke="#010101" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="1.978" points="35.6 18.8 22.5 31.9 22.5 31.9 35.6 31.9"></polygon><rect width="35.9" height="15.7" x="31.6" y="40.2" fill="#F2DFD5" stroke="#010101" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="1.978"></rect><path fill="#010101" d="M43 44c.7.6 1 1.5 1 2.7 0 1.2-.4 2.1-1.1 2.7-.7.6-1.8.9-3.3.9h-1.3v2.8h-2.2v-9.9h3.5C41.2 43.1 42.3 43.4 43 44zM41.4 47.9c.3-.3.4-.7.4-1.3 0-.6-.2-1-.5-1.2C41 45.2 40.4 45 39.7 45h-1.3v3.3h1.5C40.6 48.4 41.2 48.2 41.4 47.9zM53.4 44.4c.9.9 1.4 2.1 1.4 3.6 0 1.5-.5 2.8-1.4 3.7-.9.9-2.3 1.3-4.2 1.3h-3.4v-9.9h3.5C51.1 43.1 52.5 43.6 53.4 44.4zM51.8 50.3c.5-.5.8-1.3.8-2.2s-.3-1.7-.8-2.3c-.5-.5-1.4-.8-2.5-.8H48v6h1.4C50.5 51.1 51.2 50.9 51.8 50.3zM63.6 43.1v1.9H59v2.1h4.4v1.9H59v3.9h-2.2v-9.9H63.6z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="655.359" height="655.359" fill-rule="evenodd" clip-rule="evenodd" image-rendering="optimizeQuality" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" viewBox="0 0 6.827 6.827" id="png-file"><circle cx="3.413" cy="3.413" r="3.413" fill="#42a5f5"></circle><path fill="#fffffe" d="M1.744 4.074h.27V1.75a.164.164 0 0 1 .164-.164H4.3l.023.022.544.545.023.023v1.898h.191a.198.198 0 0 1 .198.199v.77a.198.198 0 0 1-.198.198H1.744a.198.198 0 0 1-.198-.199v-.769a.198.198 0 0 1 .198-.199zm.425 0h2.567V2.24l-.004-.004h-.498v-.495H2.178a.009.009 0 0 0-.007.003.009.009 0 0 0-.002.006v2.324zm.389-.7h1.789v.156h-1.79v-.156zm0-.544h1.789v.156h-1.79V2.83zm.07 2.094V4.37h.179c.068 0 .112.003.132.009a.145.145 0 0 1 .08.054.172.172 0 0 1 .032.107.18.18 0 0 1-.018.086.152.152 0 0 1-.047.055.162.162 0 0 1-.058.026.637.637 0 0 1-.116.008h-.073v.209h-.111zm.111-.46v.157H2.8a.29.29 0 0 0 .089-.009.074.074 0 0 0 .034-.027.075.075 0 0 0 .013-.043.072.072 0 0 0-.018-.05.077.077 0 0 0-.044-.024.532.532 0 0 0-.08-.004h-.055zm.405.46V4.37h.109l.226.37v-.37h.104v.554h-.112l-.223-.361v.36h-.104zm.814-.204v-.093H4.2v.22a.372.372 0 0 1-.237.086.304.304 0 0 1-.15-.036.232.232 0 0 1-.098-.105.337.337 0 0 1-.032-.147.32.32 0 0 1 .036-.154.244.244 0 0 1 .106-.102.285.285 0 0 1 .132-.028.26.26 0 0 1 .161.043.195.195 0 0 1 .075.12l-.111.02a.118.118 0 0 0-.044-.064.133.133 0 0 0-.08-.024.152.152 0 0 0-.117.047c-.029.03-.043.077-.043.138 0 .065.014.114.044.147.029.033.067.05.114.05a.194.194 0 0 0 .07-.014.244.244 0 0 0 .061-.034v-.07h-.128z"></path><path fill="none" d="M1.547 1.547H5.28V5.28H1.547z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 128 128" viewBox="0 0 128 128" id="Alert"><path fill="#f34093" d="M122.9,100.2L74.3,15.9c-4.6-7.9-16-7.9-20.6,0L5.1,100.2C0.5,108.1,6.2,118,15.4,118h97.3
|
||||
C121.8,118,127.5,108.1,122.9,100.2z M63.9,101c-3.5-0.1-6.7-3.3-6.6-6.8c0.1-3.5,3.3-6.7,6.8-6.6c3.5,0.1,6.7,3.3,6.6,6.8
|
||||
C70.6,98,67.4,101.1,63.9,101z M71.3,51.8c-0.7,7.8-1.5,15.6-2.3,23.4c-0.5,4.4-3.2,6.1-7.3,4.5c-1-0.4-2-2-2.2-3.2
|
||||
C58.6,70,58,63.4,57.3,56.8c-0.3-2.8-0.5-5.6-0.8-8.5c-0.4-3.3,0.6-4.5,4-4.5c1.1,0,2.3,0,3.4,0C72,43.8,72,43.8,71.3,51.8z" class="color343433 svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 621 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" id="Messages"><path fill="#4687ba" d="m447.372 413.112-17.544-52.629c-1-3.002-.674-6.23.775-9.043 13.184-25.615 18.629-55.858 12.925-87.736-8.746-48.868-44.53-89.475-90.943-105.048 11.976 28.924 15.628 61.084 9.645 92.984-12.155 64.837-64.074 116.246-129.191 127.924-8.429 1.512-16.945 2.248-25.396 2.463 19.776 21.336 46.173 36.503 75.619 41.784 31.682 5.682 61.784.393 87.322-12.594 2.802-1.425 6.007-1.742 8.99-.748l52.83 17.61c9.251 3.084 18.052-5.716 14.968-14.967z" class="color173042 svgShape"></path><path fill="#4687ba" d="M177.161 85.744C122.283 95.941 78.306 140.526 68.472 195.47c-5.704 31.878-.259 62.121 12.925 87.736 1.449 2.813 1.775 6.041.776 9.043l-17.545 52.629c-3.083 9.251 5.717 18.051 14.968 14.968l52.83-17.61c2.984-.994 6.19-.677 8.991.748 25.537 12.987 55.638 18.276 87.321 12.594 54.809-9.829 99.281-53.698 109.541-108.428 18.078-96.414-64.733-179.316-161.118-161.406zm34.938 177.536h-68.234c-6.73 0-12.185-5.454-12.185-12.185 0-6.73 5.455-12.185 12.185-12.185h68.234c6.731 0 12.185 5.455 12.185 12.185 0 6.731-5.454 12.185-12.185 12.185zm48.739-48.739H143.864c-6.73 0-12.185-5.454-12.185-12.185 0-6.73 5.455-12.185 12.185-12.185h116.973c6.731 0 12.185 5.455 12.185 12.185.001 6.731-5.453 12.185-12.184 12.185z" class="color173042 svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" id="phone" x="0" y="0" version="1.1" viewBox="0 0 29 29" xml:space="preserve"><path d="M5.661 23.339c4.882 4.882 12.796 4.882 17.678 0 4.882-4.882 4.882-12.796 0-17.678s-12.796-4.882-17.678 0C.78 10.543.78 18.457 5.661 23.339zm5.545-16.613l1.86 1.86c.372.372.451.947.193 1.406l-.699 1.241a.781.781 0 0 0 .129.937l4.141 4.141a.781.781 0 0 0 .937.128l1.241-.699a1.173 1.173 0 0 1 1.406.193l1.861 1.861a1.175 1.175 0 0 1 0 1.66l-.881.881a3.135 3.135 0 0 1-3.786.493l-.084-.048a24.54 24.54 0 0 1-8.868-8.681l-.423-.706a3.128 3.128 0 0 1 .469-3.823l.844-.844a1.173 1.173 0 0 1 1.66 0z" fill="#4687ba" class="color000000 svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 678 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" viewBox="0 0 512 512" id="Sms"><circle cx="256" cy="256" r="256" fill="#4687ba" class="color00aebb svgShape"></circle><path fill="#ffffff" d="M256 129.3c-88.4 0-160 52-160 116.2 0 26.6 12.3 51.1 33 70.7-11.6 26.2-22.6 66.2-22.6 66.2 6.1 3.1 60.9-23.9 78.4-32.8 21.4 7.7 45.6 12.1 71.2 12.1 88.4 0 160-52 160-116.2s-71.6-116.2-160-116.2zm-59.2 148.9c-5.2 3.8-12 5.7-20.4 5.7-8.3 0-15.4-2.1-21.4-6.2-6-4.1-8.8-10.3-8.7-18.5l.1-.3h15c0 4.6 1.3 7.9 4 10.1 2.7 2.2 6.3 3.2 10.9 3.2 4.1 0 7.3-.9 9.5-2.6 2.2-1.7 3.3-4 3.3-6.9 0-3-1-5.3-3.1-7.1-2.1-1.8-5.7-3.5-10.9-5.1-8.9-2.7-15.6-5.8-20.3-9.5-4.6-3.6-6.9-8.6-6.9-14.9 0-6.3 2.6-11.5 7.8-15.5 5.2-4 11.8-6 19.9-6 8.5 0 15.4 2.2 20.6 6.5 5.2 4.3 7.7 10 7.5 16.9l-.1.3h-15c0-3.8-1.2-6.8-3.5-8.9-2.3-2.1-5.6-3.1-9.8-3.1-3.8 0-6.8.9-8.8 2.8-2.1 1.8-3.1 4.2-3.1 7 0 2.6 1.1 4.8 3.4 6.4 2.3 1.7 6.2 3.5 11.7 5.3 8.5 2.4 14.9 5.5 19.4 9.4 4.4 3.9 6.7 9 6.7 15.3-.1 6.7-2.7 11.9-7.8 15.7zm99.3 4.7h-15.5v-52.6l-.3-.1-19.1 52.7h-10.5l-19.1-52.8-.3.1v52.7h-15.5v-77.1h20.3l19.6 56.8h.3l19.8-56.8H296v77.1zm62.1-4.7c-5.2 3.8-12 5.7-20.4 5.7-8.3 0-15.4-2.1-21.4-6.2-5.9-4.1-8.8-10.3-8.7-18.5l.1-.3h15c0 4.6 1.3 7.9 4 10.1 2.7 2.2 6.3 3.2 10.9 3.2 4.1 0 7.3-.9 9.5-2.6 2.2-1.7 3.3-4 3.3-6.9 0-3-1-5.3-3.1-7.1-2.1-1.8-5.7-3.5-10.9-5.1-8.9-2.7-15.7-5.8-20.3-9.5-4.6-3.6-6.9-8.6-6.9-14.9 0-6.3 2.6-11.5 7.8-15.5 5.2-4 11.8-6 19.9-6 8.5 0 15.4 2.2 20.6 6.5 5.2 4.3 7.7 10 7.5 16.9l-.1.3h-15c0-3.8-1.2-6.8-3.5-8.9-2.3-2.1-5.6-3.1-9.8-3.1-3.8 0-6.8.9-8.8 2.8-2.1 1.8-3.1 4.2-3.1 7 0 2.6 1.1 4.8 3.4 6.4 2.3 1.7 6.2 3.5 11.7 5.3 8.5 2.4 14.9 5.5 19.4 9.4 4.4 3.9 6.7 9 6.7 15.3-.1 6.7-2.6 11.9-7.8 15.7z" class="colorffffff svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 101 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="1200" height="1227" viewBox="0 0 1200 1227" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M714.163 519.284L1160.89 0H1055.03L667.137 450.887L357.328 0H0L468.492 681.821L0 1226.37H105.866L515.491 750.218L842.672 1226.37H1200L714.137 519.284H714.163ZM569.165 687.828L521.697 619.934L144.011 79.6944H306.615L611.412 515.685L658.88 583.579L1055.08 1150.3H892.476L569.165 687.854V687.828Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 430 B |
|
After Width: | Height: | Size: 206 KiB |
|
After Width: | Height: | Size: 245 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 125 KiB |
|
After Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
@@ -1,98 +1,31 @@
|
||||
import { Field, Form, Formik } from "formik";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import * as Yup from "yup";
|
||||
import usersService from "../../services/UsersService";
|
||||
import { tableReload } from "../../store/TableReloads";
|
||||
import InputCom from "../Helpers/Inputs/InputCom";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import {
|
||||
validationSchema as VS,
|
||||
useDispatch,
|
||||
useSelector,
|
||||
usersService,
|
||||
initialValues as IV,
|
||||
initialReqState,
|
||||
useState,
|
||||
tableReload,
|
||||
Formik,
|
||||
InputCom,
|
||||
Field,
|
||||
Form,
|
||||
LoadingSpinner,
|
||||
} from "./settings";
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
country: Yup.string()
|
||||
.min(1, "Minimum 3 characters")
|
||||
.max(25, "Maximum 25 characters")
|
||||
.required("Country is required"),
|
||||
price: Yup.string()
|
||||
.typeError("Invalid number")
|
||||
.min(1, "Price must be greater than 0")
|
||||
.test("no-e", "Invalid number", (value) => {
|
||||
if (value && /\d+e/.test(value)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.required("Price is required"),
|
||||
title: Yup.string()
|
||||
.min(5, "Minimum 5 characters")
|
||||
.max(149, "Maximum 149 characters")
|
||||
.required("Title is required"),
|
||||
description: Yup.string()
|
||||
.min(5, "Minimum 5 characters")
|
||||
.max(299, "Maximum 299 characters")
|
||||
.required("Description is required"),
|
||||
job_detail: Yup.string()
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(1440, "Maximum 1440 characters")
|
||||
.required("Details is required"),
|
||||
timeline_days: Yup.number()
|
||||
.typeError("you must specify a number")
|
||||
.min(1, "Price must be greater than 0")
|
||||
.required("Timeline is required"),
|
||||
category: Yup.array().min(1, "Select at least one checkbox"),
|
||||
});
|
||||
const validationSchema = VS;
|
||||
|
||||
function AddJob({ popUpHandler, categories }) {
|
||||
const ApiCall = new usersService();
|
||||
const { walletDetails } = useSelector((state) => state.walletDetails);
|
||||
|
||||
let dispatch = useDispatch();
|
||||
|
||||
let [currency, setCurrency] = useState({
|
||||
loading: true,
|
||||
status: false,
|
||||
data: null,
|
||||
}); // To Hold the array of currency getUserCurrency returns
|
||||
const [requestStatus, setRequestStatus] = useState(initialReqState); // Holds state when submit button is pressed
|
||||
|
||||
let initialValues = {
|
||||
// initial values for formik
|
||||
country: "",
|
||||
price: "",
|
||||
title: "",
|
||||
description: "",
|
||||
job_detail: "",
|
||||
timeline_days: "",
|
||||
category: [],
|
||||
};
|
||||
|
||||
let [requestStatus, setRequestStatus] = useState({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "",
|
||||
}); // Holds state when submit button is pressed
|
||||
|
||||
// FUNCTION TO GET Currency
|
||||
const getUserCurrency = () => {
|
||||
setCurrency((prev) => ({ ...prev, loading: true }));
|
||||
ApiCall.getUserWallets()
|
||||
.then((res) => {
|
||||
if (res.data.internal_return < 0) {
|
||||
setCurrency({ loading: false, status: true, data: [] });
|
||||
return;
|
||||
}
|
||||
|
||||
setCurrency({
|
||||
loading: false,
|
||||
status: true,
|
||||
data: res.data.result_list,
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
setCurrency({ loading: false, status: false, data: [] });
|
||||
});
|
||||
};
|
||||
|
||||
// FUNCTION TO HANDLE ADD JOB FORM
|
||||
const handleAddJob = (values, helpers) => {
|
||||
let reqData = {
|
||||
const handleAddJob = async (values, helpers) => {
|
||||
const reqData = {
|
||||
country: values?.country,
|
||||
price: Number(values.price) * 100,
|
||||
title: values?.title,
|
||||
@@ -103,19 +36,19 @@ function AddJob({ popUpHandler, categories }) {
|
||||
};
|
||||
|
||||
setRequestStatus({ loading: true, status: false, message: "" });
|
||||
ApiCall.jobManagerCreateJob(reqData)
|
||||
.then((res) => {
|
||||
if (res.data.internal_return < 1) {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "Could not complete your request at the moment",
|
||||
});
|
||||
setTimeout(() => {
|
||||
popUpHandler();
|
||||
}, 1500);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await ApiCall.jobManagerCreateJob(reqData);
|
||||
if (res.data.internal_return < 1) {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "Could not complete your request at the moment",
|
||||
});
|
||||
setTimeout(() => {
|
||||
popUpHandler();
|
||||
}, 1500);
|
||||
} else {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: true,
|
||||
@@ -125,65 +58,89 @@ function AddJob({ popUpHandler, categories }) {
|
||||
dispatch(tableReload({ type: "JOBTABLE" }));
|
||||
popUpHandler();
|
||||
}, 1000);
|
||||
})
|
||||
.catch((err) => {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "Opps! something went wrong. Try Again",
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
setTimeout(() => {
|
||||
setRequestStatus({ loading: false, status: false, message: "" });
|
||||
}, 5000);
|
||||
}
|
||||
} catch (err) {
|
||||
setRequestStatus({
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "Oops! Something went wrong. Try Again",
|
||||
});
|
||||
} finally {
|
||||
setTimeout(() => {
|
||||
setRequestStatus({ loading: false, status: false, message: "" });
|
||||
}, 5000);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getUserCurrency();
|
||||
}, []);
|
||||
// For form initial values
|
||||
const initialValues = {
|
||||
// initial values for formik
|
||||
country: walletDetails.data.length == 1 ? walletDetails.data[0].country : '',
|
||||
price: "",
|
||||
title: "",
|
||||
description: "",
|
||||
job_detail: "",
|
||||
timeline_days: "",
|
||||
category: [],
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="add-job p-5 w-full bg-white rounded-md flex flex-col justify-between">
|
||||
<Formik
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={handleAddJob}
|
||||
>
|
||||
{(props) => {
|
||||
return (
|
||||
<Form>
|
||||
<div className="flex flex-col-reverse sm:flex-row">
|
||||
<div className="fields w-full">
|
||||
{/* inputs starts here */}
|
||||
<div className="xl:flex xl:space-x-7 mb-[5px]">
|
||||
<div className="field w-full mb-6 xl:mb-0">
|
||||
<label
|
||||
htmlFor="country"
|
||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex item-center gap-1"
|
||||
>
|
||||
Currency
|
||||
{props.errors.country && props.touched.country && <span className="text-[12px] text-red-500">{props.errors.country}</span>}
|
||||
</label>
|
||||
<select
|
||||
id="country"
|
||||
name="country"
|
||||
value={props.values.country}
|
||||
className={`input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none`}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
>
|
||||
{currency.loading ? (
|
||||
<option className="text-slate-500 text-lg" value="">
|
||||
Loading...
|
||||
</option>
|
||||
) : currency.data.length ? (
|
||||
<>
|
||||
<Form className='contents'>
|
||||
<div className="add-job p-5 w-full h-full rounded-md flex flex-col justify-between overflow-y-auto">
|
||||
<div className="flex flex-col-reverse sm:flex-row">
|
||||
<div className="fields w-full">
|
||||
{/* inputs starts here */}
|
||||
<div className="xl:flex xl:space-x-7 mb-[5px]">
|
||||
<div className="field w-full mb-[5px] xl:mb-0">
|
||||
<label
|
||||
htmlFor="country"
|
||||
className="job-label job-label-flex"
|
||||
>
|
||||
<span>Currency</span>
|
||||
{props.errors.country && props.touched.country && (
|
||||
<span className="text-[12px] text-red-500">
|
||||
{props.errors.country}
|
||||
</span>
|
||||
)}
|
||||
</label>
|
||||
<select
|
||||
id="country"
|
||||
name="country"
|
||||
value={props.values.country}
|
||||
className={`input-field p-2 mt-3 rounded-full placeholder:text-base text-dark-gray w-full h-[42px] bg-slate-100 focus:ring-0 focus:outline-none border`}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
disabled={walletDetails.data.length == 1}
|
||||
>
|
||||
{walletDetails?.loading ? (
|
||||
<option className="text-slate-500 text-lg" value="">
|
||||
Select a currency
|
||||
Loading...
|
||||
</option>
|
||||
{currency.data?.map((item, index) => (
|
||||
) : walletDetails.data.length > 1 ? (
|
||||
<>
|
||||
<option className="text-slate-500 text-lg" value="">
|
||||
Select a currency
|
||||
</option>
|
||||
{walletDetails.data?.map((item, index) => (
|
||||
<option
|
||||
key={index}
|
||||
className="text-slate-500 text-lg"
|
||||
value={item?.country}
|
||||
>
|
||||
{item?.description}
|
||||
</option>
|
||||
))}
|
||||
</>
|
||||
) : walletDetails.data.length == 1 ?
|
||||
<>
|
||||
{walletDetails.data?.map((item, index) => (
|
||||
<option
|
||||
key={index}
|
||||
className="text-slate-500 text-lg"
|
||||
@@ -193,215 +150,274 @@ function AddJob({ popUpHandler, categories }) {
|
||||
</option>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<option className="text-slate-500 text-lg" value="">
|
||||
No Options Found! Try Again
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
:(
|
||||
<option className="text-slate-500 text-lg" value="">
|
||||
No Options Found! Try Again
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Price */}
|
||||
<div className="field w-full mb-[5px] xl:mb-0">
|
||||
<InputCom
|
||||
fieldClass="px-6 text-right flex"
|
||||
label="Reward"
|
||||
labelClass=""
|
||||
type="number"
|
||||
name="price"
|
||||
placeholder="0"
|
||||
value={props.values.price}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={
|
||||
props.errors.price &&
|
||||
props.touched.price &&
|
||||
props.errors.price
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Timeline */}
|
||||
<div className="field w-full mb-[5px] xl:mb-0">
|
||||
<label
|
||||
className="job-label job-label-flex"
|
||||
htmlFor="timeline_days"
|
||||
>
|
||||
Timeline
|
||||
<span className="text-green-700 text-[12px] tracking-wide">
|
||||
- Duration
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<Field
|
||||
component="select"
|
||||
name="timeline_days"
|
||||
className={`input-field p-2 mt-3 rounded-full placeholder:text-base text-dark-gray w-full h-[42px] bg-slate-100 focus:ring-0 focus:outline-none border ${
|
||||
props.errors.timeline_days &&
|
||||
props.touched.timeline_days
|
||||
? "border-[#ff0a0a63] shadow-red-500 animate-shake"
|
||||
: "dark:border-[#5e6278]"
|
||||
}`}
|
||||
value={props.values.timeline_days}
|
||||
>
|
||||
<option value="" className='text-slate-500 text-lg'>Select Duration</option>
|
||||
{publicArray.map(({ name, duration }, idx) => (
|
||||
<option
|
||||
key={idx}
|
||||
className="text-slate-500 text-lg"
|
||||
value={duration}
|
||||
>
|
||||
{name}
|
||||
</option>
|
||||
))}
|
||||
</Field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Price */}
|
||||
<div className="field w-full">
|
||||
{/* Title */}
|
||||
<div className="field w-full mb-[5px]">
|
||||
<InputCom
|
||||
fieldClass="px-6 text-right"
|
||||
label="Price"
|
||||
labelClass="tracking-wide"
|
||||
inputBg="bg-slate-100"
|
||||
type="number"
|
||||
name="price"
|
||||
placeholder="0"
|
||||
value={props.values.price}
|
||||
fieldClass="px-6"
|
||||
label="Title"
|
||||
labelClass=""
|
||||
type="text"
|
||||
name="title"
|
||||
value={props.values.title}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.price && props.touched.price && props.errors.price}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Title */}
|
||||
<div className="field w-full mb-[5px]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
label="Title"
|
||||
labelClass="tracking-wide"
|
||||
inputBg="bg-slate-100"
|
||||
type="text"
|
||||
name="title"
|
||||
value={props.values.title}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.title && props.touched.title && props.errors.title}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Description */}
|
||||
<div className="field w-full mb-[5px]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
label="Description"
|
||||
labelClass="tracking-wide"
|
||||
inputBg="bg-slate-100"
|
||||
type="text"
|
||||
name="description"
|
||||
value={props.values.description}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.description && props.touched.description && props.errors.description}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Details */}
|
||||
<div className="field flex flex-col sm:flex-row w-full mb-[5px] gap-2">
|
||||
<div className="sm:w-[60%] w-full">
|
||||
<label
|
||||
htmlFor="Job Delivery Details"
|
||||
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex items-center gap-1'
|
||||
>
|
||||
Job Delivery Details
|
||||
{props.errors.job_detail && props.touched.job_detail && <span className="text-[12px] text-red-500">{props.errors.job_detail}</span>}
|
||||
</label>
|
||||
<textarea
|
||||
id="Job Delivery Details"
|
||||
rows="5"
|
||||
className={`input-field px-3 py-2 placeholder:text-base text-dark-gray dark:text-white w-full h-[100px] bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-[#dce4e9] rounded-[10px]`}
|
||||
style={{ resize: "none" }}
|
||||
name="job_detail"
|
||||
value={props.values.job_detail}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
error={
|
||||
props.errors.title &&
|
||||
props.touched.title &&
|
||||
props.errors.title
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="sm:w-[35%] w-full">
|
||||
<div
|
||||
htmlFor="Job Categories"
|
||||
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'
|
||||
id="checked-group"
|
||||
>
|
||||
Categories
|
||||
</div>
|
||||
<div
|
||||
className="sm:flex-col flex flex-wrap px-3 mt-3"
|
||||
role="group"
|
||||
aria-labelledby="checked-group"
|
||||
>
|
||||
{Object?.entries(categories).map(([key, value]) => (
|
||||
<label
|
||||
key={key}
|
||||
className="flex gap-1 w-full items-center"
|
||||
>
|
||||
<Field
|
||||
type="checkbox"
|
||||
name="category"
|
||||
value={key}
|
||||
/>
|
||||
<span className="text-[13.975px]">{value}</span>
|
||||
</label>
|
||||
))}
|
||||
<span className="h-5 text-sm italic text-[#cf3917]">
|
||||
{props.errors.category &&
|
||||
props.touched.category &&
|
||||
"please select a category"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="field w-full mb-[5px]">
|
||||
<div className={`flex items-center justify-between mb-2.5`}>
|
||||
<label
|
||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
|
||||
htmlFor="timeline_days"
|
||||
>
|
||||
Timeline
|
||||
<span className="text-green-700 text-sm tracking-wide">
|
||||
- Expected duration of this task
|
||||
</span>
|
||||
</label>
|
||||
{/* Description */}
|
||||
<div className="field w-full mb-[5px]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
label="Description"
|
||||
labelClass=""
|
||||
type="text"
|
||||
name="description"
|
||||
value={props.values.description}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={
|
||||
props.errors.description &&
|
||||
props.touched.description &&
|
||||
props.errors.description
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Field
|
||||
component="select"
|
||||
name="timeline_days"
|
||||
className={`input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none ${
|
||||
props.errors.timeline_days &&
|
||||
props.touched.timeline_days
|
||||
? "border-[#ff0a0a63] shadow-red-500 border-[0.5px] animate-shake"
|
||||
: "border border-[#f5f8fa] dark:border-[#5e6278]"
|
||||
}`}
|
||||
value={props.values.timeline_days}
|
||||
>
|
||||
<option value="">Select Duration</option>
|
||||
{publicArray.map(({ name, duration }, idx) => (
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
value={duration}
|
||||
{/* Details */}
|
||||
<div className="field flex flex-col sm:flex-row w-full mb-[5px] gap-2">
|
||||
<div className="sm:w-[60%] w-full">
|
||||
<label
|
||||
htmlFor="Job Delivery Details"
|
||||
className="job-label job-label-flex"
|
||||
>
|
||||
{name}
|
||||
</option>
|
||||
))}
|
||||
</Field>
|
||||
</div>
|
||||
{/* inputs ends here */}
|
||||
</div>
|
||||
</div>
|
||||
Job Delivery Details
|
||||
{props.errors.job_detail &&
|
||||
props.touched.job_detail && (
|
||||
<span className="text-[12px] text-red-500">
|
||||
{props.errors.job_detail}
|
||||
</span>
|
||||
)}
|
||||
</label>
|
||||
<textarea
|
||||
id="Job Delivery Details"
|
||||
rows="5"
|
||||
className={`input-field px-3 py-2 placeholder:text-base text-dark-gray dark:text-white w-full h-[100px] bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-[#dce4e9] rounded-[10px] border`}
|
||||
style={{ resize: "none" }}
|
||||
name="job_detail"
|
||||
value={props.values.job_detail}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* ERROR DISPLAY AND SUBMIT BUTTON */}
|
||||
<div className="content-footer w-full">
|
||||
{/* error or success display */}
|
||||
{requestStatus.message != "" &&
|
||||
(!requestStatus.status ? (
|
||||
<div
|
||||
className={`relative p-4 my-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||
>
|
||||
{requestStatus.message}
|
||||
<div className="sm:w-[35%] w-full">
|
||||
<label
|
||||
htmlFor="Job Categories"
|
||||
className='job-label'
|
||||
id="checked-group"
|
||||
>
|
||||
Categories
|
||||
</label>
|
||||
<div
|
||||
className="sm:flex-col flex flex-wrap px-3 mt-3"
|
||||
role="group"
|
||||
aria-labelledby="checked-group"
|
||||
>
|
||||
{categories ? (
|
||||
<>
|
||||
{Object?.entries(categories).map(([key, value]) => (
|
||||
<label
|
||||
key={key}
|
||||
className="flex gap-1 w-full items-center"
|
||||
>
|
||||
<Field
|
||||
type="checkbox"
|
||||
name="category"
|
||||
value={key}
|
||||
/>
|
||||
<span className="text-[13.975px]">{value}</span>
|
||||
</label>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<label className="flex gap-1 w-full items-center">
|
||||
<Field type="checkbox" name="category" />
|
||||
<span className="text-[13.975px]">null</span>
|
||||
</label>
|
||||
)}
|
||||
<span className="h-5 text-sm italic text-[#cf3917]">
|
||||
{props.errors.category &&
|
||||
props.touched.category &&
|
||||
"please select a category"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
requestStatus.status && (
|
||||
|
||||
{/* <div className="field w-full mb-[5px]">
|
||||
<div className={`flex items-center justify-between mb-2.5`}>
|
||||
<label
|
||||
className="job-label"
|
||||
htmlFor="timeline_days"
|
||||
>
|
||||
Timeline
|
||||
<span className="text-green-700 text-sm tracking-wide">
|
||||
- Expected duration of this task
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<Field
|
||||
component="select"
|
||||
name="timeline_days"
|
||||
className={`input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none border ${
|
||||
props.errors.timeline_days &&
|
||||
props.touched.timeline_days
|
||||
? "border-[#ff0a0a63] shadow-red-500 border-[0.5px] animate-shake"
|
||||
: "border border-[#f5f8fa] dark:border-[#5e6278]"
|
||||
}`}
|
||||
value={props.values.timeline_days}
|
||||
>
|
||||
<option value="">Select Duration</option>
|
||||
{publicArray.map(({ name, duration }, idx) => (
|
||||
<option
|
||||
key={idx}
|
||||
className="text-slate-500 text-lg"
|
||||
value={duration}
|
||||
>
|
||||
{name}
|
||||
</option>
|
||||
))}
|
||||
</Field>
|
||||
</div> */}
|
||||
{/* inputs ends here */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ERROR DISPLAY AND SUBMIT BUTTON */}
|
||||
<div className="content-footer w-full">
|
||||
{/* error or success display */}
|
||||
{requestStatus.message != "" &&
|
||||
(!requestStatus.status ? (
|
||||
<div
|
||||
className={`relative p-4 my-4 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||
className={`relative p-4 my-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||
>
|
||||
{requestStatus.message}
|
||||
</div>
|
||||
)
|
||||
))}
|
||||
{/* End of error or success display */}
|
||||
|
||||
<div className="w-full h-[70px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
|
||||
<div className="flex items-center space-x-4 mr-9">
|
||||
<button
|
||||
type="button"
|
||||
className="text-18 text-light-red tracking-wide "
|
||||
>
|
||||
<span
|
||||
className="border-b dark:border-[#5356fb29] border-light-red"
|
||||
onClick={popUpHandler}
|
||||
>
|
||||
{" "}
|
||||
Cancel
|
||||
</span>
|
||||
</button>
|
||||
|
||||
{requestStatus.loading ? (
|
||||
<LoadingSpinner size="8" color="sky-blue" />
|
||||
) : (
|
||||
<button
|
||||
type="submit"
|
||||
className="w-[152px] h-[46px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
// className='w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white'
|
||||
>
|
||||
Add Job
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
requestStatus.status && (
|
||||
<div
|
||||
className={`relative p-4 my-4 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||
>
|
||||
{requestStatus.message}
|
||||
</div>
|
||||
)
|
||||
))}
|
||||
{/* End of error or success display */}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div className="modal-footer-wrapper grid grid-cols-1 xxs:grid-cols-3">
|
||||
<div className="w-full col-span-1 xxs:col-span-2 xxs:col-start-2 flex justify-between items-center">
|
||||
<button
|
||||
type="button"
|
||||
className="custom-btn border border-light-red text-light-red"
|
||||
>
|
||||
<span
|
||||
className="px-2"
|
||||
onClick={popUpHandler}
|
||||
>
|
||||
{" "}
|
||||
Cancel
|
||||
</span>
|
||||
</button>
|
||||
|
||||
{requestStatus?.loading ? (
|
||||
<LoadingSpinner size="8" color="sky-blue" />
|
||||
) : (
|
||||
<button
|
||||
type="submit"
|
||||
className="custom-btn btn-gradient text-white"
|
||||
>
|
||||
Add Job
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
);
|
||||
}}
|
||||
</Formik>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
import { Field, Form, Formik } from "formik";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import * as Yup from "yup";
|
||||
import usersService from "../../services/UsersService";
|
||||
import { tableReload } from "../../store/TableReloads";
|
||||
import InputCom from "../Helpers/Inputs/InputCom";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
|
||||
// Initialize state for request values
|
||||
const initialReqState = {
|
||||
loading: false,
|
||||
status: false,
|
||||
message: "",
|
||||
};
|
||||
|
||||
// For form initial values
|
||||
const initialValues = {
|
||||
// initial values for formik
|
||||
country: "",
|
||||
price: "",
|
||||
title: "",
|
||||
description: "",
|
||||
job_detail: "",
|
||||
timeline_days: "",
|
||||
category: [],
|
||||
};
|
||||
|
||||
// const getWalletDetail = (country) => { // A FUNCTION TO GET USER BALANCE BASED ON COUNTRY SELECTED
|
||||
// const walletChecker = walletDetails?.data.find(
|
||||
// (item) => item.country === country
|
||||
// );
|
||||
// return walletChecker ? walletChecker.amount : 0;
|
||||
// };
|
||||
|
||||
// To get the validation schema
|
||||
const validationSchema = Yup.object().shape({
|
||||
country: Yup.string()
|
||||
.min(1, "Minimum 3 characters")
|
||||
.max(25, "Maximum 25 characters")
|
||||
.required("Currency is required"),
|
||||
price: Yup.string()
|
||||
.typeError("Invalid number")
|
||||
.min(1, "Price must be greater than 0")
|
||||
.test("no-e", "Invalid number", (value) => {
|
||||
if (value && /\d+e/.test(value)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.required("Price is required"),
|
||||
title: Yup.string()
|
||||
.min(5, "Minimum 5 characters")
|
||||
.max(80, "Maximum 80 characters")
|
||||
.required("Title is required"),
|
||||
description: Yup.string()
|
||||
.min(5, "Minimum 5 characters")
|
||||
.max(299, "Maximum 299 characters")
|
||||
.required("Description is required"),
|
||||
job_detail: Yup.string()
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(499, "Maximum 499 characters")
|
||||
.required("Details is required"),
|
||||
timeline_days: Yup.number()
|
||||
.typeError("you must specify a number")
|
||||
.min(1, "Price must be greater than 0")
|
||||
.required("Timeline is required"),
|
||||
category: Yup.array().min(1, "Select category"),
|
||||
});
|
||||
|
||||
const getWalletDetail = (countryParams, walletDetails) => {
|
||||
// A FUNCTION TO GET USER BALANCE BASED ON COUNTRY SELECTED
|
||||
const walletChecker = walletDetails?.data.find(
|
||||
(item) => item.country === countryParams
|
||||
);
|
||||
return walletChecker
|
||||
? {
|
||||
description: walletChecker.description,
|
||||
country: walletChecker.country,
|
||||
}
|
||||
: "";
|
||||
};
|
||||
|
||||
export {
|
||||
Field,
|
||||
Form,
|
||||
Formik,
|
||||
useState,
|
||||
useEffect,
|
||||
useDispatch,
|
||||
useSelector,
|
||||
usersService,
|
||||
InputCom,
|
||||
LoadingSpinner,
|
||||
initialReqState,
|
||||
initialValues,
|
||||
validationSchema,
|
||||
getWalletDetail,
|
||||
tableReload
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
import React from 'react'
|
||||
|
||||
export default function AppDownload() {
|
||||
return (
|
||||
<div>
|
||||
<div className='h-screen flex justify-center items-center'>App Download Content Comes here</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import React, { useContext } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { localImgLoad } from "../../lib";
|
||||
|
||||
import DarkModeContext from "../Contexts/DarkModeContext";
|
||||
|
||||
export default function LoginLayout({ slogan, children }) {
|
||||
const bgImg = localImgLoad("images/left-wrenchboard.jpg");
|
||||
const bgImgNig = localImgLoad("images/wrench-home-back-nigeria.jpg");
|
||||
const bgImgCom = localImgLoad("images/wrench-home-back-common.jpg");
|
||||
|
||||
const { countryMode } = useContext(DarkModeContext);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`min-h-screen overflow-y-auto bg-cover bg-center flex flex-col justify-between items-center`}
|
||||
style={{
|
||||
backgroundImage: `url(${countryMode == "NG" ? bgImgNig : bgImgCom})`,
|
||||
}}
|
||||
>
|
||||
|
||||
<div className={`w-full grid grid-cols-1 xl:grid-cols-2`}>
|
||||
{/* <div
|
||||
className={`auth-bg hidden xl:block bg-blue-50 relative bg-cover bg-no-repeat border-0 after:content-[''] after:absolute after:inset-0`}
|
||||
style={{backgroundImage: `url(${bgImg})`}}
|
||||
>
|
||||
</div> */}
|
||||
<div className="p-5 sm:p-7 flex place-content-center xl:col-start-2">
|
||||
<div className="py-5 w-full sm:w-11/12 max-w-[550px] shadow-md bg-slate-50 dark:bg-dark-white rounded-[0.475rem]">
|
||||
<div className="w-full flex justify-center items-center">
|
||||
{children && children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='w-full shadow-md bg-slate-50 dark:bg-dark-white'>
|
||||
<div className="w-full flex flex-col md:flex-row justify-center items-center px-10 py-2">
|
||||
<div className="flex justify-center items-center">
|
||||
<div className="flex items-center">
|
||||
<a
|
||||
href="https://www.wrenchboard.com/about-us"
|
||||
className="text-[#a1a5b7] text-[15px] px-2 font-medium hover:text-[#009ef7]"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
About
|
||||
</a>
|
||||
<a
|
||||
href="https://www.wrenchboard.com/service"
|
||||
className="text-[#a1a5b7] text-[15px] px-2 font-medium hover:text-[#009ef7]"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Services
|
||||
</a>
|
||||
<a
|
||||
href="https://www.wrenchboard.com/contact"
|
||||
className="text-[#a1a5b7] text-[15px] px-2 font-medium hover:text-[#009ef7]"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Contact Us
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-black text-[15px] px-2 font-medium flex items-center gap-1">
|
||||
<span className="dark:text-white">
|
||||
© {new Date().getFullYear()} -
|
||||
</span>
|
||||
<Link to="/" className="text-[#009ef7] ml-1">
|
||||
WrenchBoard
|
||||
</Link>{" "}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -42,7 +42,7 @@ export default function ActivitiesTab({ className }) {
|
||||
<div className="relative w-full overflow-x-auto sm:rounded-lg">
|
||||
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||
<tbody>
|
||||
<tr className="text-base text-thin-light-gray whitespace-nowrap border-b dark:border-[#5356fb29] default-border-b dark:border-[#5356fb29] ottom ">
|
||||
<tr className="text-base text-thin-light-gray whitespace-nowrap border-b default-border-b dark:border-[#5356fb29] ottom ">
|
||||
<td className="py-4 pr-12">List</td>
|
||||
<td className="py-4 text-start px-2">Product Name</td>
|
||||
<td className="py-4 text-start px-2">Price</td>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import usersService from '../../../services/UsersService';
|
||||
import {updateUserDetails} from "../../../store/UserDetails";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { updateUserDetails } from "../../../store/UserDetails";
|
||||
import AuthLayout from "../AuthLayout";
|
||||
|
||||
function FbookRedirect() {
|
||||
@@ -22,38 +22,50 @@ function FbookRedirect() {
|
||||
console.log(codeResponse);
|
||||
|
||||
/*
|
||||
POST /token HTTP/1.1
|
||||
Host: oauth2.googleapis.com
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
https://developers.facebook.com/docs/facebook-login/guides/advanced/manual-flow/#exchangecode
|
||||
Step 1. Get access token by code
|
||||
|
||||
code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
|
||||
client_id=your_client_id&
|
||||
client_secret=your_client_secret&
|
||||
redirect_uri=https%3A//oauth2.example.com/code&
|
||||
grant_type=authorization_code
|
||||
GET https://graph.facebook.com/v17.0/oauth/access_token?
|
||||
client_id={app-id}
|
||||
&redirect_uri={redirect-uri}
|
||||
&client_secret={app-secret}
|
||||
&code={code-parameter}
|
||||
|
||||
https://developers.facebook.com/docs/facebook-login/guides/access-tokens/get-long-lived
|
||||
Step 2. Get long-lived token by access token
|
||||
|
||||
curl -i -X GET "https://graph.facebook.com/{graph-api-version}/oauth/access_token?
|
||||
grant_type=fb_exchange_token&
|
||||
client_id={app-id}&
|
||||
client_secret={app-secret}&
|
||||
fb_exchange_token={your-access-token}"
|
||||
*/
|
||||
|
||||
// process.env.REACT_APP_FACEBOOK_CLIENT_ID
|
||||
// process.env.REACT_APP_FACEBOOK_CLIENT_SCOPE
|
||||
|
||||
var reqData = {
|
||||
auth_type: "FACEBOOK",
|
||||
code: codeResponse,
|
||||
redirect_uri: process.env.REACT_APP_GOOGLE_REDIRECT_URL,
|
||||
redirect_uri: process.env.REACT_APP_FACEBOOK_REDIRECT_URL,
|
||||
};
|
||||
// userApi
|
||||
// .authStart(reqData)
|
||||
// .then((res) => {
|
||||
// if (res.status == 200 && res.data.internal_return >= 0 && res.data.member_id && res.data.uid && res.data.session) {
|
||||
// localStorage.setItem("member_id", `${res.data.member_id}`);
|
||||
// localStorage.setItem("uid", `${res.data.uid}`);
|
||||
// localStorage.setItem("session_token", `${res.data.session}`);
|
||||
// dispatch(updateUserDetails({...res.data}));
|
||||
// navigate('/', {replace: true})
|
||||
// return
|
||||
// }
|
||||
// navigate('/login', {state: {error: true}})
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// navigate('/login', {state: {error: true}})
|
||||
// console.log(error);
|
||||
// });
|
||||
userApi
|
||||
.authStart(reqData)
|
||||
.then((res) => {
|
||||
if (res.status == 200 && res.data.internal_return >= 0 && res.data.member_id && res.data.uid && res.data.session) {
|
||||
localStorage.setItem("member_id", `${res.data.member_id}`);
|
||||
localStorage.setItem("uid", `${res.data.uid}`);
|
||||
localStorage.setItem("session_token", `${res.data.session}`);
|
||||
dispatch(updateUserDetails({...res.data}));
|
||||
navigate('/', {replace: true})
|
||||
return
|
||||
}
|
||||
navigate('/login', {state: {error: true}})
|
||||
})
|
||||
.catch((error) => {
|
||||
navigate('/login', {state: {error: true}})
|
||||
console.log(error);
|
||||
});
|
||||
},[])
|
||||
return (
|
||||
<AuthLayout>
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import usersService from '../../../services/UsersService';
|
||||
import {updateUserDetails} from "../../../store/UserDetails";
|
||||
import React, { useEffect } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import { updateUserDetails } from "../../../store/UserDetails";
|
||||
import AuthLayout from "../AuthLayout";
|
||||
|
||||
function Redirect() {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const userApi = new usersService();
|
||||
const dispatch = useDispatch()
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const userApi = new usersService();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const queryParams = new URLSearchParams(location?.search);
|
||||
const codeResponse = queryParams.get("code");
|
||||
const queryParams = new URLSearchParams(location?.search);
|
||||
const codeResponse = queryParams.get("code");
|
||||
|
||||
useEffect(()=>{
|
||||
if(!codeResponse){
|
||||
navigate('/login', {state: {error: true}})
|
||||
return
|
||||
}
|
||||
console.log(codeResponse);
|
||||
/*
|
||||
useEffect(() => {
|
||||
if (!codeResponse) {
|
||||
navigate("/login", { state: { error: true } });
|
||||
return;
|
||||
}
|
||||
console.log(codeResponse);
|
||||
/*
|
||||
POST /token HTTP/1.1
|
||||
Host: oauth2.googleapis.com
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
@@ -31,34 +31,40 @@ function Redirect() {
|
||||
redirect_uri=https%3A//oauth2.example.com/code&
|
||||
grant_type=authorization_code
|
||||
*/
|
||||
var reqData = {
|
||||
auth_type: "GOOGLE",
|
||||
code: codeResponse,
|
||||
redirect_uri: process.env.REACT_APP_GOOGLE_REDIRECT_URL,
|
||||
};
|
||||
userApi
|
||||
.authStart(reqData)
|
||||
.then((res) => {
|
||||
if (res.status == 200 && res.data.internal_return >= 0 && res.data.member_id && res.data.uid && res.data.session) {
|
||||
localStorage.setItem("member_id", `${res.data.member_id}`);
|
||||
localStorage.setItem("uid", `${res.data.uid}`);
|
||||
localStorage.setItem("session_token", `${res.data.session}`);
|
||||
dispatch(updateUserDetails({...res.data}));
|
||||
navigate('/', {replace: true})
|
||||
return
|
||||
}
|
||||
navigate('/login', {state: {error: true}})
|
||||
})
|
||||
.catch((error) => {
|
||||
navigate('/login', {state: {error: true}})
|
||||
console.log(error);
|
||||
});
|
||||
},[])
|
||||
var reqData = {
|
||||
auth_type: "GOOGLE",
|
||||
code: codeResponse,
|
||||
redirect_uri: process.env.REACT_APP_GOOGLE_REDIRECT_URL,
|
||||
};
|
||||
userApi
|
||||
.authStart(reqData)
|
||||
.then((res) => {
|
||||
if (
|
||||
res.status == 200 &&
|
||||
res.data.internal_return >= 0 &&
|
||||
res.data.member_id &&
|
||||
res.data.uid &&
|
||||
res.data.session
|
||||
) {
|
||||
localStorage.setItem("member_id", `${res.data.member_id}`);
|
||||
localStorage.setItem("uid", `${res.data.uid}`);
|
||||
localStorage.setItem("session_token", `${res.data.session}`);
|
||||
dispatch(updateUserDetails({ ...res.data }));
|
||||
navigate("/", { replace: true });
|
||||
return;
|
||||
}
|
||||
navigate("/login", { state: { error: true } });
|
||||
})
|
||||
.catch((error) => {
|
||||
navigate("/login", { state: { error: true } });
|
||||
console.log(error);
|
||||
});
|
||||
}, []);
|
||||
return (
|
||||
<AuthLayout>
|
||||
<div className='min-h-[70vh]'>Redirecting ... </div>
|
||||
</AuthLayout>
|
||||
)
|
||||
<div className="min-h-[70vh]">Redirecting ... </div>
|
||||
</AuthLayout>
|
||||
);
|
||||
}
|
||||
|
||||
export default Redirect
|
||||
export default Redirect;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import React from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import localImgLoad from '../../lib/localImgLoad'
|
||||
|
||||
const ForgetPwdResponse = ({title, message, type}) => {
|
||||
const navigate = useNavigate()
|
||||
return (
|
||||
<>
|
||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||
<h1 className={`${type ? 'text-black' : 'text-red-500'}text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]`}>
|
||||
{title}
|
||||
</h1>
|
||||
</div>
|
||||
<div className="title-area w-[100px] h-[100px] mx-auto flex flex-col justify-center items-center relative text-center mb-7">
|
||||
<img className='w-full h-full' src={`${type ? localImgLoad('images/icons/success.svg') : localImgLoad('images/icons/error.svg')}`} alt='alert-banner' />
|
||||
</div>
|
||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||
<p className={`${type ? 'text-sky-blue' : 'text-red-500'} font-semibold dark:text-white mb-3 leading-[27.3px] text-[18px]`}>
|
||||
{message}
|
||||
</p>
|
||||
</div>
|
||||
<div className="signin-area mb-3.5">
|
||||
<div className="flex justify-center items-center gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => navigate("/login")}
|
||||
className={`h-[48px] rounded-full mb-6 text-[15px] font-semibold text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.81rem]`}
|
||||
>
|
||||
<span>Home</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default ForgetPwdResponse
|
||||
@@ -1,9 +1,13 @@
|
||||
import React, { useState } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import WrenchBoard from "../../../assets/images/wrenchboard.png";
|
||||
import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import InputCom from "../../Helpers/Inputs/InputCom";
|
||||
import AuthLayout from "../AuthLayout";
|
||||
import EmailValidator from "../../../lib/EmailValidator";
|
||||
import ForgetPwdResponse from "../ForgetPwdResponse";
|
||||
|
||||
import ReCAPTCHA from "react-google-recaptcha";
|
||||
|
||||
export default function ForgotPassword() {
|
||||
const [checked, setValue] = useState(false);
|
||||
@@ -11,7 +15,7 @@ export default function ForgotPassword() {
|
||||
// email
|
||||
const [email, setMail] = useState("");
|
||||
const [msgError, setMsgError] = useState("");
|
||||
const [msgSuccess, setMsgSuccess] = useState(false);
|
||||
const [msgSuccess, setMsgSuccess] = useState(null);
|
||||
|
||||
const navigate = useNavigate();
|
||||
const userApi = new usersService();
|
||||
@@ -20,15 +24,38 @@ export default function ForgotPassword() {
|
||||
setMail(e?.target.value);
|
||||
};
|
||||
|
||||
const humanChecker = () => {
|
||||
setValue(!checked);
|
||||
};
|
||||
// const humanChecker = () => {
|
||||
// setValue(!checked);
|
||||
// };
|
||||
|
||||
function humanChecker(value) {
|
||||
// console.log("Captcha value:", value);
|
||||
if(value){
|
||||
setValue(true)
|
||||
}else{
|
||||
setValue(false)
|
||||
}
|
||||
}
|
||||
|
||||
const resetHandler = async () => {
|
||||
if (email == "") {
|
||||
setMsgError("An email is required");
|
||||
} else if (!checked) {
|
||||
return setTimeout(() => {
|
||||
setMsgError(null);
|
||||
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT);
|
||||
}
|
||||
if (!checked) {
|
||||
setMsgError("Check if you are human");
|
||||
return setTimeout(() => {
|
||||
setMsgError(null);
|
||||
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT);
|
||||
}
|
||||
|
||||
if(!EmailValidator(email)){ // CHECKS IF EMAIL IS VALID
|
||||
setMsgError("Invalid Email");
|
||||
return setTimeout(() => {
|
||||
setMsgError(null);
|
||||
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT);
|
||||
}
|
||||
|
||||
if (email !== "" && checked) {
|
||||
@@ -41,8 +68,11 @@ export default function ForgotPassword() {
|
||||
setMail("");
|
||||
setValue(false);
|
||||
setResetLoading(false);
|
||||
}else{
|
||||
setMsgSuccess(false);
|
||||
}
|
||||
} catch (error) {
|
||||
setMsgSuccess(false);
|
||||
setResetLoading(false);
|
||||
setMail("");
|
||||
setMsgError("An error occurred");
|
||||
@@ -53,9 +83,6 @@ export default function ForgotPassword() {
|
||||
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT);
|
||||
}
|
||||
}
|
||||
setTimeout(() => {
|
||||
setMsgError(null);
|
||||
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -73,106 +100,108 @@ export default function ForgotPassword() {
|
||||
</div>
|
||||
<div className="content-wrapper login shadow-md w-full lg:max-w-[500px] mx-auto flex justify-center items-center xl:bg-white dark:bg-dark-white 2xl:w-[828px] rounded-[0.475rem] sm:p-7 p-5">
|
||||
<div className="flex flex-col justify-center w-full h-full px-5">
|
||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
||||
Forget Password
|
||||
</h1>
|
||||
<span className="text-gray-400 font-medium text-[16.25px] leading-[24.375px]">
|
||||
Enter your email to reset your password.
|
||||
</span>
|
||||
</div>
|
||||
<div className="input-area">
|
||||
<div className="input-item mb-10">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
placeholder="Your Username/Email"
|
||||
label="Email"
|
||||
name="email"
|
||||
type="email"
|
||||
value={email}
|
||||
inputHandler={handleEmail}
|
||||
iconName="message"
|
||||
/>
|
||||
{msgSuccess == null ?
|
||||
<>
|
||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
||||
Forget Password
|
||||
</h1>
|
||||
<span className="text-gray-400 font-medium text-[16.25px] leading-[24.375px]">
|
||||
Enter your email to reset your password.
|
||||
</span>
|
||||
</div>
|
||||
{/* hCaptha clone for the time being */}
|
||||
<div className="mb-10">
|
||||
<div className="w-[303px] h-[78px] mx-auto overflow-hidden">
|
||||
<div className="w-[300px] h-[74px] bg-white bottom-[1px] rounded border-gray-100 overflow-hidden cursor-pointer">
|
||||
{/* Checkbox */}
|
||||
<div className="h-full relative inline-block">
|
||||
<div className="relative table top-0 h-full">
|
||||
<div className="table-cell align-middle">
|
||||
<div className="relative w-[30px] h-[30px] mx-[15px]">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="human-checkbox"
|
||||
id="human-checkbox"
|
||||
className="w-[28px] h-[28px] border-[1px] rounded border-gray-400 checked:bg-white"
|
||||
checked={checked}
|
||||
onChange={humanChecker}
|
||||
/>
|
||||
<div className="input-area">
|
||||
<div className="input-item mb-10">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
placeholder="Your Username/Email"
|
||||
label="Email"
|
||||
name="email"
|
||||
type="email"
|
||||
value={email}
|
||||
inputHandler={handleEmail}
|
||||
iconName="message"
|
||||
/>
|
||||
</div>
|
||||
{/* hCaptha clone for the time being */}
|
||||
<div className="mb-10 flex justify-center w-full">
|
||||
<ReCAPTCHA
|
||||
sitekey={process.env.REACT_APP_GOOGLE_RECAPTCHA_SITEKEY}
|
||||
onChange={humanChecker}
|
||||
/>
|
||||
</div>
|
||||
{/* <div className="mb-10">
|
||||
<div className="w-[303px] h-[78px] mx-auto overflow-hidden">
|
||||
<div className="w-[300px] h-[74px] bg-white bottom-[1px] rounded border-gray-100 overflow-hidden cursor-pointer">
|
||||
|
||||
<div className="h-full relative inline-block">
|
||||
<div className="relative table top-0 h-full">
|
||||
<div className="table-cell align-middle">
|
||||
<div className="relative w-[30px] h-[30px] mx-[15px]">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="human-checkbox"
|
||||
id="human-checkbox"
|
||||
className="w-[28px] h-[28px] border-[1px] rounded border-gray-400 checked:bg-white"
|
||||
checked={checked}
|
||||
onChange={humanChecker}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-full relative inline-block w-[170px]">
|
||||
<label className="relative table top-0 h-full">
|
||||
<label className="table-cell align-middle">
|
||||
<label
|
||||
className="text-800 text-sm"
|
||||
htmlFor="human-checkbox"
|
||||
>
|
||||
I am human
|
||||
<div className="h-full relative inline-block w-[170px]">
|
||||
<label className="relative table top-0 h-full">
|
||||
<label className="table-cell align-middle">
|
||||
<label
|
||||
className="text-800 text-sm"
|
||||
htmlFor="human-checkbox"
|
||||
>
|
||||
I am human
|
||||
</label>
|
||||
</label>
|
||||
</label>
|
||||
</label>
|
||||
</div>
|
||||
<div className="h-full relative inline-block w-16"></div>
|
||||
</div>
|
||||
<div className="h-full relative inline-block w-16"></div>
|
||||
</div>
|
||||
</div> */}
|
||||
{msgError && (
|
||||
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]">
|
||||
{msgError}
|
||||
</div>
|
||||
)}
|
||||
<div className="signin-area mb-3.5">
|
||||
<div className="flex justify-center items-center gap-4">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => navigate("/login")}
|
||||
className={`h-[48px] rounded-full mb-6 text-[15px] font-semibold text-white hover:text-white flex justify-center bg-red-500 hover:bg-red-600 transition-all duration-300 items-center py-[0.8875rem] px-[1.8125rem] `}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={resetHandler}
|
||||
className={`h-[48px] rounded-full mb-6 text-[15px] font-semibold text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.81rem]`}
|
||||
>
|
||||
{resetLoading ? (
|
||||
<div className="signup btn-loader"></div>
|
||||
) : (
|
||||
<span>Send Code</span>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{msgError && (
|
||||
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]">
|
||||
{msgError}
|
||||
</div>
|
||||
)}
|
||||
{msgSuccess && (
|
||||
<div className="relative p-4 text-[#44228c] bg-[#e3d7fb] border-[#d5c4f9] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]">
|
||||
If we find your email, you will receive a link to reset your
|
||||
password. Please use or{" "}
|
||||
<Link
|
||||
to="/contact"
|
||||
className="text-[#4687ba] hover:text-[#009ef7]"
|
||||
>
|
||||
contact form
|
||||
</Link>{" "}
|
||||
if you did not get our message after few minutes.
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="signin-area mb-3.5">
|
||||
<div className="flex justify-center items-center gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={resetHandler}
|
||||
className={`rounded-[0.475rem] mb-6 text-[15px] font-semibold text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.81rem]`}
|
||||
>
|
||||
{resetLoading ? (
|
||||
<div className="signup btn-loader"></div>
|
||||
) : (
|
||||
<span>Send Code</span>
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => navigate("/login")}
|
||||
className={`rounded-[0.475rem] mb-6 text-[15px] font-semibold text-[#009ef7] hover:text-white flex justify-center bg-[#f1faff] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.8125rem] `}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
:
|
||||
<ForgetPwdResponse
|
||||
title={'Forget Password'}
|
||||
message={msgSuccess? `Check your email for the link to continue password reset. Note the reset link will expire short time` : 'We are unable to continue with your request. Please try another username or contact us for help'}
|
||||
type={msgSuccess}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
import React, { useState } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import InputCom from "../../Helpers/Inputs/InputCom";
|
||||
import AuthLayout from "../AuthLayout2";
|
||||
import EmailValidator from "../../../lib/EmailValidator";
|
||||
import ForgetPwdResponse from "../ForgetPwdResponse";
|
||||
|
||||
import ReCAPTCHA from "react-google-recaptcha";
|
||||
|
||||
export default function ForgotPassword() {
|
||||
const [checked, setValue] = useState(false);
|
||||
const [resetLoading, setResetLoading] = useState(false);
|
||||
// email
|
||||
const [email, setMail] = useState("");
|
||||
const [msgError, setMsgError] = useState("");
|
||||
const [msgSuccess, setMsgSuccess] = useState(null);
|
||||
|
||||
const navigate = useNavigate();
|
||||
const userApi = new usersService();
|
||||
|
||||
const handleEmail = (e) => {
|
||||
setMail(e?.target.value);
|
||||
};
|
||||
|
||||
// const humanChecker = () => {
|
||||
// setValue(!checked);
|
||||
// };
|
||||
|
||||
function humanChecker(value) {
|
||||
// console.log("Captcha value:", value);
|
||||
if(value){
|
||||
setValue(true)
|
||||
}else{
|
||||
setValue(false)
|
||||
}
|
||||
}
|
||||
|
||||
const resetHandler = async () => {
|
||||
if (email == "") {
|
||||
setMsgError("An email is required");
|
||||
return setTimeout(() => {
|
||||
setMsgError(null);
|
||||
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT);
|
||||
}
|
||||
if (!checked) {
|
||||
setMsgError("Check if you are human");
|
||||
return setTimeout(() => {
|
||||
setMsgError(null);
|
||||
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT);
|
||||
}
|
||||
|
||||
if(!EmailValidator(email)){ // CHECKS IF EMAIL IS VALID
|
||||
setMsgError("Invalid Email");
|
||||
return setTimeout(() => {
|
||||
setMsgError(null);
|
||||
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT);
|
||||
}
|
||||
|
||||
if (email !== "" && checked) {
|
||||
const reqData = { email };
|
||||
setResetLoading(true);
|
||||
try {
|
||||
const res = await userApi.StartResetPassword(reqData);
|
||||
if (res.status === 200 && res?.data?.internal_return >= 0) {
|
||||
setMsgSuccess(true);
|
||||
setMail("");
|
||||
setValue(false);
|
||||
setResetLoading(false);
|
||||
}else{
|
||||
setMsgSuccess(false);
|
||||
}
|
||||
} catch (error) {
|
||||
setMsgSuccess(false);
|
||||
setResetLoading(false);
|
||||
setMail("");
|
||||
setMsgError("An error occurred");
|
||||
throw new Error(error);
|
||||
} finally {
|
||||
setTimeout(() => {
|
||||
setMsgError(null);
|
||||
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<AuthLayout slogan="Welcome to WrenchBoard">
|
||||
<div className="w-full">
|
||||
<div className="mb-12">
|
||||
<Link to="#">
|
||||
<img
|
||||
src={WrenchBoard}
|
||||
alt="wrenchboard"
|
||||
className="h-10 mx-auto"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex place-content-center">
|
||||
<div className="w-10/12">
|
||||
{msgSuccess == null ?
|
||||
<>
|
||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
||||
Forget Password
|
||||
</h1>
|
||||
<span className="text-gray-400 font-medium text-[16.25px] leading-[24.375px]">
|
||||
Enter your email to reset your password.
|
||||
</span>
|
||||
</div>
|
||||
<div className="input-area">
|
||||
<div className="input-item mb-10">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
placeholder="Your Username/Email"
|
||||
label="Email"
|
||||
name="email"
|
||||
type="email"
|
||||
value={email}
|
||||
inputHandler={handleEmail}
|
||||
iconName="message"
|
||||
/>
|
||||
</div>
|
||||
{/* hCaptha clone for the time being */}
|
||||
<div className="mb-10 flex justify-center w-full">
|
||||
<ReCAPTCHA
|
||||
sitekey={process.env.REACT_APP_GOOGLE_RECAPTCHA_SITEKEY}
|
||||
onChange={humanChecker}
|
||||
/>
|
||||
</div>
|
||||
{/* <div className="mb-10">
|
||||
<div className="w-[303px] h-[78px] mx-auto overflow-hidden">
|
||||
<div className="w-[300px] h-[74px] bg-white bottom-[1px] rounded border-gray-100 overflow-hidden cursor-pointer">
|
||||
|
||||
<div className="h-full relative inline-block">
|
||||
<div className="relative table top-0 h-full">
|
||||
<div className="table-cell align-middle">
|
||||
<div className="relative w-[30px] h-[30px] mx-[15px]">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="human-checkbox"
|
||||
id="human-checkbox"
|
||||
className="w-[28px] h-[28px] border-[1px] rounded border-gray-400 checked:bg-white"
|
||||
checked={checked}
|
||||
onChange={humanChecker}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-full relative inline-block w-[170px]">
|
||||
<label className="relative table top-0 h-full">
|
||||
<label className="table-cell align-middle">
|
||||
<label
|
||||
className="text-800 text-sm"
|
||||
htmlFor="human-checkbox"
|
||||
>
|
||||
I am human
|
||||
</label>
|
||||
</label>
|
||||
</label>
|
||||
</div>
|
||||
<div className="h-full relative inline-block w-16"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
{msgError && (
|
||||
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]">
|
||||
{msgError}
|
||||
</div>
|
||||
)}
|
||||
<div className="signin-area mb-3.5">
|
||||
<div className="flex justify-center items-center gap-4">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => navigate("/login")}
|
||||
className={`h-[48px] rounded-full mb-6 text-[15px] font-semibold text-white hover:text-white flex justify-center bg-red-500 hover:bg-red-600 transition-all duration-300 items-center py-[0.8875rem] px-[1.8125rem] `}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={resetHandler}
|
||||
className={`h-[48px] rounded-full mb-6 text-[15px] font-semibold text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.81rem]`}
|
||||
>
|
||||
{resetLoading ? (
|
||||
<div className="signup btn-loader"></div>
|
||||
) : (
|
||||
<span>Send Code</span>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
:
|
||||
<ForgetPwdResponse
|
||||
title={'Forget Password'}
|
||||
message={msgSuccess? `Check your email for the link to continue password reset. Note the reset link will expire short time` : 'We are unable to continue with your request. Please try another username or contact us for help'}
|
||||
type={msgSuccess}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AuthLayout>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,26 +1,35 @@
|
||||
import React, { useEffect, useLayoutEffect, useState } from "react";
|
||||
import { Link, useNavigate, useLocation } from "react-router-dom";
|
||||
import { Link, useLocation, useNavigate } from "react-router-dom";
|
||||
import linkedInLogo from "../../../assets/images/Linkedin.png";
|
||||
import appleLogo from "../../../assets/images/apple-black.svg";
|
||||
import facebookLogo from "../../../assets/images/facebook-4.svg";
|
||||
import facebookLogo from "../../../assets/images/facebook.svg";
|
||||
import googleLogo from "../../../assets/images/google-logo.svg";
|
||||
import WrenchBoard from "../../../assets/images/wrenchboard.png";
|
||||
import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import InputCom from "../../Helpers/Inputs/InputCom";
|
||||
import AuthLayout from "../AuthLayout";
|
||||
// import { GoogleOAuthProvider } from '@react-oauth/google';
|
||||
import { googleLogout, useGoogleLogin } from "@react-oauth/google";
|
||||
import { useGoogleLogin } from "@react-oauth/google";
|
||||
|
||||
import { useDispatch } from "react-redux";
|
||||
import { updateUserDetails } from "../../../store/UserDetails";
|
||||
|
||||
import ReCAPTCHA from "react-google-recaptcha";
|
||||
|
||||
export default function Login() {
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
const queryParams = new URLSearchParams(location?.search);
|
||||
// const sessionExpired = queryParams.get("sessionExpired");
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const {state} = useLocation()
|
||||
const { state } = useLocation();
|
||||
|
||||
let [loginType, setLoginType] = useState('');
|
||||
const [sessionExpired, setSessionExpired] = useState(queryParams.get("sessionExpired"))
|
||||
|
||||
const [validCaptcha, setValidCaptcha] = useState({ show: false, valid: "" }); // FOR CAPTCHA
|
||||
|
||||
let [loginType, setLoginType] = useState("");
|
||||
|
||||
const [checked, setValue] = useState(false);
|
||||
const [loginLoading, setLoginLoading] = useState(false);
|
||||
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
@@ -30,12 +39,8 @@ export default function Login() {
|
||||
// for the catch error
|
||||
const [msgError, setMsgError] = useState("");
|
||||
|
||||
const rememberMe = () => {
|
||||
setValue(!checked);
|
||||
};
|
||||
|
||||
// To Show and Hide Password
|
||||
const togglePasswordVisibility = () => {
|
||||
// To Show and Hide Password
|
||||
const togglePasswordVisibility = () => {
|
||||
setShowPassword(!showPassword);
|
||||
};
|
||||
|
||||
@@ -43,7 +48,7 @@ export default function Login() {
|
||||
const handleLoginType = ({ target: { name } }) => {
|
||||
setLoginType(name);
|
||||
let currentDate = new Date();
|
||||
let expirationDate = new Date(currentDate.getTime() + (24 * 60 * 60 * 1000));
|
||||
let expirationDate = new Date(currentDate.getTime() + 24 * 60 * 60 * 1000);
|
||||
// Convert the expiration date to the appropriate format
|
||||
let expirationDateString = expirationDate.toUTCString();
|
||||
document.cookie = `loginType=${name}; expires=${expirationDateString}; path=/;`;
|
||||
@@ -83,7 +88,9 @@ export default function Login() {
|
||||
if (regEx.test(email) == false) {
|
||||
setLoginLoading(false);
|
||||
setMsgError("Invalid Email");
|
||||
return setTimeout(()=>{setMsgError("");},3000)
|
||||
return setTimeout(() => {
|
||||
setMsgError("");
|
||||
}, 3000);
|
||||
}
|
||||
// Post Data Info for normal Login
|
||||
postData = {
|
||||
@@ -91,7 +98,6 @@ export default function Login() {
|
||||
password: password,
|
||||
sessionid: "STARTING",
|
||||
login_mode: 1100,
|
||||
action: 11025,
|
||||
};
|
||||
} else if (name == "family") {
|
||||
// Post Data Info for family Login
|
||||
@@ -100,7 +106,6 @@ export default function Login() {
|
||||
pin: password,
|
||||
sessionid: "20067A92714",
|
||||
login_mode: 1105,
|
||||
action: 11025,
|
||||
};
|
||||
} else {
|
||||
setLoginLoading(false);
|
||||
@@ -110,20 +115,39 @@ export default function Login() {
|
||||
}, Number(process.env.REACT_APP_LOGIN_ERROR_TIMEOUT));
|
||||
return;
|
||||
}
|
||||
if (name == "full" && !validCaptcha.valid && validCaptcha.show) {
|
||||
// RUNS AND DISPLAYS CAPTCHA, IF ERROR OCCURED DURING LOGIN FOR FULL LOGIN ALONE
|
||||
setMsgError("Please Verify Captcha");
|
||||
setLoginLoading(false);
|
||||
setTimeout(() => {
|
||||
setMsgError("");
|
||||
}, Number(process.env.REACT_APP_LOGIN_ERROR_TIMEOUT));
|
||||
return;
|
||||
}
|
||||
userApi
|
||||
.logInUser(postData)
|
||||
.then((res) => {
|
||||
if (res.status != 200 || res.data.internal_return < 0 || !res.data.member_id || !res.data.uid || !res.data.session) {
|
||||
if (
|
||||
res.status != 200 ||
|
||||
res.data.internal_return < 0 ||
|
||||
!res.data.member_id ||
|
||||
!res.data.uid ||
|
||||
!res.data.session
|
||||
) {
|
||||
// setMsgError("Wrong, email/password");
|
||||
setLoginError(true);
|
||||
setLoginLoading(false);
|
||||
setValidCaptcha((prev) => ({ ...prev, show: true })); // DISPLAYS CAPTCHA IF ERROR
|
||||
return;
|
||||
}
|
||||
localStorage.setItem("member_id", `${res.data.member_id}`);
|
||||
localStorage.setItem("uid", `${res.data.uid}`);
|
||||
localStorage.setItem("session_token", `${res.data.session}`);
|
||||
if (name === "family") {
|
||||
sessionStorage.setItem("family_uid", res.data?.family_uid);
|
||||
}
|
||||
// localStorage.setItem("session", `${res.data.session}`);
|
||||
dispatch(updateUserDetails({...res.data}));
|
||||
dispatch(updateUserDetails({ ...res.data }));
|
||||
setTimeout(() => {
|
||||
navigate("/", { replace: true });
|
||||
setLoginLoading(false);
|
||||
@@ -132,6 +156,7 @@ export default function Login() {
|
||||
.catch((error) => {
|
||||
setMsgError("Unable to login, try again");
|
||||
setLoginLoading(false);
|
||||
setValidCaptcha((prev) => ({ ...prev, show: true })); // DISPLAYS CAPTCHA IF ERROR
|
||||
})
|
||||
.finally(() => {
|
||||
setTimeout(() => {
|
||||
@@ -142,6 +167,15 @@ export default function Login() {
|
||||
});
|
||||
};
|
||||
|
||||
function captchaChecker(value) {
|
||||
// FUNCTION TO VALIDATE CAPTCHA
|
||||
if (value) {
|
||||
setValidCaptcha({ show: true, valid: value });
|
||||
} else {
|
||||
setValidCaptcha({ show: true, valid: "" });
|
||||
}
|
||||
}
|
||||
|
||||
const googleLogin = useGoogleLogin({
|
||||
flow: "auth-code",
|
||||
ux_mode: "redirect",
|
||||
@@ -154,11 +188,12 @@ export default function Login() {
|
||||
|
||||
// In order to update the selected login type whenever the component renders
|
||||
// useEffect(() => {
|
||||
// Clear the loginType cookie if the user switches to loginfull
|
||||
// document.cookie ="loginType=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||
// Clear the loginType cookie if the user switches to loginfull
|
||||
// document.cookie ="loginType=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||
// }, []);
|
||||
|
||||
useLayoutEffect(()=>{ // checks the cookie in order to set the login type before components mounts
|
||||
useLayoutEffect(() => {
|
||||
// checks the cookie in order to set the login type before components mounts
|
||||
// if(document.cookie.includes("loginType=family")){
|
||||
// setLoginType('family')
|
||||
// }else if(document.cookie.includes("loginType=full")){
|
||||
@@ -166,39 +201,54 @@ export default function Login() {
|
||||
// }else{
|
||||
// setLoginType('full')
|
||||
// }
|
||||
function readCookie(cname) { // checks the cookie in order to set the login type before components mounts
|
||||
function readCookie(cname) {
|
||||
// checks the cookie in order to set the login type before components mounts
|
||||
let name = cname + "=";
|
||||
let decoded_cookie = decodeURIComponent(document.cookie);
|
||||
let carr = decoded_cookie.split(';');
|
||||
for(let i=0; i<carr.length;i++){
|
||||
let carr = decoded_cookie.split(";");
|
||||
for (let i = 0; i < carr.length; i++) {
|
||||
let c = carr[i];
|
||||
while(c.charAt(0)==' '){
|
||||
c=c.substring(1);
|
||||
while (c.charAt(0) == " ") {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if(c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
if (c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return 'full'
|
||||
return "full";
|
||||
}
|
||||
let loginValue = readCookie('loginType')
|
||||
setLoginType(loginValue)
|
||||
let loginValue = readCookie("loginType");
|
||||
setLoginType(loginValue);
|
||||
|
||||
if(state?.error){ //check if the login path has an error state indicating any social handle login with error
|
||||
if (state?.error) {
|
||||
//check if the login path has an error state indicating any social handle login with error
|
||||
setMsgError("Unexpected Error, Please try again soon.");
|
||||
setTimeout(()=>{
|
||||
setTimeout(() => {
|
||||
setMsgError("");
|
||||
navigate('/login', {replace: true})
|
||||
},4000)
|
||||
navigate("/login", { replace: true });
|
||||
}, 4000);
|
||||
}
|
||||
},[])
|
||||
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setMail("");
|
||||
setPassword("");
|
||||
}, [loginType]);
|
||||
|
||||
|
||||
// EFFECT TO CLEAR SESSION EXPIRY IF IT EXISTS AFTER SOME SECONDS
|
||||
useEffect(()=>{
|
||||
let timer;
|
||||
if(sessionExpired == "true"){
|
||||
timer = setTimeout(()=>{
|
||||
setSessionExpired(false)
|
||||
},5000)
|
||||
}
|
||||
return () => {
|
||||
clearTimeout(timer)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<AuthLayout slogan="Welcome to WrenchBoard">
|
||||
@@ -214,27 +264,41 @@ export default function Login() {
|
||||
</div>
|
||||
<div className="content-wrapper login shadow-md w-full lg:max-w-[530px] mx-auto flex justify-center items-center xl:bg-white dark:bg-dark-white 2xl:w-[828px] rounded-[0.475rem] sm:p-7 p-5">
|
||||
<div className="w-full">
|
||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||
{/* <h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
||||
{/* HIDES THIS IF USER SESSION HAS EXPIRED */}
|
||||
{sessionExpired != "true" && (
|
||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||
{/* <h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
||||
Sign In to WrenchBoard
|
||||
</h1> */}
|
||||
<span className="text-gray-400 font-medium text-[16.25px] leading-[24.375px]">
|
||||
New Here?{" "}
|
||||
<Link
|
||||
to="/signup"
|
||||
className="font-semibold text-[#4687ba] hover:text-[#009ef7] transition"
|
||||
>
|
||||
Create an Account
|
||||
</Link>
|
||||
</span>
|
||||
</div>
|
||||
<span className="text-gray-400 font-medium text-[16.25px] leading-[24.375px]">
|
||||
New Here?{" "}
|
||||
<Link
|
||||
to="/signup"
|
||||
className="font-semibold text-[#4687ba] hover:text-[#009ef7] transition"
|
||||
>
|
||||
Create an Account
|
||||
</Link>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* SHOWS THIS IF USER SESSION HAS EXPIRED */}
|
||||
{sessionExpired == "true" && (
|
||||
<div className="w-full p-1 mb-7">
|
||||
<p className="text-red-500 text-base text-center">
|
||||
Your session expired and will need to login again
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* switch login component */}
|
||||
<div className="ml-7 flex justify-start items-center gap-3">
|
||||
<button
|
||||
name="full"
|
||||
className={`login-type-btn px-4 py-1 rounded-t-2xl ${
|
||||
loginType=='full' ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
|
||||
loginType == "full"
|
||||
? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white"
|
||||
: "bg-white text-[#000] border-t-[2px]"
|
||||
}`}
|
||||
onClick={handleLoginType}
|
||||
>
|
||||
@@ -243,7 +307,9 @@ export default function Login() {
|
||||
<button
|
||||
name="family"
|
||||
className={`login-type-btn px-4 py-1 rounded-t-2xl ${
|
||||
loginType=='family' ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
|
||||
loginType == "family"
|
||||
? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white"
|
||||
: "bg-white text-[#000] border-t-[2px]"
|
||||
}`}
|
||||
onClick={handleLoginType}
|
||||
>
|
||||
@@ -255,7 +321,7 @@ export default function Login() {
|
||||
|
||||
{/* for login component */}
|
||||
{
|
||||
loginType == 'full' ? (
|
||||
loginType == "full" ? (
|
||||
//user login component
|
||||
<div className="p-6 input-area login-area border-2 border-[#4687ba] rounded-2xl">
|
||||
<div className="input-item mb-5">
|
||||
@@ -275,7 +341,7 @@ export default function Login() {
|
||||
<div className="input-item mb-5">
|
||||
<InputCom
|
||||
labelClass="tracking-wider"
|
||||
fieldClass="sm:px-6 px-2"
|
||||
fieldClass="sm:px-6 px-2 tracking-[0.25em] text-2xl"
|
||||
value={password}
|
||||
inputHandler={handlePassword}
|
||||
placeholder="● ● ● ● ● ●"
|
||||
@@ -287,6 +353,19 @@ export default function Login() {
|
||||
forgotPassword
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* hCaptha clone for the time being */}
|
||||
{validCaptcha.show && (
|
||||
<div className="mb-5 flex justify-center w-full">
|
||||
<ReCAPTCHA
|
||||
sitekey={
|
||||
process.env.REACT_APP_GOOGLE_RECAPTCHA_SITEKEY
|
||||
}
|
||||
onChange={captchaChecker}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{loginError && (
|
||||
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-thin leading-[19.5px] text-[13px]">
|
||||
Invalid username or password- Please{" "}
|
||||
@@ -311,7 +390,7 @@ export default function Login() {
|
||||
onClick={doLogin}
|
||||
type="button"
|
||||
disabled={loginLoading}
|
||||
className={`btn-login rounded-[0.475rem] mb-6 text-xl text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center text-[15px]`}
|
||||
className={`btn-login rounded-full mb-6 text-xl text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center text-[15px]`}
|
||||
>
|
||||
{loginLoading ? (
|
||||
<div className="signup btn-loader"></div>
|
||||
@@ -320,34 +399,51 @@ export default function Login() {
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
<div className="sm:flex sm:justify-between sm:items-center sm:space-x-2">
|
||||
<BrandBtn
|
||||
link="#"
|
||||
imgSrc={googleLogo}
|
||||
brand="Google"
|
||||
onClick={googleLogin}
|
||||
/>
|
||||
<BrandBtn
|
||||
// link={`https://appleid.apple.com/auth/authorize?response_type=code&response_mode=form_post&client_id=${process.env.REACT_APP_APPLE_CLIENT_ID}&redirect_uri=https%3A%2F%2Fwork.wrenchboard.com%2Flogin%2Fauth%2Fapple&state=4b2c4456b7&scope=name+email`}
|
||||
link={`https://appleid.apple.com/auth/authorize?response_type=code&response_mode=form_post&client_id=${process.env.REACT_APP_APPLE_CLIENT_ID}&redirect_uri=${process.env.REACT_APP_APPLE_REDIRECT_URL}&state=4b2c4456b7&scope=name+email`}
|
||||
imgSrc={appleLogo}
|
||||
brand="Apple"
|
||||
isAnchor={true}
|
||||
/>
|
||||
</div>
|
||||
<div className="sm:flex sm:justify-between sm:items-center sm:space-x-2">
|
||||
<BrandBtn
|
||||
link={`https://www.facebook.com/v14.0/dialog/oauth?client_id=${process.env.REACT_APP_FACEBOOK_CLIENT_ID}&redirect_uri=${process.env.REACT_APP_FACEBOOK_REDIRECT_URL}&scope=${process.env.REACT_APP_FACEBOOK_CLIENT_SCOPE}`}
|
||||
imgSrc={facebookLogo}
|
||||
brand="Facebook"
|
||||
isAnchor={true}
|
||||
/>
|
||||
<BrandBtn
|
||||
// link="https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=comma-separated-list-of-scopes&state=YOUR_STATE_VALUE"
|
||||
imgSrc={linkedInLogo}
|
||||
brand="LinkedIn"
|
||||
isAnchor={true}
|
||||
/>
|
||||
<div className="sm:grid grid-cols-2 gap-1">
|
||||
<div className="w-full">
|
||||
<BrandBtn
|
||||
link="#"
|
||||
imgSrc={googleLogo}
|
||||
brand="Google"
|
||||
onClick={googleLogin}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={`w-full ${
|
||||
process.env.REACT_APP_APPLE_SOCIAL_LOGIN !== 0 &&
|
||||
"hidden"
|
||||
}`}
|
||||
>
|
||||
<BrandBtn
|
||||
// link={`https://appleid.apple.com/auth/authorize?response_type=code&response_mode=form_post&client_id=${process.env.REACT_APP_APPLE_CLIENT_ID}&redirect_uri=https%3A%2F%2Fwork.wrenchboard.com%2Flogin%2Fauth%2Fapple&state=4b2c4456b7&scope=name+email`}
|
||||
link={`https://appleid.apple.com/auth/authorize?response_type=code&response_mode=form_post&client_id=${process.env.REACT_APP_APPLE_CLIENT_ID}&redirect_uri=${process.env.REACT_APP_APPLE_REDIRECT_URL}&state=4b2c4456b7&scope=name+email`}
|
||||
imgSrc={appleLogo}
|
||||
brand="Apple"
|
||||
isAnchor={true}
|
||||
// style={{visibility: 'hidden'}}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<BrandBtn
|
||||
link={`https://www.facebook.com/v14.0/dialog/oauth?client_id=${process.env.REACT_APP_FACEBOOK_CLIENT_ID}&redirect_uri=${process.env.REACT_APP_FACEBOOK_REDIRECT_URL}&scope=${process.env.REACT_APP_FACEBOOK_CLIENT_SCOPE}`}
|
||||
imgSrc={facebookLogo}
|
||||
brand="Facebook"
|
||||
isAnchor={true}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={`w-full ${
|
||||
process.env.REACT_APP_LINKEDIN_SOCIAL_LOGIN !== 0 &&
|
||||
"hidden"
|
||||
}`}
|
||||
>
|
||||
<BrandBtn
|
||||
// link="https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=comma-separated-list-of-scopes&state=YOUR_STATE_VALUE"
|
||||
imgSrc={linkedInLogo}
|
||||
brand="LinkedIn"
|
||||
isAnchor={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -407,7 +503,7 @@ export default function Login() {
|
||||
onClick={doLogin}
|
||||
disabled={loginLoading}
|
||||
type="button"
|
||||
className={`btn-login rounded-[0.475rem] text-xl text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center text-[15px]`}
|
||||
className={`btn-login rounded-full text-xl text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center text-[15px]`}
|
||||
>
|
||||
{loginLoading ? (
|
||||
<div className="signup btn-loader"></div>
|
||||
@@ -423,10 +519,12 @@ export default function Login() {
|
||||
}
|
||||
{/* END of login component */}
|
||||
|
||||
<div className="pt-5 text-[#181c32] text-center font-semibold text-[13.975px] leading-[20.9625px]">
|
||||
This site is protected by hCaptcha and the our Privacy Policy
|
||||
and Terms of Service apply.
|
||||
</div>
|
||||
{loginType == "full" && (
|
||||
<div className="pt-5 text-[#181c32] text-center font-semibold text-[13.975px] leading-[20.9625px]">
|
||||
This site is protected by a Captcha. Our Privacy Policy and
|
||||
Terms of Service apply.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -435,7 +533,14 @@ export default function Login() {
|
||||
);
|
||||
}
|
||||
|
||||
const BrandBtn = ({ link, imgSrc, brand, onClick, isAnchor=false }) => {
|
||||
const BrandBtn = ({
|
||||
link,
|
||||
imgSrc,
|
||||
brand,
|
||||
onClick,
|
||||
isAnchor = false,
|
||||
style = { visibility: "visible" },
|
||||
}) => {
|
||||
// const doGoogle = async () => {
|
||||
// alert("start google");
|
||||
// };
|
||||
@@ -455,34 +560,29 @@ const BrandBtn = ({ link, imgSrc, brand, onClick, isAnchor=false }) => {
|
||||
// alert("start facebook");
|
||||
// };
|
||||
return (
|
||||
<div className="w-full sm:w-1/2 flex justify-center bottomMargin">
|
||||
{isAnchor ?
|
||||
(
|
||||
<div className="w-full flex justify-center bottomMargin" style={style}>
|
||||
{isAnchor ? (
|
||||
<a
|
||||
href={link}
|
||||
className="w-full border border-light-purple dark:border-[#5356fb29] rounded-[0.475rem] h-[48px] flex justify-center bg-[#FAFAFA] hover:bg-[#eff2f5] hover:text-[#7e8299] transition duration-300 dark:bg-[#11131F] items-center font-medium cursor-pointer"
|
||||
>
|
||||
<img className="mr-3 h-6" src={imgSrc} alt="logo-icon(s)" />
|
||||
<span className="text-lg text-thin-light-gray font-normal text-[15px]">
|
||||
Continue with {brand}
|
||||
</span>
|
||||
</a>
|
||||
)
|
||||
:
|
||||
(
|
||||
href={link}
|
||||
className="w-full border border-light-purple dark:border-[#5356fb29] rounded-[0.475rem] h-[48px] flex justify-center bg-[#FAFAFA] hover:bg-[#eff2f5] hover:text-[#7e8299] transition duration-300 dark:bg-[#11131F] items-center font-medium cursor-pointer"
|
||||
>
|
||||
<img className="mr-3 h-6" src={imgSrc} alt="logo-icon(s)" />
|
||||
<span className="text-lg text-thin-light-gray font-normal text-[15px]">
|
||||
Continue with {brand}
|
||||
</span>
|
||||
</a>
|
||||
) : (
|
||||
<button
|
||||
onClick={onClick}
|
||||
// href="#dd"
|
||||
className="w-full border border-light-purple dark:border-[#5356fb29] rounded-[0.475rem] h-[48px] flex justify-center bg-[#FAFAFA] hover:bg-[#eff2f5] hover:text-[#7e8299] transition duration-300 dark:bg-[#11131F] items-center font-medium cursor-pointer"
|
||||
>
|
||||
<img className="mr-3 h-6" src={imgSrc} alt="logo-icon(s)" />
|
||||
<span className="text-lg text-thin-light-gray font-normal text-[15px]">
|
||||
Continue with {brand}
|
||||
</span>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
onClick={onClick}
|
||||
// href="#dd"
|
||||
className="w-full border border-light-purple dark:border-[#5356fb29] rounded-[0.475rem] h-[48px] flex justify-center bg-[#FAFAFA] hover:bg-[#eff2f5] hover:text-[#7e8299] transition duration-300 dark:bg-[#11131F] items-center font-medium cursor-pointer"
|
||||
>
|
||||
<img className="mr-3 h-6" src={imgSrc} alt="logo-icon(s)" />
|
||||
<span className="text-lg text-thin-light-gray font-normal text-[15px]">
|
||||
Continue with {brand}
|
||||
</span>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,637 @@
|
||||
import React, { useEffect, useLayoutEffect, useState } from "react";
|
||||
import { Link, useLocation, useNavigate } from "react-router-dom";
|
||||
import linkedInLogo from "../../../assets/images/Linkedin.png";
|
||||
import appleLogo from "../../../assets/images/apple-black.svg";
|
||||
import facebookLogo from "../../../assets/images/facebook.svg";
|
||||
import googleLogo from "../../../assets/images/google-logo.svg";
|
||||
import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import InputCom from "../../Helpers/Inputs/InputCom";
|
||||
import AuthLayout from "../AuthLayout2";
|
||||
// import { GoogleOAuthProvider } from '@react-oauth/google';
|
||||
import { useGoogleLogin } from "@react-oauth/google";
|
||||
|
||||
import { useDispatch } from "react-redux";
|
||||
import { updateUserDetails } from "../../../store/UserDetails";
|
||||
|
||||
import ReCAPTCHA from "react-google-recaptcha";
|
||||
|
||||
import GoogleDownload from '../../../assets/images/download/andriod.jpg'
|
||||
import IOSDownload from '../../../assets/images/download/apple.jpg'
|
||||
|
||||
export default function Login() {
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
const queryParams = new URLSearchParams(location?.search);
|
||||
// const sessionExpired = queryParams.get("sessionExpired");
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const { state } = useLocation();
|
||||
|
||||
const [sessionExpired, setSessionExpired] = useState(
|
||||
queryParams.get("sessionExpired")
|
||||
);
|
||||
|
||||
const [validCaptcha, setValidCaptcha] = useState({ show: false, valid: "" }); // FOR CAPTCHA
|
||||
|
||||
let [loginType, setLoginType] = useState("");
|
||||
|
||||
const [loginLoading, setLoginLoading] = useState(false);
|
||||
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
|
||||
//login error state
|
||||
const [loginError, setLoginError] = useState(false);
|
||||
// for the catch error
|
||||
const [msgError, setMsgError] = useState("");
|
||||
|
||||
// To Show and Hide Password
|
||||
const togglePasswordVisibility = () => {
|
||||
setShowPassword(!showPassword);
|
||||
};
|
||||
|
||||
//FUNCTION TO DETERMINE/CHANGE LOGIN COMPONENT
|
||||
const handleLoginType = ({ target: { name } }) => {
|
||||
setLoginType(name);
|
||||
let currentDate = new Date();
|
||||
let expirationDate = new Date(currentDate.getTime() + 24 * 60 * 60 * 1000);
|
||||
// Convert the expiration date to the appropriate format
|
||||
let expirationDateString = expirationDate.toUTCString();
|
||||
document.cookie = `loginType=${name}; expires=${expirationDateString}; path=/;`;
|
||||
};
|
||||
|
||||
// email
|
||||
const [email, setMail] = useState("");
|
||||
const handleEmail = (e) => {
|
||||
setMail(e.target.value);
|
||||
};
|
||||
// password
|
||||
const [password, setPassword] = useState("");
|
||||
const handlePassword = (e) => {
|
||||
setPassword(e.target.value);
|
||||
};
|
||||
const navigate = useNavigate();
|
||||
const userApi = new usersService();
|
||||
|
||||
// FUNCTION TO HANDLE USER LOGIN
|
||||
const doLogin = ({ target: { name } }) => {
|
||||
setMsgError("");
|
||||
setLoginError(false);
|
||||
setLoginLoading(true);
|
||||
let postData; // Post Data for API
|
||||
if (!email || !password) {
|
||||
setLoginLoading(false);
|
||||
setMsgError("Please fill all the fields");
|
||||
setTimeout(() => {
|
||||
setMsgError("");
|
||||
}, Number(process.env.REACT_APP_LOGIN_ERROR_TIMEOUT));
|
||||
return;
|
||||
}
|
||||
|
||||
if (name == "full") {
|
||||
//checks if email is a valid email address
|
||||
let regEx = /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/;
|
||||
if (regEx.test(email) == false) {
|
||||
setLoginLoading(false);
|
||||
setMsgError("Invalid Email");
|
||||
return setTimeout(() => {
|
||||
setMsgError("");
|
||||
}, 3000);
|
||||
}
|
||||
// Post Data Info for normal Login
|
||||
postData = {
|
||||
username: email,
|
||||
password: password,
|
||||
sessionid: "STARTING",
|
||||
login_mode: 1100,
|
||||
};
|
||||
} else if (name == "family") {
|
||||
// Post Data Info for family Login
|
||||
postData = {
|
||||
username: email,
|
||||
pin: password,
|
||||
sessionid: "20067A92714",
|
||||
login_mode: 1105,
|
||||
};
|
||||
} else {
|
||||
setLoginLoading(false);
|
||||
setMsgError("Invalid Login Type. Consider refreshing the page");
|
||||
setTimeout(() => {
|
||||
setMsgError("");
|
||||
}, Number(process.env.REACT_APP_LOGIN_ERROR_TIMEOUT));
|
||||
return;
|
||||
}
|
||||
if (name == "full" && !validCaptcha.valid && validCaptcha.show) {
|
||||
// RUNS AND DISPLAYS CAPTCHA, IF ERROR OCCURED DURING LOGIN FOR FULL LOGIN ALONE
|
||||
setMsgError("Please Verify Captcha");
|
||||
setLoginLoading(false);
|
||||
setTimeout(() => {
|
||||
setMsgError("");
|
||||
}, Number(process.env.REACT_APP_LOGIN_ERROR_TIMEOUT));
|
||||
return;
|
||||
}
|
||||
userApi
|
||||
.logInUser(postData)
|
||||
.then((res) => {
|
||||
if (
|
||||
res.status != 200 ||
|
||||
res.data.internal_return < 0 ||
|
||||
!res.data.member_id ||
|
||||
!res.data.uid ||
|
||||
!res.data.session
|
||||
) {
|
||||
// setMsgError("Wrong, email/password");
|
||||
setLoginError(true);
|
||||
setLoginLoading(false);
|
||||
setValidCaptcha((prev) => ({ ...prev, show: true })); // DISPLAYS CAPTCHA IF ERROR
|
||||
return;
|
||||
}
|
||||
localStorage.setItem("member_id", `${res.data.member_id}`);
|
||||
localStorage.setItem("uid", `${res.data.uid}`);
|
||||
localStorage.setItem("session_token", `${res.data.session}`);
|
||||
localStorage.setItem("wallet_available_status", `${res.data.wallet_available_status}`);
|
||||
if (res.data?.account_type == "FAMILY") {
|
||||
sessionStorage.setItem("family_uid", res.data?.family_uid);
|
||||
sessionStorage.setItem("parent_uid", res.data?.parent_uid);
|
||||
}
|
||||
// localStorage.setItem("session", `${res.data.session}`);
|
||||
dispatch(updateUserDetails({ ...res.data }));
|
||||
setTimeout(() => {
|
||||
navigate("/", { replace: true });
|
||||
setLoginLoading(false);
|
||||
}, 2000);
|
||||
})
|
||||
.catch((error) => {
|
||||
setMsgError("Unable to login, try again");
|
||||
setLoginLoading(false);
|
||||
setValidCaptcha((prev) => ({ ...prev, show: true })); // DISPLAYS CAPTCHA IF ERROR
|
||||
})
|
||||
.finally(() => {
|
||||
setTimeout(() => {
|
||||
setLoginError(false);
|
||||
setMsgError("");
|
||||
setLoginLoading(false);
|
||||
}, Number(process.env.REACT_APP_LOGIN_ERROR_TIMEOUT));
|
||||
});
|
||||
};
|
||||
|
||||
function captchaChecker(value) {
|
||||
// FUNCTION TO VALIDATE CAPTCHA
|
||||
if (value) {
|
||||
setValidCaptcha({ show: true, valid: value });
|
||||
} else {
|
||||
setValidCaptcha({ show: true, valid: "" });
|
||||
}
|
||||
}
|
||||
|
||||
const googleLogin = useGoogleLogin({
|
||||
flow: "auth-code",
|
||||
ux_mode: "redirect",
|
||||
redirect_uri: process.env.REACT_APP_GOOGLE_REDIRECT_URL,
|
||||
onSuccess: async (codeResponse) => {
|
||||
console.log("GOOGLE LOGIN GOOD --- ", codeResponse);
|
||||
},
|
||||
onError: (errorResponse) => console.log(errorResponse),
|
||||
});
|
||||
|
||||
// In order to update the selected login type whenever the component renders
|
||||
// useEffect(() => {
|
||||
// Clear the loginType cookie if the user switches to loginfull
|
||||
// document.cookie ="loginType=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||
// }, []);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
// checks the cookie in order to set the login type before components mounts
|
||||
// if(document.cookie.includes("loginType=family")){
|
||||
// setLoginType('family')
|
||||
// }else if(document.cookie.includes("loginType=full")){
|
||||
// setLoginType('full')
|
||||
// }else{
|
||||
// setLoginType('full')
|
||||
// }
|
||||
function readCookie(cname) {
|
||||
// checks the cookie in order to set the login type before components mounts
|
||||
let name = cname + "=";
|
||||
let decoded_cookie = decodeURIComponent(document.cookie);
|
||||
let carr = decoded_cookie.split(";");
|
||||
for (let i = 0; i < carr.length; i++) {
|
||||
let c = carr[i];
|
||||
while (c.charAt(0) == " ") {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return "full";
|
||||
}
|
||||
let loginValue = readCookie("loginType");
|
||||
setLoginType(loginValue);
|
||||
|
||||
if (state?.error) {
|
||||
//check if the login path has an error state indicating any social handle login with error
|
||||
setMsgError("Unexpected Error, Please try again soon.");
|
||||
setTimeout(() => {
|
||||
setMsgError("");
|
||||
navigate("/login", { replace: true });
|
||||
}, 4000);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setMail("");
|
||||
setPassword("");
|
||||
}, [loginType]);
|
||||
|
||||
// EFFECT TO CLEAR SESSION EXPIRY IF IT EXISTS AFTER SOME SECONDS
|
||||
useEffect(() => {
|
||||
let timer;
|
||||
if (sessionExpired == "true") {
|
||||
timer = setTimeout(() => {
|
||||
setSessionExpired(false);
|
||||
}, 5000);
|
||||
}
|
||||
return () => {
|
||||
clearTimeout(timer);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<AuthLayout slogan="Welcome to WrenchBoard">
|
||||
<div className="w-full">
|
||||
<div className="mb-5">
|
||||
<Link to="#">
|
||||
<img
|
||||
src={WrenchBoard}
|
||||
alt="wrenchboard"
|
||||
className="h-10 mx-auto"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
{/* <div className="content-wrapper login shadow-md w-10/12 mx-auto flex justify-center items-center xl:bg-white dark:bg-dark-white 2xl:w-[828px] rounded-[0.475rem] sm:p-7 p-5"> */}
|
||||
<div className="flex place-content-center">
|
||||
<div className="w-10/12">
|
||||
{/* HIDES THIS IF USER SESSION HAS EXPIRED */}
|
||||
{sessionExpired != "true" && (
|
||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||
{/* <h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
||||
Sign In to WrenchBoard
|
||||
</h1> */}
|
||||
<span className="text-gray-400 font-medium text-[16.25px] leading-[24.375px]">
|
||||
New Here?{" "}
|
||||
<Link
|
||||
to="/signup"
|
||||
className="font-semibold text-[#4687ba] hover:text-[#009ef7] transition"
|
||||
>
|
||||
Create an Account
|
||||
</Link>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* SHOWS THIS IF USER SESSION HAS EXPIRED */}
|
||||
{sessionExpired == "true" && (
|
||||
<div className="w-full p-1 mb-7">
|
||||
<p className="text-red-500 text-base text-center">
|
||||
Your session expired and will need to login again
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* switch login component */}
|
||||
<div className="ml-7 flex justify-start items-center gap-3">
|
||||
<button
|
||||
name="full"
|
||||
className={`login-type-btn px-4 py-1 rounded-t-2xl ${
|
||||
loginType == "full"
|
||||
? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white"
|
||||
: "bg-white text-[#000] border-t-[2px]"
|
||||
}`}
|
||||
onClick={handleLoginType}
|
||||
>
|
||||
Sign in
|
||||
</button>
|
||||
<button
|
||||
name="family"
|
||||
className={`login-type-btn px-4 py-1 rounded-t-2xl ${
|
||||
loginType == "family"
|
||||
? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white"
|
||||
: "bg-white text-[#000] border-t-[2px]"
|
||||
}`}
|
||||
onClick={handleLoginType}
|
||||
>
|
||||
Family Account
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* END of switch login component */}
|
||||
|
||||
{/* for login component */}
|
||||
{
|
||||
loginType == "full" ? (
|
||||
//user login component
|
||||
<div className="p-6 input-area login-area border-2 border-[#4687ba] rounded-2xl">
|
||||
<div className="input-item mb-5">
|
||||
<InputCom
|
||||
labelClass="tracking-wider"
|
||||
fieldClass="sm:px-6 px-2"
|
||||
value={email}
|
||||
inputHandler={handleEmail}
|
||||
placeholder="Your Email"
|
||||
label="Email"
|
||||
name="email"
|
||||
type="email"
|
||||
iconName="message"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="input-item mb-5">
|
||||
<InputCom
|
||||
labelClass="tracking-wider"
|
||||
fieldClass="sm:px-6 px-2 tracking-[0.25em] text-2xl"
|
||||
value={password}
|
||||
inputHandler={handlePassword}
|
||||
placeholder="● ● ● ● ● ●"
|
||||
label="Password"
|
||||
name="password"
|
||||
type={showPassword ? "text" : "password"}
|
||||
onClick={togglePasswordVisibility}
|
||||
passIcon={showPassword ? "password" : "password"}
|
||||
forgotPassword
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* hCaptha clone for the time being */}
|
||||
{validCaptcha.show && (
|
||||
<div className="mb-5 flex justify-center w-full">
|
||||
<ReCAPTCHA
|
||||
sitekey={
|
||||
process.env.REACT_APP_GOOGLE_RECAPTCHA_SITEKEY
|
||||
}
|
||||
onChange={captchaChecker}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{loginError && (
|
||||
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-thin leading-[19.5px] text-[13px]">
|
||||
Invalid username or password- Please{" "}
|
||||
<Link to="/#" className="text-[#009ef7]">
|
||||
reset your password
|
||||
</Link>{" "}
|
||||
or{" "}
|
||||
<Link to="/signup" className="text-[#009ef7]">
|
||||
create a new account
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
{msgError && (
|
||||
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]">
|
||||
{msgError}
|
||||
</div>
|
||||
)}
|
||||
<div className="signin-area mb-3.5">
|
||||
<div className="flex justify-center">
|
||||
<button
|
||||
name="full"
|
||||
onClick={doLogin}
|
||||
type="button"
|
||||
disabled={loginLoading}
|
||||
className={`btn-login rounded-full mb-6 text-xl text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center text-[15px]`}
|
||||
>
|
||||
{loginLoading ? (
|
||||
<div className="signup btn-loader"></div>
|
||||
) : (
|
||||
<>Continue</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
<div className="sm:grid grid-cols-2 gap-1">
|
||||
<div className="w-full">
|
||||
<BrandBtn
|
||||
link="#"
|
||||
imgSrc={googleLogo}
|
||||
brand="Google"
|
||||
onClick={googleLogin}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={`w-full ${
|
||||
process.env.REACT_APP_APPLE_SOCIAL_LOGIN !== 0 &&
|
||||
"hidden"
|
||||
}`}
|
||||
>
|
||||
<BrandBtn
|
||||
// link={`https://appleid.apple.com/auth/authorize?response_type=code&response_mode=form_post&client_id=${process.env.REACT_APP_APPLE_CLIENT_ID}&redirect_uri=https%3A%2F%2Fwork.wrenchboard.com%2Flogin%2Fauth%2Fapple&state=4b2c4456b7&scope=name+email`}
|
||||
link={`https://appleid.apple.com/auth/authorize?response_type=code&response_mode=form_post&client_id=${process.env.REACT_APP_APPLE_CLIENT_ID}&redirect_uri=${process.env.REACT_APP_APPLE_REDIRECT_URL}&state=4b2c4456b7&scope=name+email`}
|
||||
imgSrc={appleLogo}
|
||||
brand="Apple"
|
||||
isAnchor={true}
|
||||
// style={{visibility: 'hidden'}}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<BrandBtn
|
||||
link={`https://www.facebook.com/v14.0/dialog/oauth?client_id=${process.env.REACT_APP_FACEBOOK_CLIENT_ID}&redirect_uri=${process.env.REACT_APP_FACEBOOK_REDIRECT_URL}&scope=${process.env.REACT_APP_FACEBOOK_CLIENT_SCOPE}`}
|
||||
imgSrc={facebookLogo}
|
||||
brand="Facebook"
|
||||
isAnchor={true}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={`w-full ${
|
||||
process.env.REACT_APP_LINKEDIN_SOCIAL_LOGIN !== 0 &&
|
||||
"hidden"
|
||||
}`}
|
||||
>
|
||||
<BrandBtn
|
||||
// link="https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=comma-separated-list-of-scopes&state=YOUR_STATE_VALUE"
|
||||
imgSrc={linkedInLogo}
|
||||
brand="LinkedIn"
|
||||
isAnchor={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
// END of user login compoenent
|
||||
// family login compoenent
|
||||
<div className="p-6 input-area login-area border-2 border-[#4687ba] rounded-2xl">
|
||||
<div className="input-item mb-5">
|
||||
<InputCom
|
||||
labelClass="tracking-wider"
|
||||
fieldClass="px-6"
|
||||
value={email}
|
||||
inputHandler={handleEmail}
|
||||
placeholder="Account ID"
|
||||
label="Username"
|
||||
name="email"
|
||||
type="email"
|
||||
iconName="family-id"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="input-item mb-5">
|
||||
<InputCom
|
||||
labelClass="tracking-wider"
|
||||
fieldClass="px-6"
|
||||
value={password}
|
||||
inputHandler={handlePassword}
|
||||
placeholder="● ● ● ● ● ●"
|
||||
label="Pin"
|
||||
name="password"
|
||||
type={showPassword ? "text" : "password"}
|
||||
onClick={togglePasswordVisibility}
|
||||
passIcon={showPassword ? "family-pin" : "family-pin"}
|
||||
/>
|
||||
</div>
|
||||
{loginError && (
|
||||
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-thin leading-[19.5px] text-[13px]">
|
||||
Invalid username or password{" "}
|
||||
{/* <Link to="/#" className="text-[#009ef7]">
|
||||
reset your password
|
||||
</Link>{" "}
|
||||
or{" "}
|
||||
<Link to="/signup" className="text-[#009ef7]">
|
||||
create a new account
|
||||
</Link> */}
|
||||
</div>
|
||||
)}
|
||||
{msgError && (
|
||||
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]">
|
||||
{msgError}
|
||||
</div>
|
||||
)}
|
||||
<div className="signin-area mb-1.5">
|
||||
<div className="flex justify-center">
|
||||
<button
|
||||
name="family"
|
||||
onClick={doLogin}
|
||||
disabled={loginLoading}
|
||||
type="button"
|
||||
className={`btn-login rounded-full text-xl text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center text-[15px]`}
|
||||
>
|
||||
{loginLoading ? (
|
||||
<div className="signup btn-loader"></div>
|
||||
) : (
|
||||
<>Continue</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
// END of family login compoenent
|
||||
}
|
||||
{/* END of login component */}
|
||||
|
||||
{/* APP DOWNLOAD STORE */}
|
||||
<div className="w-full mt-4">
|
||||
<div className="w-full flex justify-center items-center gap-4">
|
||||
<div className="w-32 lg:w-48">
|
||||
<a
|
||||
// className="px-1 py-1 lg:py-2 flex justify-center items-center gap-1 w-full rounded-md bg-black text-white hover:text-slate-500 hover:shadow-lg transition-all duration-300"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
href={process.env.REACT_APP_APPLE_APP}
|
||||
>
|
||||
{/* <i className="fa-brands fa-apple text-3xl"></i>
|
||||
<div className="flex flex-col">
|
||||
<span className="text-[11px]">Available on the</span>
|
||||
<span className="text-[12px] lg:text-base">
|
||||
App Store
|
||||
</span>
|
||||
</div> */}
|
||||
<img src={IOSDownload} className='w-full h-auto' alt='IOS Download' />
|
||||
</a>
|
||||
</div>
|
||||
<div className="w-32 lg:w-48">
|
||||
<a
|
||||
// className="px-1 py-1 lg:py-2 flex justify-center items-center gap-1 w-full rounded-md bg-black text-white hover:text-slate-500 hover:shadow-lg transition-all duration-300"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
href={process.env.REACT_APP_ANDROID_APP}
|
||||
>
|
||||
{/* <i className="fa-brands fa-google-play text-2xl"></i>
|
||||
<div className="flex flex-col">
|
||||
<span className="text-[11px]">Available on the</span>
|
||||
<span className="text-[12px] lg:text-base">
|
||||
Google Play
|
||||
</span>
|
||||
</div> */}
|
||||
<img src={GoogleDownload} className='w-full h-auto' alt='IOS Download' />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{loginType == "full" && (
|
||||
<>
|
||||
<div className="pt-5 text-[#181c32] text-center font-semibold text-[13.975px] leading-[20.9625px]">
|
||||
This site is protected by a Captcha. <br />Our Privacy Policy and
|
||||
Terms of Service apply.
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AuthLayout>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const BrandBtn = ({
|
||||
link,
|
||||
imgSrc,
|
||||
brand,
|
||||
onClick,
|
||||
isAnchor = false,
|
||||
style = { visibility: "visible" },
|
||||
}) => {
|
||||
// const doGoogle = async () => {
|
||||
// alert("start google");
|
||||
// };
|
||||
|
||||
// onSuccess: (codeResponse) => setUser(codeResponse),
|
||||
|
||||
// const doGoogle = useGoogleLogin({
|
||||
// onSuccess: (codeResponse) => console.log('Login onSuccess:', codeResponse),
|
||||
// onError: (error) => console.log('Login Failed:', error)
|
||||
// });
|
||||
|
||||
// const doApple = async () => {
|
||||
// alert("start apple");
|
||||
// };
|
||||
|
||||
// const doFacebook = async () => {
|
||||
// alert("start facebook");
|
||||
// };
|
||||
return (
|
||||
<div className="w-full flex justify-center bottomMargin" style={style}>
|
||||
{isAnchor ? (
|
||||
<a
|
||||
href={link}
|
||||
className="w-full border border-light-purple rounded-[0.475rem] h-[48px] flex justify-center bg-[#FAFAFA] hover:bg-[#eff2f5] hover:text-[#7e8299] transition duration-300 items-center font-medium cursor-pointer"
|
||||
>
|
||||
<img className="mr-3 h-6" src={imgSrc} alt="logo-icon(s)" />
|
||||
<span className="text-lg text-thin-light-gray font-normal text-[15px]">
|
||||
Continue with {brand}
|
||||
</span>
|
||||
</a>
|
||||
) : (
|
||||
<button
|
||||
onClick={onClick}
|
||||
// href="#dd"
|
||||
className="w-full border border-light-purple rounded-[0.475rem] h-[48px] flex justify-center bg-[#FAFAFA] hover:bg-[#eff2f5] hover:text-[#7e8299] transition duration-300 items-center font-medium cursor-pointer"
|
||||
>
|
||||
<img className="mr-3 h-6" src={imgSrc} alt="logo-icon(s)" />
|
||||
<span className="text-lg text-thin-light-gray font-normal text-[15px]">
|
||||
Continue with {brand}
|
||||
</span>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,252 @@
|
||||
import React, {useState, useEffect} from 'react'
|
||||
import { Link, useParams, useNavigate } from "react-router-dom";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { updateUserDetails } from "../../../store/UserDetails";
|
||||
|
||||
import usersService from "../../../services/UsersService";
|
||||
|
||||
import PromoPageLayout from '../PromoPageLayout'
|
||||
import InputCom from "../../Helpers/Inputs/InputCom";
|
||||
import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
|
||||
import LoadingSpinner from '../../../components/Spinners/LoadingSpinner'
|
||||
|
||||
import GoogleDownload from '../../../assets/images/download/andriod.jpg'
|
||||
import IOSDownload from '../../../assets/images/download/apple.jpg'
|
||||
|
||||
export default function Promo() {
|
||||
|
||||
const api = new usersService()
|
||||
|
||||
const {name, id} = useParams() // PARAMETERS COMING FROM THE LINK
|
||||
// console.log(name, id)
|
||||
|
||||
const navigate = useNavigate()
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [requestStatus, setRequestStatus] = useState({loading:true, data:{}})
|
||||
|
||||
const [completeSignUp, setCompleteSignUp] = useState({loading:false, status:false, message: ''});
|
||||
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
|
||||
const [password, setPassword] = useState("");
|
||||
|
||||
const handlePassword = (e) => {
|
||||
setPassword(e.target.value);
|
||||
};
|
||||
|
||||
// To Show and Hide Password
|
||||
const togglePasswordVisibility = () => {
|
||||
setShowPassword(!showPassword);
|
||||
};
|
||||
|
||||
const handleContinue = () => {
|
||||
let reqData = { // API REQUEST DATA/PAYLOAD
|
||||
username: requestStatus?.data?.email,
|
||||
promo: name,
|
||||
promo_owner: id,
|
||||
password: password,
|
||||
sessionid: '24271A99426'
|
||||
}
|
||||
setCompleteSignUp({loading:true, status:false, message: ''})
|
||||
if(!password){ // CHECKS FOR EMPTY PASSWORD
|
||||
setCompleteSignUp({loading:false, status:false, message: 'Please Enter Password'})
|
||||
return setTimeout(()=>{
|
||||
setCompleteSignUp({loading:false, status:false, message: ''})
|
||||
},2000)
|
||||
}
|
||||
api.loginPromo(reqData).then(res => { //loginPromo
|
||||
console.log('RES', res)
|
||||
if(res.data?.internal_return < 0 || !res?.data?.member_id || !res?.data?.uid || !res?.data?.session || res?.data?.status_message == 'VALID_LINK_NOT_FOUND'){
|
||||
setCompleteSignUp({loading:false, status:false, message: 'Unable to login'})
|
||||
return setTimeout(()=>{
|
||||
setCompleteSignUp({loading:false, status:false, message: ''})
|
||||
},4000)
|
||||
}
|
||||
|
||||
// Do LOGIN HERE
|
||||
localStorage.setItem("member_id", `${res.data.member_id}`);
|
||||
localStorage.setItem("uid", `${res.data.uid}`);
|
||||
localStorage.setItem("session_token", `${res.data.session}`);
|
||||
localStorage.setItem("wallet_available_status", `${res.data.wallet_available_status}`);
|
||||
if (res.data?.account_type == "FAMILY") {
|
||||
sessionStorage.setItem("family_uid", res.data?.family_uid);
|
||||
sessionStorage.setItem("parent_uid", res.data?.parent_uid);
|
||||
}
|
||||
dispatch(updateUserDetails({ ...res.data }));
|
||||
setTimeout(() => {
|
||||
navigate("/", { replace: true });
|
||||
setCompleteSignUp({loading:false, status:true, message: ''})
|
||||
}, 2000);
|
||||
|
||||
}).catch(err => {
|
||||
setCompleteSignUp({loading:false, status:false, message: 'Opps! try again'})
|
||||
setTimeout(()=>{
|
||||
setCompleteSignUp({loading:false, status:false, message: ''})
|
||||
},4000)
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
let reqData = { // API REQUEST DATA/PAYLOAD
|
||||
promo: name,
|
||||
promo_owner: id,
|
||||
sessionid: '79970A12501'
|
||||
}
|
||||
api.verifyPromo(reqData).then(res => {
|
||||
if(res?.data?.internal_return < 0 || !res?.data?.email || res?.data?.status_message != 'VALID_LINK_FOUND'){
|
||||
return setRequestStatus({loading:false, data:{}})
|
||||
}
|
||||
setRequestStatus({loading:false, data:res?.data})
|
||||
}).catch(err => {
|
||||
setRequestStatus({loading:false, data:{}})
|
||||
})
|
||||
},[])
|
||||
|
||||
return (
|
||||
<PromoPageLayout>
|
||||
<div className="w-full">
|
||||
<div className="mb-5">
|
||||
<Link to="#">
|
||||
<img
|
||||
src={WrenchBoard}
|
||||
alt="wrenchboard"
|
||||
className="h-10 mx-auto"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
{requestStatus.loading ?
|
||||
<div className='flex flex-col justify-center items-center'>
|
||||
<LoadingSpinner height='h-40' size='8' />
|
||||
<p>Loading...</p>
|
||||
<p>please do not refresh</p>
|
||||
</div>
|
||||
: Object.keys(requestStatus.data).length > 0 ?
|
||||
<div className="flex place-content-center">
|
||||
<div className="w-10/12 pb-3">
|
||||
<div className="p-6 input-area login-area border-2 border-[#4687ba] rounded-2xl">
|
||||
<div className="input-item mb-5">
|
||||
<InputCom
|
||||
labelClass="tracking-wider"
|
||||
fieldClass="sm:px-6 px-2"
|
||||
value={requestStatus?.data?.email}
|
||||
// inputHandler={handleEmail}
|
||||
placeholder="Your Email"
|
||||
label="Email"
|
||||
name="email"
|
||||
type="email"
|
||||
iconName="message"
|
||||
disable={true}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="input-item mb-5">
|
||||
<InputCom
|
||||
labelClass="tracking-wider"
|
||||
fieldClass="sm:px-6 px-2 tracking-[0.25em] text-2xl"
|
||||
value={password}
|
||||
inputHandler={handlePassword}
|
||||
placeholder="● ● ● ● ● ●"
|
||||
label="Set Password"
|
||||
name="password"
|
||||
type={showPassword ? "text" : "password"}
|
||||
onClick={togglePasswordVisibility}
|
||||
passIcon={showPassword ? "password" : "password"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{completeSignUp.message && (
|
||||
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]">
|
||||
{completeSignUp.message}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex justify-center">
|
||||
<button
|
||||
name="full"
|
||||
onClick={handleContinue}
|
||||
type="button"
|
||||
disabled={completeSignUp.loading}
|
||||
className={`btn-login rounded-full text-xl text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center text-[15px]`}
|
||||
>
|
||||
{completeSignUp.loading ? (
|
||||
<div className="signup btn-loader"></div>
|
||||
) : (
|
||||
<>Continue</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* APP DOWNLOAD STORE */}
|
||||
<div className="w-full mt-4">
|
||||
<div className="w-full flex justify-center items-center gap-4">
|
||||
<div className="w-32 lg:w-48">
|
||||
<a
|
||||
// className="px-1 py-1 lg:py-2 flex justify-center items-center gap-1 w-full rounded-md bg-black text-white hover:text-slate-500 hover:shadow-lg transition-all duration-300"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
href={process.env.REACT_APP_APPLE_APP}
|
||||
>
|
||||
{/* <i className="fa-brands fa-apple text-3xl"></i>
|
||||
<div className="flex flex-col">
|
||||
<span className="text-[11px]">Available on the</span>
|
||||
<span className="text-[12px] lg:text-base">
|
||||
App Store
|
||||
</span>
|
||||
</div> */}
|
||||
<img src={IOSDownload} className='w-full h-auto' alt='IOS Download' />
|
||||
</a>
|
||||
</div>
|
||||
<div className="w-32 lg:w-48">
|
||||
<a
|
||||
// className="px-1 py-1 lg:py-2 flex justify-center items-center gap-1 w-full rounded-md bg-black text-white hover:text-slate-500 hover:shadow-lg transition-all duration-300"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
href={process.env.REACT_APP_ANDROID_APP}
|
||||
>
|
||||
{/* <i className="fa-brands fa-google-play text-2xl"></i>
|
||||
<div className="flex flex-col">
|
||||
<span className="text-[11px]">Available on the</span>
|
||||
<span className="text-[12px] lg:text-base">
|
||||
Google Play
|
||||
</span>
|
||||
</div> */}
|
||||
<img src={GoogleDownload} className='w-full h-auto' alt='IOS Download' />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<ErrorComponent onClick={() => navigate("/login")} />
|
||||
}
|
||||
</div>
|
||||
</PromoPageLayout>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
const ErrorComponent = ({ onClick }) => (
|
||||
<div className="input-area">
|
||||
<div className="my-5">
|
||||
<p className="text-[14px] leading-[19px] text-center text-[#181c32]">
|
||||
This error occurs because you have already verified this link or the
|
||||
link has expired. Try login or reset password. If none worked, try to
|
||||
create the account from the start.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="signin-area flex justify-center mb-3.5">
|
||||
<button
|
||||
onClick={onClick}
|
||||
type="button"
|
||||
className={`rounded-[0.475rem] mb-6 text-[15px] font-semibold text-[#009ef7] hover:text-white flex justify-center bg-[#f1faff] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.81rem]`}
|
||||
>
|
||||
<span>Return Home</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -0,0 +1,80 @@
|
||||
import React, { useContext } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { localImgLoad } from "../../lib";
|
||||
|
||||
import DarkModeContext from "../Contexts/DarkModeContext";
|
||||
|
||||
export default function PromoPageLayout({ children }) {
|
||||
const bgImg = localImgLoad("images/left-wrenchboard.jpg");
|
||||
const bgImgNig = localImgLoad("images/wrench-home-back-nigeria.jpg");
|
||||
const bgImgCom = localImgLoad("images/wrench-promo-back-common.jpg");
|
||||
|
||||
const { countryMode } = useContext(DarkModeContext);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`min-h-screen overflow-y-auto bg-cover bg-center flex flex-col justify-between items-center`}
|
||||
style={{
|
||||
backgroundImage: `url(${countryMode == "NG" ? bgImgCom : bgImgCom})`,
|
||||
}}
|
||||
>
|
||||
|
||||
<div className={`w-full grid grid-cols-1`}>
|
||||
{/* <div
|
||||
className={`auth-bg hidden xl:block bg-blue-50 relative bg-cover bg-no-repeat border-0 after:content-[''] after:absolute after:inset-0`}
|
||||
style={{backgroundImage: `url(${bgImg})`}}
|
||||
>
|
||||
</div> */}
|
||||
<div className="p-5 sm:p-7 flex place-content-center">
|
||||
<div className="py-5 w-full sm:w-11/12 max-w-[550px] shadow-md bg-slate-50 dark:bg-dark-white rounded-[0.475rem]">
|
||||
<div className="w-full flex justify-center items-center">
|
||||
{children && children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='hidden w-full shadow-md bg-slate-50 dark:bg-dark-white'>
|
||||
<div className="w-full flex flex-col md:flex-row justify-center items-center px-10 py-2">
|
||||
<div className="flex justify-center items-center">
|
||||
<div className="flex items-center">
|
||||
<a
|
||||
href="https://www.wrenchboard.com/about-us"
|
||||
className="text-[#a1a5b7] text-[15px] px-2 font-medium hover:text-[#009ef7]"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
About
|
||||
</a>
|
||||
<a
|
||||
href="https://www.wrenchboard.com/service"
|
||||
className="text-[#a1a5b7] text-[15px] px-2 font-medium hover:text-[#009ef7]"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Services
|
||||
</a>
|
||||
<a
|
||||
href="https://www.wrenchboard.com/contact"
|
||||
className="text-[#a1a5b7] text-[15px] px-2 font-medium hover:text-[#009ef7]"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Contact Us
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-black text-[15px] px-2 font-medium flex items-center gap-1">
|
||||
<span className="dark:text-white">
|
||||
© {new Date().getFullYear()} -
|
||||
</span>
|
||||
<Link to="/" className="text-[#009ef7] ml-1">
|
||||
WrenchBoard
|
||||
</Link>{" "}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||