Completed particle background

This commit is contained in:
THIS ONE IS A LITTLE BIT TRICKY KRUB 2023-11-19 10:33:54 +07:00
parent 15576df657
commit e25a6b6d24
5 changed files with 427 additions and 144 deletions

View File

@ -8,9 +8,7 @@
</head>
<body>
<div id="root"></div>
<div id="particles-js"></div>
<script type="module" src="/src/main.jsx"></script>
<script src="/node_modules/particles.js/particles.js"></script>
</body>
</html>

View File

@ -33,13 +33,14 @@
"framer-motion": "^10.16.4",
"gapi-script": "^1.2.0",
"jwt-decode": "^4.0.0",
"particles.js": "^2.0.0",
"react": "^18.2.0",
"react-beautiful-dnd": "^13.1.1",
"react-bootstrap": "^2.9.1",
"react-dom": "^18.2.0",
"react-icons": "^4.11.0",
"react-router-dom": "^6.18.0"
"react-router-dom": "^6.18.0",
"react-tsparticles": "^2.12.2",
"tsparticles": "^2.12.0"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.10",

View File

@ -74,9 +74,6 @@ dependencies:
jwt-decode:
specifier: ^4.0.0
version: 4.0.0
particles.js:
specifier: ^2.0.0
version: 2.0.0
react:
specifier: ^18.2.0
version: 18.2.0
@ -95,6 +92,12 @@ dependencies:
react-router-dom:
specifier: ^6.18.0
version: 6.19.0(react-dom@18.2.0)(react@18.2.0)
react-tsparticles:
specifier: ^2.12.2
version: 2.12.2(react@18.2.0)
tsparticles:
specifier: ^2.12.0
version: 2.12.0
devDependencies:
'@tailwindcss/typography':
@ -2928,10 +2931,6 @@ packages:
lines-and-columns: 1.2.4
dev: false
/particles.js@2.0.0:
resolution: {integrity: sha512-8e0JIqkRbMMPlFBnF9f+92hX1s07jdkd3tqB8uHE9L+cwGGjIYjQM7QLgt0FQ5MZp6SFFYYDm/Y48pqK3ZvJOQ==}
dev: false
/path-exists@4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
@ -3238,6 +3237,16 @@ packages:
react-dom: 18.2.0(react@18.2.0)
dev: false
/react-tsparticles@2.12.2(react@18.2.0):
resolution: {integrity: sha512-/nrEbyL8UROXKIMXe+f+LZN2ckvkwV2Qa+GGe/H26oEIc+wq/ybSG9REDwQiSt2OaDQGu0MwmA4BKmkL6wAWcA==}
requiresBuild: true
peerDependencies:
react: '>=16'
dependencies:
react: 18.2.0
tsparticles-engine: 2.12.0
dev: false
/react@18.2.0:
resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
engines: {node: '>=0.10.0'}
@ -3571,6 +3580,310 @@ packages:
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
dev: false
/tsparticles-basic@2.12.0:
resolution: {integrity: sha512-pN6FBpL0UsIUXjYbiui5+IVsbIItbQGOlwyGV55g6IYJBgdTNXgFX0HRYZGE9ZZ9psEXqzqwLM37zvWnb5AG9g==}
dependencies:
tsparticles-engine: 2.12.0
tsparticles-move-base: 2.12.0
tsparticles-shape-circle: 2.12.0
tsparticles-updater-color: 2.12.0
tsparticles-updater-opacity: 2.12.0
tsparticles-updater-out-modes: 2.12.0
tsparticles-updater-size: 2.12.0
dev: false
/tsparticles-engine@2.12.0:
resolution: {integrity: sha512-ZjDIYex6jBJ4iMc9+z0uPe7SgBnmb6l+EJm83MPIsOny9lPpetMsnw/8YJ3xdxn8hV+S3myTpTN1CkOVmFv0QQ==}
requiresBuild: true
dev: false
/tsparticles-interaction-external-attract@2.12.0:
resolution: {integrity: sha512-0roC6D1QkFqMVomcMlTaBrNVjVOpyNzxIUsjMfshk2wUZDAvTNTuWQdUpmsLS4EeSTDN3rzlGNnIuuUQqyBU5w==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-interaction-external-bounce@2.12.0:
resolution: {integrity: sha512-MMcqKLnQMJ30hubORtdq+4QMldQ3+gJu0bBYsQr9BsThsh8/V0xHc1iokZobqHYVP5tV77mbFBD8Z7iSCf0TMQ==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-interaction-external-bubble@2.12.0:
resolution: {integrity: sha512-5kImCSCZlLNccXOHPIi2Yn+rQWTX3sEa/xCHwXW19uHxtILVJlnAweayc8+Zgmb7mo0DscBtWVFXHPxrVPFDUA==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-interaction-external-connect@2.12.0:
resolution: {integrity: sha512-ymzmFPXz6AaA1LAOL5Ihuy7YSQEW8MzuSJzbd0ES13U8XjiU3HlFqlH6WGT1KvXNw6WYoqrZt0T3fKxBW3/C3A==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-interaction-external-grab@2.12.0:
resolution: {integrity: sha512-iQF/A947hSfDNqAjr49PRjyQaeRkYgTYpfNmAf+EfME8RsbapeP/BSyF6mTy0UAFC0hK2A2Hwgw72eT78yhXeQ==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-interaction-external-pause@2.12.0:
resolution: {integrity: sha512-4SUikNpsFROHnRqniL+uX2E388YTtfRWqqqZxRhY0BrijH4z04Aii3YqaGhJxfrwDKkTQlIoM2GbFT552QZWjw==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-interaction-external-push@2.12.0:
resolution: {integrity: sha512-kqs3V0dgDKgMoeqbdg+cKH2F+DTrvfCMrPF1MCCUpBCqBiH+TRQpJNNC86EZYHfNUeeLuIM3ttWwIkk2hllR/Q==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-interaction-external-remove@2.12.0:
resolution: {integrity: sha512-2eNIrv4m1WB2VfSVj46V2L/J9hNEZnMgFc+A+qmy66C8KzDN1G8aJUAf1inW8JVc0lmo5+WKhzex4X0ZSMghBg==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-interaction-external-repulse@2.12.0:
resolution: {integrity: sha512-rSzdnmgljeBCj5FPp4AtGxOG9TmTsK3AjQW0vlyd1aG2O5kSqFjR+FuT7rfdSk9LEJGH5SjPFE6cwbuy51uEWA==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-interaction-external-slow@2.12.0:
resolution: {integrity: sha512-2IKdMC3om7DttqyroMtO//xNdF0NvJL/Lx7LDo08VpfTgJJozxU+JAUT8XVT7urxhaDzbxSSIROc79epESROtA==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-interaction-external-trail@2.12.0:
resolution: {integrity: sha512-LKSapU5sPTaZqYx+y5VJClj0prlV7bswplSFQaIW1raXkvsk45qir2AVcpP5JUhZSFSG+SwsHr+qCgXhNeN1KA==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-interaction-particles-attract@2.12.0:
resolution: {integrity: sha512-Hl8qwuwF9aLq3FOkAW+Zomu7Gb8IKs6Y3tFQUQScDmrrSCaeRt2EGklAiwgxwgntmqzL7hbMWNx06CHHcUQKdQ==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-interaction-particles-collisions@2.12.0:
resolution: {integrity: sha512-Se9nPWlyPxdsnHgR6ap4YUImAu3W5MeGKJaQMiQpm1vW8lSMOUejI1n1ioIaQth9weKGKnD9rvcNn76sFlzGBA==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-interaction-particles-links@2.12.0:
resolution: {integrity: sha512-e7I8gRs4rmKfcsHONXMkJnymRWpxHmeaJIo4g2NaDRjIgeb2AcJSWKWZvrsoLnm7zvaf/cMQlbN6vQwCixYq3A==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-move-base@2.12.0:
resolution: {integrity: sha512-oSogCDougIImq+iRtIFJD0YFArlorSi8IW3HD2gO3USkH+aNn3ZqZNTqp321uB08K34HpS263DTbhLHa/D6BWw==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-move-parallax@2.12.0:
resolution: {integrity: sha512-58CYXaX8Ih5rNtYhpnH0YwU4Ks7gVZMREGUJtmjhuYN+OFr9FVdF3oDIJ9N6gY5a5AnAKz8f5j5qpucoPRcYrQ==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-particles.js@2.12.0:
resolution: {integrity: sha512-LyOuvYdhbUScmA4iDgV3LxA0HzY1DnOwQUy3NrPYO393S2YwdDjdwMod6Btq7EBUjg9FVIh+sZRizgV5elV2dg==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-plugin-absorbers@2.12.0:
resolution: {integrity: sha512-2CkPreaXHrE5VzFlxUKLeRB5t66ff+3jwLJoDFgQcp+R4HOEITo0bBZv2DagGP0QZdYN4grpnQzRBVdB4d1rWA==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-plugin-easing-quad@2.12.0:
resolution: {integrity: sha512-2mNqez5pydDewMIUWaUhY5cNQ80IUOYiujwG6qx9spTq1D6EEPLbRNAEL8/ecPdn2j1Um3iWSx6lo340rPkv4Q==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-plugin-emitters@2.12.0:
resolution: {integrity: sha512-fbskYnaXWXivBh9KFReVCfqHdhbNQSK2T+fq2qcGEWpwtDdgujcaS1k2Q/xjZnWNMfVesik4IrqspcL51gNdSA==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-shape-circle@2.12.0:
resolution: {integrity: sha512-L6OngbAlbadG7b783x16ns3+SZ7i0SSB66M8xGa5/k+YcY7zm8zG0uPt1Hd+xQDR2aNA3RngVM10O23/Lwk65Q==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-shape-image@2.12.0:
resolution: {integrity: sha512-iCkSdUVa40DxhkkYjYuYHr9MJGVw+QnQuN5UC+e/yBgJQY+1tQL8UH0+YU/h0GHTzh5Sm+y+g51gOFxHt1dj7Q==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-shape-line@2.12.0:
resolution: {integrity: sha512-RcpKmmpKlk+R8mM5wA2v64Lv1jvXtU4SrBDv3vbdRodKbKaWGGzymzav1Q0hYyDyUZgplEK/a5ZwrfrOwmgYGA==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-shape-polygon@2.12.0:
resolution: {integrity: sha512-5YEy7HVMt1Obxd/jnlsjajchAlYMr9eRZWN+lSjcFSH6Ibra7h59YuJVnwxOxAobpijGxsNiBX0PuGQnB47pmA==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-shape-square@2.12.0:
resolution: {integrity: sha512-33vfajHqmlODKaUzyPI/aVhnAOT09V7nfEPNl8DD0cfiNikEuPkbFqgJezJuE55ebtVo7BZPDA9o7GYbWxQNuw==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-shape-star@2.12.0:
resolution: {integrity: sha512-4sfG/BBqm2qBnPLASl2L5aBfCx86cmZLXeh49Un+TIR1F5Qh4XUFsahgVOG0vkZQa+rOsZPEH04xY5feWmj90g==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-shape-text@2.12.0:
resolution: {integrity: sha512-v2/FCA+hyTbDqp2ymFOe97h/NFb2eezECMrdirHWew3E3qlvj9S/xBibjbpZva2gnXcasBwxn0+LxKbgGdP0rA==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-slim@2.12.0:
resolution: {integrity: sha512-27w9aGAAAPKHvP4LHzWFpyqu7wKyulayyaZ/L6Tuuejy4KP4BBEB4rY5GG91yvAPsLtr6rwWAn3yS+uxnBDpkA==}
dependencies:
tsparticles-basic: 2.12.0
tsparticles-engine: 2.12.0
tsparticles-interaction-external-attract: 2.12.0
tsparticles-interaction-external-bounce: 2.12.0
tsparticles-interaction-external-bubble: 2.12.0
tsparticles-interaction-external-connect: 2.12.0
tsparticles-interaction-external-grab: 2.12.0
tsparticles-interaction-external-pause: 2.12.0
tsparticles-interaction-external-push: 2.12.0
tsparticles-interaction-external-remove: 2.12.0
tsparticles-interaction-external-repulse: 2.12.0
tsparticles-interaction-external-slow: 2.12.0
tsparticles-interaction-particles-attract: 2.12.0
tsparticles-interaction-particles-collisions: 2.12.0
tsparticles-interaction-particles-links: 2.12.0
tsparticles-move-base: 2.12.0
tsparticles-move-parallax: 2.12.0
tsparticles-particles.js: 2.12.0
tsparticles-plugin-easing-quad: 2.12.0
tsparticles-shape-circle: 2.12.0
tsparticles-shape-image: 2.12.0
tsparticles-shape-line: 2.12.0
tsparticles-shape-polygon: 2.12.0
tsparticles-shape-square: 2.12.0
tsparticles-shape-star: 2.12.0
tsparticles-shape-text: 2.12.0
tsparticles-updater-color: 2.12.0
tsparticles-updater-life: 2.12.0
tsparticles-updater-opacity: 2.12.0
tsparticles-updater-out-modes: 2.12.0
tsparticles-updater-rotate: 2.12.0
tsparticles-updater-size: 2.12.0
tsparticles-updater-stroke-color: 2.12.0
dev: false
/tsparticles-updater-color@2.12.0:
resolution: {integrity: sha512-KcG3a8zd0f8CTiOrylXGChBrjhKcchvDJjx9sp5qpwQK61JlNojNCU35xoaSk2eEHeOvFjh0o3CXWUmYPUcBTQ==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-updater-destroy@2.12.0:
resolution: {integrity: sha512-6NN3dJhxACvzbIGL4dADbYQSZJmdHfwjujj1uvnxdMbb2x8C/AZzGxiN33smo4jkrZ5VLEWZWCJPJ8aOKjQ2Sg==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-updater-life@2.12.0:
resolution: {integrity: sha512-J7RWGHAZkowBHpcLpmjKsxwnZZJ94oGEL2w+wvW1/+ZLmAiFFF6UgU0rHMC5CbHJT4IPx9cbkYMEHsBkcRJ0Bw==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-updater-opacity@2.12.0:
resolution: {integrity: sha512-YUjMsgHdaYi4HN89LLogboYcCi1o9VGo21upoqxq19yRy0hRCtx2NhH22iHF/i5WrX6jqshN0iuiiNefC53CsA==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-updater-out-modes@2.12.0:
resolution: {integrity: sha512-owBp4Gk0JNlSrmp12XVEeBroDhLZU+Uq3szbWlHGSfcR88W4c/0bt0FiH5bHUqORIkw+m8O56hCjbqwj69kpOQ==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-updater-roll@2.12.0:
resolution: {integrity: sha512-dxoxY5jP4C9x15BxlUv5/Q8OjUPBiE09ToXRyBxea9aEJ7/iMw6odvi1HuT0H1vTIfV7o1MYawjeCbMycvODKQ==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-updater-rotate@2.12.0:
resolution: {integrity: sha512-waOFlGFmEZOzsQg4C4VSejNVXGf4dMf3fsnQrEROASGf1FCd8B6WcZau7JtXSTFw0OUGuk8UGz36ETWN72DkCw==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-updater-size@2.12.0:
resolution: {integrity: sha512-B0yRdEDd/qZXCGDL/ussHfx5YJ9UhTqNvmS5X2rR2hiZhBAE2fmsXLeWkdtF2QusjPeEqFDxrkGiLOsh6poqRA==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-updater-stroke-color@2.12.0:
resolution: {integrity: sha512-MPou1ZDxsuVq6SN1fbX+aI5yrs6FyP2iPCqqttpNbWyL+R6fik1rL0ab/x02B57liDXqGKYomIbBQVP3zUTW1A==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-updater-tilt@2.12.0:
resolution: {integrity: sha512-HDEFLXazE+Zw+kkKKAiv0Fs9D9sRP61DoCR6jZ36ipea6OBgY7V1Tifz2TSR1zoQkk57ER9+EOQbkSQO+YIPGQ==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-updater-twinkle@2.12.0:
resolution: {integrity: sha512-JhK/DO4kTx7IFwMBP2EQY9hBaVVvFnGBvX21SQWcjkymmN1hZ+NdcgUtR9jr4jUiiSNdSl7INaBuGloVjWvOgA==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles-updater-wobble@2.12.0:
resolution: {integrity: sha512-85FIRl95ipD3jfIsQdDzcUC5PRMWIrCYqBq69nIy9P8rsNzygn+JK2n+P1VQZowWsZvk0mYjqb9OVQB21Lhf6Q==}
dependencies:
tsparticles-engine: 2.12.0
dev: false
/tsparticles@2.12.0:
resolution: {integrity: sha512-aw77llkaEhcKYUHuRlggA6SB1Dpa814/nrStp9USGiDo5QwE1Ckq30QAgdXU6GRvnblUFsiO750ZuLQs5Y0tVw==}
dependencies:
tsparticles-engine: 2.12.0
tsparticles-interaction-external-trail: 2.12.0
tsparticles-plugin-absorbers: 2.12.0
tsparticles-plugin-emitters: 2.12.0
tsparticles-slim: 2.12.0
tsparticles-updater-destroy: 2.12.0
tsparticles-updater-roll: 2.12.0
tsparticles-updater-tilt: 2.12.0
tsparticles-updater-twinkle: 2.12.0
tsparticles-updater-wobble: 2.12.0
dev: false
/type-check@0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'}

View File

@ -1,109 +0,0 @@
{
"particles": {
"number": {
"value": 50,
"density": {
"enable": true,
"value_area": 800
}
},
"color": {
"value": "#000"
},
"shape": {
"type": "circle",
"stroke": {
"width": 0,
"color": "#000000"
},
"polygon": {
"nb_sides": 5
},
"image": {
"src": "img/github.svg",
"width": 100,
"height": 100
}
},
"opacity": {
"value": 0.5,
"random": false,
"anim": {
"enable": false,
"speed": 1,
"opacity_min": 0.1,
"sync": false
}
},
"size": {
"value": 10,
"random": true,
"anim": {
"enable": false,
"speed": 80,
"size_min": 0.1,
"sync": false
}
},
"line_linked": {
"enable": true,
"distance": 150,
"color": "#000",
"opacity": 0.4,
"width": 2
},
"move": {
"enable": true,
"speed": 6,
"direction": "none",
"random": false,
"straight": false,
"out_mode": "out",
"bounce": false,
"attract": {
"enable": false,
"rotateX": 600,
"rotateY": 1200
}
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": true,
"mode": "repulse"
},
"onclick": {
"enable": false,
"mode": "push"
},
"resize": true
},
"modes": {
"grab": {
"distance": 150,
"line_linked": {
"opacity": 1
}
},
"bubble": {
"distance": 800,
"size": 80,
"duration": 2,
"opacity": 0.8,
"speed": 3
},
"repulse": {
"distance": 400,
"duration": 0.4
},
"push": {
"particles_nb": 4
},
"remove": {
"particles_nb": 2
}
}
}
}

View File

@ -1,9 +1,12 @@
import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { useGoogleLogin } from "@react-oauth/google";
import { useCallback } from "react";
import Particles from "react-tsparticles";
import { loadFull } from "tsparticles";
import refreshAccessToken from "./refreshAcesstoken";
import axiosapi from "../../api/AuthenticationApi";
import { useAuth } from "../../hooks/authentication/IsAuthenticated";
import { useAuth } from "../../hooks/authentication/IsAuthenticated";
function LoginPage() {
const Navigate = useNavigate();
@ -18,15 +21,14 @@ function LoginPage() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const handleEmailChange = event => {
const handleEmailChange = (event) => {
setEmail(event.target.value);
};
const handlePasswordChange = event => {
const handlePasswordChange = (event) => {
setPassword(event.target.value);
};
const handleSubmit = event => {
const handleSubmit = (event) => {
event.preventDefault();
// Send a POST request to the authentication API
@ -35,15 +37,16 @@ function LoginPage() {
email: email,
password: password,
})
.then(res => {
.then((res) => {
// On successful login, store tokens and set the authorization header
localStorage.setItem("access_token", res.data.access);
localStorage.setItem("refresh_token", res.data.refresh);
axiosapi.axiosInstance.defaults.headers["Authorization"] = "Bearer " + res.data.access;
axiosapi.axiosInstance.defaults.headers["Authorization"] =
"Bearer " + res.data.access;
setIsAuthenticated(true);
Navigate("/");
})
.catch(err => {
.catch((err) => {
console.log("Login failed");
console.log(err);
setIsAuthenticated(false);
@ -53,7 +56,7 @@ function LoginPage() {
const googleLoginImplicit = useGoogleLogin({
flow: "auth-code",
redirect_uri: "postmessage",
onSuccess: async response => {
onSuccess: async (response) => {
try {
const loginResponse = await axiosapi.googleLogin(response.code);
if (loginResponse && loginResponse.data) {
@ -69,23 +72,99 @@ function LoginPage() {
setIsAuthenticated(false);
}
},
onError: errorResponse => console.log(errorResponse),
onError: (errorResponse) => console.log(errorResponse),
});
useEffect(() => {
// Load particles.js configuration
particlesJS.load('particles-js', 'src/assets/particles.json', function() {
console.log('callback - particles.js config loaded');
});
const particlesInit = useCallback(async (engine) => {
console.log(engine);
await loadFull(engine);
}, []);
const particlesLoaded = useCallback(async (container) => {
console.log(container);
}, []);
return (
<div data-theme="night" className="h-screen flex">
<div id="particles-js" className="absolute inset-0 "></div>
{/* Left Section (Login Box) */}
<div className="w-1/2 flex items-center justify-center">
<div className="w-96 bg-neutral rounded-lg p-8 shadow-md space-y-4">
<h2 className="text-2xl font-semibold text-left">Log in to your account</h2>
<div
data-theme="night"
className="h-screen flex items-center justify-center"
>
{/* Particles Container */}
<div style={{ width: "0%", height: "100vh" }}>
<Particles
id="particles"
init={particlesInit}
loaded={particlesLoaded}
className="-z-10"
options={{
fpsLimit: 240,
interactivity: {
events: {
onClick: {
enable: true,
mode: "push",
},
onHover: {
enable: true,
mode: "repulse",
},
resize: true,
},
modes: {
push: {
quantity: 4,
},
repulse: {
distance: 200,
duration: 0.4,
},
},
},
particles: {
color: {
value: "#008000",
},
links: {
color: "#ffffff",
distance: 150,
enable: true,
opacity: 0.1,
width: 1,
},
move: {
direction: "none",
enable: true,
outModes: {
default: "bounce",
},
random: false,
speed: 4,
straight: false,
},
number: {
density: {
enable: true,
area: 800,
},
value: 50,
},
opacity: {
value: 0.5,
},
shape: {
type: "circle",
},
size: {
value: { min: 4, max: 5 },
},
},
detectRetina: true,
}}
/>
</div>
{/* Login Box */}
<div className="w-1/4 flex items-center justify-center">
<div className="w-96 bg-neutral rounded-lg p-8 shadow-md space-y-4 z-10">
<h2 className="text-4xl font-semibold text-center">Login</h2>
{/* Email Input */}
<div className="form-control ">
<label className="label" htmlFor="email">
@ -98,7 +177,6 @@ function LoginPage() {
type="email"
id="email"
placeholder="Enter your email"
onChange={handleEmailChange}
/>
</div>
@ -123,7 +201,10 @@ function LoginPage() {
</button>
<div className="divider">OR</div>
{/* Login with Google Button */}
<button className="btn btn-outline btn-secondary w-full " onClick={() => googleLoginImplicit()}>
<button
className="btn btn-outline btn-secondary w-full "
onClick={() => googleLoginImplicit()}
>
Login with Google
</button>
{/* Forgot Password Link */}
@ -134,7 +215,6 @@ function LoginPage() {
</div>
</div>
</div>
</div>
);
}