From fae6b16bb6b53bdb7c6aa0a8d5184fe1b657154c Mon Sep 17 00:00:00 2001 From: Leo dev Date: Sun, 21 Sep 2025 19:46:11 +0200 Subject: [PATCH] Updated layout and background --- package-lock.json | 449 ++++++++++++++++++++++++++++++++- package.json | 3 +- src/app/api/blog/route.ts | 17 -- src/app/api/route.ts | 5 - src/app/api/search/route.ts | 11 - src/app/blog/[id]/page.tsx | 71 ------ src/app/blog/[id]/style.css | 11 - src/app/blog/page.tsx | 95 ------- src/app/globals.css | 9 - src/app/layout.tsx | 6 +- src/app/page.tsx | 84 +++--- src/app/pricing/page.tsx | 181 ------------- src/components/Background.css | 290 --------------------- src/components/Background.tsx | 218 +++++++++++++--- src/components/Navbar.tsx | 9 - src/components/PinnedRepos.tsx | 29 ++- src/components/Skill.tsx | 21 +- 17 files changed, 713 insertions(+), 796 deletions(-) delete mode 100644 src/app/api/blog/route.ts delete mode 100644 src/app/api/route.ts delete mode 100644 src/app/api/search/route.ts delete mode 100644 src/app/blog/[id]/page.tsx delete mode 100644 src/app/blog/[id]/style.css delete mode 100644 src/app/blog/page.tsx delete mode 100644 src/app/pricing/page.tsx delete mode 100644 src/components/Background.css diff --git a/package-lock.json b/package-lock.json index 0ef10dd..e550702 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,8 @@ "rehype-raw": "^7.0.0", "remark-breaks": "^4.0.0", "remark-gfm": "^4.0.0", - "remark-math": "^6.0.0" + "remark-math": "^6.0.0", + "tsparticles-slim": "^2.12.0" }, "devDependencies": { "@types/node": "^20", @@ -4535,6 +4536,452 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/tsparticles-basic": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-basic/-/tsparticles-basic-2.12.0.tgz", + "integrity": "sha512-pN6FBpL0UsIUXjYbiui5+IVsbIItbQGOlwyGV55g6IYJBgdTNXgFX0HRYZGE9ZZ9psEXqzqwLM37zvWnb5AG9g==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/matteobruni" + }, + { + "type": "github", + "url": "https://github.com/sponsors/tsparticles" + }, + { + "type": "buymeacoffee", + "url": "https://www.buymeacoffee.com/matteobruni" + } + ], + "license": "MIT", + "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" + } + }, + "node_modules/tsparticles-engine": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-engine/-/tsparticles-engine-2.12.0.tgz", + "integrity": "sha512-ZjDIYex6jBJ4iMc9+z0uPe7SgBnmb6l+EJm83MPIsOny9lPpetMsnw/8YJ3xdxn8hV+S3myTpTN1CkOVmFv0QQ==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/matteobruni" + }, + { + "type": "github", + "url": "https://github.com/sponsors/tsparticles" + }, + { + "type": "buymeacoffee", + "url": "https://www.buymeacoffee.com/matteobruni" + } + ], + "hasInstallScript": true, + "license": "MIT" + }, + "node_modules/tsparticles-interaction-external-attract": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-interaction-external-attract/-/tsparticles-interaction-external-attract-2.12.0.tgz", + "integrity": "sha512-0roC6D1QkFqMVomcMlTaBrNVjVOpyNzxIUsjMfshk2wUZDAvTNTuWQdUpmsLS4EeSTDN3rzlGNnIuuUQqyBU5w==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-interaction-external-bounce": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-interaction-external-bounce/-/tsparticles-interaction-external-bounce-2.12.0.tgz", + "integrity": "sha512-MMcqKLnQMJ30hubORtdq+4QMldQ3+gJu0bBYsQr9BsThsh8/V0xHc1iokZobqHYVP5tV77mbFBD8Z7iSCf0TMQ==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-interaction-external-bubble": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-interaction-external-bubble/-/tsparticles-interaction-external-bubble-2.12.0.tgz", + "integrity": "sha512-5kImCSCZlLNccXOHPIi2Yn+rQWTX3sEa/xCHwXW19uHxtILVJlnAweayc8+Zgmb7mo0DscBtWVFXHPxrVPFDUA==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-interaction-external-connect": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-interaction-external-connect/-/tsparticles-interaction-external-connect-2.12.0.tgz", + "integrity": "sha512-ymzmFPXz6AaA1LAOL5Ihuy7YSQEW8MzuSJzbd0ES13U8XjiU3HlFqlH6WGT1KvXNw6WYoqrZt0T3fKxBW3/C3A==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-interaction-external-grab": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-interaction-external-grab/-/tsparticles-interaction-external-grab-2.12.0.tgz", + "integrity": "sha512-iQF/A947hSfDNqAjr49PRjyQaeRkYgTYpfNmAf+EfME8RsbapeP/BSyF6mTy0UAFC0hK2A2Hwgw72eT78yhXeQ==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-interaction-external-pause": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-interaction-external-pause/-/tsparticles-interaction-external-pause-2.12.0.tgz", + "integrity": "sha512-4SUikNpsFROHnRqniL+uX2E388YTtfRWqqqZxRhY0BrijH4z04Aii3YqaGhJxfrwDKkTQlIoM2GbFT552QZWjw==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-interaction-external-push": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-interaction-external-push/-/tsparticles-interaction-external-push-2.12.0.tgz", + "integrity": "sha512-kqs3V0dgDKgMoeqbdg+cKH2F+DTrvfCMrPF1MCCUpBCqBiH+TRQpJNNC86EZYHfNUeeLuIM3ttWwIkk2hllR/Q==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-interaction-external-remove": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-interaction-external-remove/-/tsparticles-interaction-external-remove-2.12.0.tgz", + "integrity": "sha512-2eNIrv4m1WB2VfSVj46V2L/J9hNEZnMgFc+A+qmy66C8KzDN1G8aJUAf1inW8JVc0lmo5+WKhzex4X0ZSMghBg==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-interaction-external-repulse": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-interaction-external-repulse/-/tsparticles-interaction-external-repulse-2.12.0.tgz", + "integrity": "sha512-rSzdnmgljeBCj5FPp4AtGxOG9TmTsK3AjQW0vlyd1aG2O5kSqFjR+FuT7rfdSk9LEJGH5SjPFE6cwbuy51uEWA==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-interaction-external-slow": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-interaction-external-slow/-/tsparticles-interaction-external-slow-2.12.0.tgz", + "integrity": "sha512-2IKdMC3om7DttqyroMtO//xNdF0NvJL/Lx7LDo08VpfTgJJozxU+JAUT8XVT7urxhaDzbxSSIROc79epESROtA==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-interaction-particles-attract": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-interaction-particles-attract/-/tsparticles-interaction-particles-attract-2.12.0.tgz", + "integrity": "sha512-Hl8qwuwF9aLq3FOkAW+Zomu7Gb8IKs6Y3tFQUQScDmrrSCaeRt2EGklAiwgxwgntmqzL7hbMWNx06CHHcUQKdQ==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-interaction-particles-collisions": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-interaction-particles-collisions/-/tsparticles-interaction-particles-collisions-2.12.0.tgz", + "integrity": "sha512-Se9nPWlyPxdsnHgR6ap4YUImAu3W5MeGKJaQMiQpm1vW8lSMOUejI1n1ioIaQth9weKGKnD9rvcNn76sFlzGBA==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-interaction-particles-links": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-interaction-particles-links/-/tsparticles-interaction-particles-links-2.12.0.tgz", + "integrity": "sha512-e7I8gRs4rmKfcsHONXMkJnymRWpxHmeaJIo4g2NaDRjIgeb2AcJSWKWZvrsoLnm7zvaf/cMQlbN6vQwCixYq3A==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-move-base": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-move-base/-/tsparticles-move-base-2.12.0.tgz", + "integrity": "sha512-oSogCDougIImq+iRtIFJD0YFArlorSi8IW3HD2gO3USkH+aNn3ZqZNTqp321uB08K34HpS263DTbhLHa/D6BWw==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-move-parallax": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-move-parallax/-/tsparticles-move-parallax-2.12.0.tgz", + "integrity": "sha512-58CYXaX8Ih5rNtYhpnH0YwU4Ks7gVZMREGUJtmjhuYN+OFr9FVdF3oDIJ9N6gY5a5AnAKz8f5j5qpucoPRcYrQ==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-particles.js": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-particles.js/-/tsparticles-particles.js-2.12.0.tgz", + "integrity": "sha512-LyOuvYdhbUScmA4iDgV3LxA0HzY1DnOwQUy3NrPYO393S2YwdDjdwMod6Btq7EBUjg9FVIh+sZRizgV5elV2dg==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/matteobruni" + }, + { + "type": "github", + "url": "https://github.com/sponsors/tsparticles" + }, + { + "type": "buymeacoffee", + "url": "https://www.buymeacoffee.com/matteobruni" + } + ], + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-plugin-easing-quad": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-plugin-easing-quad/-/tsparticles-plugin-easing-quad-2.12.0.tgz", + "integrity": "sha512-2mNqez5pydDewMIUWaUhY5cNQ80IUOYiujwG6qx9spTq1D6EEPLbRNAEL8/ecPdn2j1Um3iWSx6lo340rPkv4Q==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/matteobruni" + }, + { + "type": "github", + "url": "https://github.com/sponsors/tsparticles" + }, + { + "type": "buymeacoffee", + "url": "https://www.buymeacoffee.com/matteobruni" + } + ], + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-shape-circle": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-shape-circle/-/tsparticles-shape-circle-2.12.0.tgz", + "integrity": "sha512-L6OngbAlbadG7b783x16ns3+SZ7i0SSB66M8xGa5/k+YcY7zm8zG0uPt1Hd+xQDR2aNA3RngVM10O23/Lwk65Q==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-shape-image": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-shape-image/-/tsparticles-shape-image-2.12.0.tgz", + "integrity": "sha512-iCkSdUVa40DxhkkYjYuYHr9MJGVw+QnQuN5UC+e/yBgJQY+1tQL8UH0+YU/h0GHTzh5Sm+y+g51gOFxHt1dj7Q==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-shape-line": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-shape-line/-/tsparticles-shape-line-2.12.0.tgz", + "integrity": "sha512-RcpKmmpKlk+R8mM5wA2v64Lv1jvXtU4SrBDv3vbdRodKbKaWGGzymzav1Q0hYyDyUZgplEK/a5ZwrfrOwmgYGA==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-shape-polygon": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-shape-polygon/-/tsparticles-shape-polygon-2.12.0.tgz", + "integrity": "sha512-5YEy7HVMt1Obxd/jnlsjajchAlYMr9eRZWN+lSjcFSH6Ibra7h59YuJVnwxOxAobpijGxsNiBX0PuGQnB47pmA==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-shape-square": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-shape-square/-/tsparticles-shape-square-2.12.0.tgz", + "integrity": "sha512-33vfajHqmlODKaUzyPI/aVhnAOT09V7nfEPNl8DD0cfiNikEuPkbFqgJezJuE55ebtVo7BZPDA9o7GYbWxQNuw==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-shape-star": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-shape-star/-/tsparticles-shape-star-2.12.0.tgz", + "integrity": "sha512-4sfG/BBqm2qBnPLASl2L5aBfCx86cmZLXeh49Un+TIR1F5Qh4XUFsahgVOG0vkZQa+rOsZPEH04xY5feWmj90g==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-shape-text": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-shape-text/-/tsparticles-shape-text-2.12.0.tgz", + "integrity": "sha512-v2/FCA+hyTbDqp2ymFOe97h/NFb2eezECMrdirHWew3E3qlvj9S/xBibjbpZva2gnXcasBwxn0+LxKbgGdP0rA==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-slim": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-slim/-/tsparticles-slim-2.12.0.tgz", + "integrity": "sha512-27w9aGAAAPKHvP4LHzWFpyqu7wKyulayyaZ/L6Tuuejy4KP4BBEB4rY5GG91yvAPsLtr6rwWAn3yS+uxnBDpkA==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/matteobruni" + }, + { + "type": "github", + "url": "https://github.com/sponsors/tsparticles" + }, + { + "type": "buymeacoffee", + "url": "https://www.buymeacoffee.com/matteobruni" + } + ], + "license": "MIT", + "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" + } + }, + "node_modules/tsparticles-updater-color": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-updater-color/-/tsparticles-updater-color-2.12.0.tgz", + "integrity": "sha512-KcG3a8zd0f8CTiOrylXGChBrjhKcchvDJjx9sp5qpwQK61JlNojNCU35xoaSk2eEHeOvFjh0o3CXWUmYPUcBTQ==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-updater-life": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-updater-life/-/tsparticles-updater-life-2.12.0.tgz", + "integrity": "sha512-J7RWGHAZkowBHpcLpmjKsxwnZZJ94oGEL2w+wvW1/+ZLmAiFFF6UgU0rHMC5CbHJT4IPx9cbkYMEHsBkcRJ0Bw==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-updater-opacity": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-updater-opacity/-/tsparticles-updater-opacity-2.12.0.tgz", + "integrity": "sha512-YUjMsgHdaYi4HN89LLogboYcCi1o9VGo21upoqxq19yRy0hRCtx2NhH22iHF/i5WrX6jqshN0iuiiNefC53CsA==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-updater-out-modes": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-updater-out-modes/-/tsparticles-updater-out-modes-2.12.0.tgz", + "integrity": "sha512-owBp4Gk0JNlSrmp12XVEeBroDhLZU+Uq3szbWlHGSfcR88W4c/0bt0FiH5bHUqORIkw+m8O56hCjbqwj69kpOQ==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-updater-rotate": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-updater-rotate/-/tsparticles-updater-rotate-2.12.0.tgz", + "integrity": "sha512-waOFlGFmEZOzsQg4C4VSejNVXGf4dMf3fsnQrEROASGf1FCd8B6WcZau7JtXSTFw0OUGuk8UGz36ETWN72DkCw==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-updater-size": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-updater-size/-/tsparticles-updater-size-2.12.0.tgz", + "integrity": "sha512-B0yRdEDd/qZXCGDL/ussHfx5YJ9UhTqNvmS5X2rR2hiZhBAE2fmsXLeWkdtF2QusjPeEqFDxrkGiLOsh6poqRA==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, + "node_modules/tsparticles-updater-stroke-color": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/tsparticles-updater-stroke-color/-/tsparticles-updater-stroke-color-2.12.0.tgz", + "integrity": "sha512-MPou1ZDxsuVq6SN1fbX+aI5yrs6FyP2iPCqqttpNbWyL+R6fik1rL0ab/x02B57liDXqGKYomIbBQVP3zUTW1A==", + "deprecated": "starting from tsparticles v3 the packages are now moved to @tsparticles/package-name instead of tsparticles-package-name", + "license": "MIT", + "dependencies": { + "tsparticles-engine": "^2.12.0" + } + }, "node_modules/typescript": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", diff --git a/package.json b/package.json index f08d42b..75f200f 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,8 @@ "rehype-raw": "^7.0.0", "remark-breaks": "^4.0.0", "remark-gfm": "^4.0.0", - "remark-math": "^6.0.0" + "remark-math": "^6.0.0", + "tsparticles-slim": "^2.12.0" }, "devDependencies": { "@types/node": "^20", diff --git a/src/app/api/blog/route.ts b/src/app/api/blog/route.ts deleted file mode 100644 index 197d5dc..0000000 --- a/src/app/api/blog/route.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { getBlog, getBlogs } from "@/blogApi"; -import { notion, databaseId, n2m } from "@/notion"; - -export async function GET(request: Request) { - const url = new URL(request.url); - const id = url.searchParams.get("id"); - if (id) { - let [status, data] = await getBlog(notion, n2m, id); - return Response.json(data, { status }); - } else { - var cursor = url.searchParams.get("cursor") || undefined; - if (cursor === "") cursor = undefined; - const size = parseInt(url.searchParams.get("size") || "5"); - let [status, response] = await getBlogs(notion, databaseId, cursor, size); - return Response.json(response, { status }); - } -} diff --git a/src/app/api/route.ts b/src/app/api/route.ts deleted file mode 100644 index b1b21f6..0000000 --- a/src/app/api/route.ts +++ /dev/null @@ -1,5 +0,0 @@ -export function GET(req: Request) { - return new Response(JSON.stringify({ - version: "1.0.2", - })); -} diff --git a/src/app/api/search/route.ts b/src/app/api/search/route.ts deleted file mode 100644 index 8fd0a8f..0000000 --- a/src/app/api/search/route.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { getBlogs, searchBlog } from "@/blogApi"; -import { notion, databaseId } from "@/notion"; - -export async function GET(request: Request) { - const url = new URL(request.url); - let [status, response] = await searchBlog( - notion, - url.searchParams.get("query") || "" - ); - return Response.json(response, { status }); -} diff --git a/src/app/blog/[id]/page.tsx b/src/app/blog/[id]/page.tsx deleted file mode 100644 index b1a3210..0000000 --- a/src/app/blog/[id]/page.tsx +++ /dev/null @@ -1,71 +0,0 @@ -"use client"; - -import MarkdownRenderer from "@/components/MarkdownRenderer"; -import { useEffect, useState } from "react"; -import "./style.css"; - -type Blog = { - title: string; - description: string; - id: string; - tags: { name: string; color: string }[]; - markdown: string; - date: string; -}; - -export default function Blog({ params }: { params: Promise<{ id: string }> }) { - const [blog, setBlog] = useState(null); - - useEffect(() => { - params.then(({ id }) => - fetch(`/api/blog/?id=${id}`) - .then((res) => { - res - .json() - .then((response) => { - if (res.status === 200) { - setBlog(response); - } else { - console.error(`'/api/blog/${id}' Error:`, response.msg); - } - }) - .catch((e) => { - console.error(`'/api/blog/${id}' Unable to obtain json:`, e); - }); - }) - .catch((e) => { - console.error(`'/api/blog/${id}' Error:`, e); - }) - ); - }, [params]); - - return ( -
-
-
-
-
- {blog ? ( -
-

{blog.title}

-

- {new Date(blog.date).toDateString()} -

-
- - {blog.markdown - .replaceAll(/\n!\n/g, "\n
\n") - .replaceAll(/\n-/g, "\n\n-")} -
-
-
- ) : ( - "" - )} -
-
-
-
-
- ); -} diff --git a/src/app/blog/[id]/style.css b/src/app/blog/[id]/style.css deleted file mode 100644 index b39d2ed..0000000 --- a/src/app/blog/[id]/style.css +++ /dev/null @@ -1,11 +0,0 @@ -.blog-md h1 { - color: #fa5770; -} - -.blog-md a { - color: #fa5770; -} - -.blog-md code { - color: #fa5770; -} \ No newline at end of file diff --git a/src/app/blog/page.tsx b/src/app/blog/page.tsx deleted file mode 100644 index 3dff79a..0000000 --- a/src/app/blog/page.tsx +++ /dev/null @@ -1,95 +0,0 @@ -"use client"; - -import Link from "next/link"; -import { useEffect, useState } from "react"; - -type Blog = { - title: string; - description: string; - id: string; - tags: { name: string; color: string }[]; -}; - -export default function Blog() { - const [blogs, setBlogs] = useState([]); - const [searchQuery, setSearchQuery] = useState(""); - - const fetchBlogs = (query: string) => { - (query === "" - ? fetch("/api/blog/") - : fetch(`/api/search/?query=${encodeURIComponent(query)}`) - ) - .then((res) => { - res - .json() - .then((response) => { - if (response && response.items) { - setBlogs(response.items); - } else { - console.error("`/api/blog/` Response is invalid:", response); - } - }) - .catch((e) => { - console.error("`/api/blog/` Unable to obtain json:", e); - }); - }) - .catch((e) => { - console.error("`/api/blog/` Error:", e); - }); - }; - - useEffect(() => { - const handler = setTimeout(() => { - fetchBlogs(searchQuery); - }, 500); - - return () => clearTimeout(handler); - }, [searchQuery]); - - return ( -
-
-
-
-
-

Leo's blog

- setSearchQuery(event.target.value)} - placeholder="Search" - /> -
- {blogs.map((blog, i) => ( -
-

- {blog.title} -

-

- {blog.description} -

-
- {blog.tags.map((tag, i) => ( - - {tag.name} - - ))} -
-
- ))} -
-
-
-
-
-
- ); -} diff --git a/src/app/globals.css b/src/app/globals.css index b325a8e..8e68a8c 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -38,13 +38,4 @@ body { h1 { font-size: 30px; font-weight: bold; -} - -.skill .tooltip { - opacity: 0; - transition: opacity .3s linear; -} - -.skill:hover .tooltip { - opacity: 1; } \ No newline at end of file diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 12b3c67..686657a 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -16,9 +16,9 @@ export default function RootLayout({ return ( - - - {children} + + {children} + ); diff --git a/src/app/page.tsx b/src/app/page.tsx index 129cb29..ee1dbc2 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -10,76 +10,70 @@ import { faReact, faRust, } from "@fortawesome/free-brands-svg-icons"; +import { faJava } from "@fortawesome/free-brands-svg-icons/faJava"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; export default function App() { return (
-
+
-

Hey, I'm Leo 👋🏻

+

Hey, I'm Klesti! 👋🏻

A 15 year old Software Engineer from Tirane, Albania, with 5 years of experience, specializing in full-stack web development, desktop applications, TUI apps, and hacking. I have a deep interest in low-level programming.

- -

Pinned Projects

-
- -
- {/* Experience and skill */} + {/* Socials and skill */}
- {/* skill */} + {/* socials */} +
-

My Skills

- - + + +
- - {/* Experience */} -
-

My Experience

-
-
Soon
-
-
+ +

Pinned Projects

+
+ +
diff --git a/src/app/pricing/page.tsx b/src/app/pricing/page.tsx deleted file mode 100644 index bf1bc99..0000000 --- a/src/app/pricing/page.tsx +++ /dev/null @@ -1,181 +0,0 @@ -import { - faCheck, - faCode, - faDatabase, - faRocket, - faWrench, -} from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; - -export default function Pricing() { - return ( -
- {/* */} -
-
-

Pricing plans

-
-
- -

Standard

-

$25

-
    -
  • - - 24-48 hours -
  • -
  • - - Simple projects or tasks (e.g., bug fixes) -
  • -
  • - - Response via Email or Discord -
  • -
-
- -
- -

Premium

-

$50

-
    -
  • - - Up to a week -
  • -
  • - - Complex projects -
  • -
  • - - Large tasks (e.g., refractoring, bug hunting) -
  • -
  • - - Documenting -
  • -
-
- -
- -

Enterprise

-

$200

-
    -
  • - - Up to a month -
  • -
  • - - Large, Complex projects -
  • -
  • - - Higher priority -
  • -
-
- -
- -

Maintenance

-

$40-150 / mo

-
    -
  • - - Weekly bug checks & fixes -
  • -
  • - - Cybersecurity pen testing -
  • - -
  • - - Feature requests -
  • - -
  • - - Performance Optimization -
  • -
-
-
-

NOTE: if the project requires more than a month there will be a extra payments

-
-
-
- ); -} diff --git a/src/components/Background.css b/src/components/Background.css deleted file mode 100644 index 405e000..0000000 --- a/src/components/Background.css +++ /dev/null @@ -1,290 +0,0 @@ -@keyframes move { - 100% { - transform: translate3d(0, 0, 1px) rotate(360deg); - } -} - -.background { - position: absolute; - width: 100vw; - height: 100vh; - top: 0; - left: 0; - background: #000000; - overflow: hidden; - z-index: -1; -} - -.background span { - width: 24vmin; - height: 24vmin; - border-radius: 24vmin; - backface-visibility: hidden; - position: absolute; - animation: move; - animation-duration: 6; - animation-timing-function: linear; - animation-iteration-count: infinite; -} - -.background span:nth-child(0) { - color: #f5304c; - top: 24%; - left: 18%; - animation-duration: 220s; - animation-delay: -272s; - transform-origin: -5vw -4vh; - box-shadow: 48vmin 0 6.421535280295322vmin currentColor; -} -.background span:nth-child(1) { - color: #f5304c; - top: 86%; - left: 77%; - animation-duration: 91s; - animation-delay: -322s; - transform-origin: 14vw 0vh; - box-shadow: -48vmin 0 6.323515398437237vmin currentColor; -} -.background span:nth-child(2) { - color: #f5304c; - top: 17%; - left: 44%; - animation-duration: 248s; - animation-delay: -181s; - transform-origin: 0vw -7vh; - box-shadow: -48vmin 0 6.116084464270985vmin currentColor; -} -.background span:nth-child(3) { - color: #f5304c; - top: 43%; - left: 15%; - animation-duration: 98s; - animation-delay: -211s; - transform-origin: -21vw 8vh; - box-shadow: 48vmin 0 6.907246782805462vmin currentColor; -} -.background span:nth-child(4) { - color: #f5304c; - top: 66%; - left: 60%; - animation-duration: 241s; - animation-delay: -75s; - transform-origin: 15vw -9vh; - box-shadow: -48vmin 0 6.832728853871303vmin currentColor; -} -.background span:nth-child(5) { - color: #f5304c; - top: 79%; - left: 87%; - animation-duration: 207s; - animation-delay: -234s; - transform-origin: -19vw 4vh; - box-shadow: -48vmin 0 6.062609002101319vmin currentColor; -} -.background span:nth-child(6) { - color: #f5304c; - top: 45%; - left: 79%; - animation-duration: 243s; - animation-delay: -285s; - transform-origin: 11vw 25vh; - box-shadow: -48vmin 0 6.42616777258573vmin currentColor; -} -.background span:nth-child(7) { - color: #f5304c; - top: 43%; - left: 51%; - animation-duration: 227s; - animation-delay: -181s; - transform-origin: -23vw 1vh; - box-shadow: 48vmin 0 6.831515741167314vmin currentColor; -} -.background span:nth-child(8) { - color: #f5304c; - top: 21%; - left: 59%; - animation-duration: 228s; - animation-delay: -196s; - transform-origin: -23vw 23vh; - box-shadow: 48vmin 0 6.824335114512845vmin currentColor; -} -.background span:nth-child(9) { - color: #f5304c; - top: 95%; - left: 81%; - animation-duration: 202s; - animation-delay: -141s; - transform-origin: 17vw 24vh; - box-shadow: 48vmin 0 6.5732268320821685vmin currentColor; -} -.background span:nth-child(10) { - color: #f5304c; - top: 23%; - left: 90%; - animation-duration: 43s; - animation-delay: -406s; - transform-origin: -7vw -12vh; - box-shadow: 48vmin 0 6.1955583991481vmin currentColor; -} -.background span:nth-child(11) { - color: #f5304c; - top: 6%; - left: 94%; - animation-duration: 422s; - animation-delay: -38s; - transform-origin: -5vw 16vh; - box-shadow: 48vmin 0 6.212234588070589vmin currentColor; -} -.background span:nth-child(12) { - color: #f5304c; - top: 76%; - left: 22%; - animation-duration: 258s; - animation-delay: -58s; - transform-origin: -23vw -6vh; - box-shadow: 48vmin 0 6.165111619626152vmin currentColor; -} -.background span:nth-child(13) { - color: #f5304c; - top: 20%; - left: 80%; - animation-duration: 363s; - animation-delay: -411s; - transform-origin: 22vw 25vh; - box-shadow: -48vmin 0 6.179675889584371vmin currentColor; -} -.background span:nth-child(14) { - color: #f5304c; - top: 88%; - left: 36%; - animation-duration: 12s; - animation-delay: -69s; - transform-origin: -11vw -4vh; - box-shadow: -48vmin 0 6.07188338021629vmin currentColor; -} -.background span:nth-child(15) { - color: #f5304c; - top: 97%; - left: 11%; - animation-duration: 351s; - animation-delay: -130s; - transform-origin: -16vw -18vh; - box-shadow: 48vmin 0 6.558182158209241vmin currentColor; -} -.background span:nth-child(16) { - color: #f5304c; - top: 60%; - left: 99%; - animation-duration: 193s; - animation-delay: -67s; - transform-origin: 10vw 25vh; - box-shadow: 48vmin 0 6.570051729134467vmin currentColor; -} -.background span:nth-child(17) { - color: #f5304c; - top: 12%; - left: 8%; - animation-duration: 166s; - animation-delay: -69s; - transform-origin: 7vw -1vh; - box-shadow: -48vmin 0 6.742868690500271vmin currentColor; -} -.background span:nth-child(18) { - color: #f5304c; - top: 44%; - left: 38%; - animation-duration: 96s; - animation-delay: -279s; - transform-origin: 11vw 1vh; - box-shadow: -48vmin 0 6.261014277195781vmin currentColor; -} -.background span:nth-child(19) { - color: #f5304c; - top: 96%; - left: 77%; - animation-duration: 122s; - animation-delay: -355s; - transform-origin: 6vw 3vh; - box-shadow: -48vmin 0 6.438018625575824vmin currentColor; -} -.background span:nth-child(20) { - color: #f5304c; - top: 2%; - left: 81%; - animation-duration: 331s; - animation-delay: -355s; - transform-origin: 11vw -18vh; - box-shadow: -48vmin 0 6.555921470976377vmin currentColor; -} -.background span:nth-child(21) { - color: #f5304c; - top: 42%; - left: 9%; - animation-duration: 439s; - animation-delay: -233s; - transform-origin: -20vw -24vh; - box-shadow: -48vmin 0 6.570997236391078vmin currentColor; -} -.background span:nth-child(22) { - color: #f5304c; - top: 69%; - left: 23%; - animation-duration: 400s; - animation-delay: -390s; - transform-origin: -18vw -21vh; - box-shadow: 48vmin 0 6.279087258882428vmin currentColor; -} -.background span:nth-child(23) { - color: #f5304c; - top: 33%; - left: 95%; - animation-duration: 18s; - animation-delay: -98s; - transform-origin: 22vw 8vh; - box-shadow: -48vmin 0 6.088381708804739vmin currentColor; -} -.background span:nth-child(24) { - color: #f5304c; - top: 39%; - left: 69%; - animation-duration: 337s; - animation-delay: -83s; - transform-origin: 15vw -5vh; - box-shadow: -48vmin 0 6.515991392427649vmin currentColor; -} -.background span:nth-child(25) { - color: #f5304c; - top: 57%; - left: 17%; - animation-duration: 126s; - animation-delay: -93s; - transform-origin: -7vw 9vh; - box-shadow: 48vmin 0 6.431063119719202vmin currentColor; -} -.background span:nth-child(26) { - color: #f5304c; - top: 91%; - left: 76%; - animation-duration: 131s; - animation-delay: -256s; - transform-origin: -4vw 23vh; - box-shadow: 48vmin 0 6.370776053425152vmin currentColor; -} -.background span:nth-child(27) { - color: #f5304c; - top: 44%; - left: 65%; - animation-duration: 160s; - animation-delay: -235s; - transform-origin: -23vw 12vh; - box-shadow: 48vmin 0 6.34935032141241vmin currentColor; -} -.background span:nth-child(28) { - color: #f5304c; - top: 89%; - left: 36%; - animation-duration: 298s; - animation-delay: -400s; - transform-origin: -7vw 2vh; - box-shadow: -48vmin 0 6.935061205772426vmin currentColor; -} diff --git a/src/components/Background.tsx b/src/components/Background.tsx index d27006d..4e35ab7 100644 --- a/src/components/Background.tsx +++ b/src/components/Background.tsx @@ -1,39 +1,189 @@ -import "./Background.css"; +'use client'; + +import React, { useEffect, useRef, useState } from "react"; + +export default function Background({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + const canvasRef = useRef(null); + const animationRef = useRef(0); + const particlesRef = useRef([]); + const [dimensions, setDimensions] = useState<{ width: number; height: number }>({ + width: 0, + height: 0, + }); + + // Particle configuration + const config = { + particleCount: 80, + maxDistance: 120, + particleSpeed: 0.5, + particleSize: 2, + lineOpacity: 0.6, + particleOpacity: 0.8, + colors: { + particles: "#f5304c", // blue-400 + connections: "#f5304c", // blue-500 + }, + }; + + // Particle class + class Particle { + x: number; + y: number; + vx: number; + vy: number; + size: number; + + constructor(width: number, height: number) { + this.x = Math.random() * width; + this.y = Math.random() * height; + this.vx = (Math.random() - 0.5) * config.particleSpeed; + this.vy = (Math.random() - 0.5) * config.particleSpeed; + this.size = config.particleSize + Math.random() * 2; + } + + update(width: number, height: number) { + this.x += this.vx; + this.y += this.vy; + + // Bounce off edges + if (this.x < 0 || this.x > width) { + this.vx = -this.vx; + this.x = Math.max(0, Math.min(width, this.x)); + } + if (this.y < 0 || this.y > height) { + this.vy = -this.vy; + this.y = Math.max(0, Math.min(height, this.y)); + } + } + + draw(ctx: CanvasRenderingContext2D) { + ctx.beginPath(); + ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); + ctx.fillStyle = `${config.colors.particles}${Math.round( + config.particleOpacity * 255 + ) + .toString(16) + .padStart(2, "0")}`; + ctx.fill(); + } + } + + // Initialize particles + const initParticles = (width: number, height: number) => { + particlesRef.current = []; + for (let i = 0; i < config.particleCount; i++) { + particlesRef.current.push(new Particle(width, height)); + } + }; + + // Draw connections between nearby particles + const drawConnections = (ctx: CanvasRenderingContext2D, particles: Particle[]) => { + for (let i = 0; i < particles.length; i++) { + for (let j = i + 1; j < particles.length; j++) { + const dx = particles[i].x - particles[j].x; + const dy = particles[i].y - particles[j].y; + const distance = Math.sqrt(dx * dx + dy * dy); + + if (distance < config.maxDistance) { + const opacity = 1 - distance / config.maxDistance; + ctx.beginPath(); + ctx.moveTo(particles[i].x, particles[i].y); + ctx.lineTo(particles[j].x, particles[j].y); + ctx.strokeStyle = `${config.colors.connections}${Math.round( + opacity * config.lineOpacity * 255 + ) + .toString(16) + .padStart(2, "0")}`; + ctx.lineWidth = 1; + ctx.stroke(); + } + } + } + }; + + // Animation loop + const animate = () => { + const canvas = canvasRef.current; + if (!canvas) return; + + const ctx = canvas.getContext("2d"); + if (!ctx) return; + + const { width, height } = dimensions; + + // Clear canvas + ctx.clearRect(0, 0, width, height); + + // Update and draw particles + particlesRef.current.forEach((particle) => { + particle.update(width, height); + particle.draw(ctx); + }); + + // Draw connections + drawConnections(ctx, particlesRef.current); + + animationRef.current = requestAnimationFrame(animate); + }; + + // Handle window resize + const handleResize = () => { + const canvas = canvasRef.current; + if (!canvas || !canvas.parentElement) return; + + const rect = canvas.parentElement.getBoundingClientRect(); + const width = rect.width; + const height = rect.height; + + const dpr = window.devicePixelRatio || 1; + canvas.width = width * dpr; + canvas.height = height * dpr; + canvas.style.width = `${width}px`; + canvas.style.height = `${height}px`; + + const ctx = canvas.getContext("2d"); + if (ctx) { + ctx.setTransform(1, 0, 0, 1, 0, 0); // reset scaling before re-scaling + ctx.scale(dpr, dpr); + } + + setDimensions({ width, height }); + }; + + useEffect(() => { + handleResize(); + window.addEventListener("resize", handleResize); + + return () => { + window.removeEventListener("resize", handleResize); + if (animationRef.current) { + cancelAnimationFrame(animationRef.current); + } + }; + }, []); + + useEffect(() => { + if (dimensions.width && dimensions.height) { + initParticles(dimensions.width, dimensions.height); + animate(); + } + + return () => { + if (animationRef.current) { + cancelAnimationFrame(animationRef.current); + } + }; + }, [dimensions]); -const Background = () => { return ( -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
+ + + {children}
); }; - -export default Background; diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 856db97..d2e6226 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -28,15 +28,6 @@ export default function Navbar() { > Pricing - - Blog -
diff --git a/src/components/PinnedRepos.tsx b/src/components/PinnedRepos.tsx index 2cc44ce..229cea7 100644 --- a/src/components/PinnedRepos.tsx +++ b/src/components/PinnedRepos.tsx @@ -1,4 +1,6 @@ -import { stringify } from "querystring"; +'use client'; + +import { useEffect, useState } from "react"; type PinnedRepo = { author: string; @@ -33,8 +35,7 @@ export function Repo({ hover:shadow-md transition-shadow duration-300 - bg-transparent-ish - backdrop-blur-xl + backdrop-blur-[2px] `} >
@@ -103,7 +104,8 @@ export function Repo({ {forks}
-
{lang}
+ )} @@ -134,11 +137,21 @@ export function Repo({ ); } -export default async function PinnedRepos() { +export default function PinnedRepos() { try { - const pinned: PinnedRepo[] = await ( - await fetch("https://pinned.berrysauce.dev/get/kleo-dev") - ).json(); + const [pinned, setPinned] = useState([]); + + useEffect(() => { + fetch("https://pinned.berrysauce.dev/get/kleo-dev").then(r => { + r.json().then(p => { + setPinned(p); + }).catch(e => { + console.error(e) + }) + }).catch(e => { + console.error(e) + }) + }); return (
diff --git a/src/components/Skill.tsx b/src/components/Skill.tsx index 5aa9ff7..b9158b1 100644 --- a/src/components/Skill.tsx +++ b/src/components/Skill.tsx @@ -4,16 +4,27 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; export default function Skill({ skill, icon, - mt, + classInsert, }: { skill: string; icon: IconProp; - mt?: string; + classInsert?: string; }) { return ( -
- - {skill} +
+ + Skilled in {" "} {skill} + + +
); }