diff --git a/package-lock.json b/package-lock.json index 1eda30e..3c3e234 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@types/cookie-parser": "^1.4.3", "@types/crypto-js": "^4.1.1", "@types/react": "^18.2.14", + "argon2": "^0.31.1", "body-parser": "^1.20.2", "cookie": "^0.5.0", "cookie-parser": "^1.4.6", @@ -51,6 +52,53 @@ "node": ">=6.9.0" } }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@next/env": { "version": "13.4.7", "resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.7.tgz", @@ -226,6 +274,14 @@ "node": ">= 8" } }, + "node_modules/@phc/format": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@phc/format/-/format-1.0.0.tgz", + "integrity": "sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==", + "engines": { + "node": ">=10" + } + }, "node_modules/@swc/helpers": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.1.tgz", @@ -373,8 +429,7 @@ "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "node_modules/accepts": { "version": "1.3.8", @@ -388,11 +443,42 @@ "node": ">= 0.6" } }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agent-base/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -425,6 +511,37 @@ "node": ">= 8" } }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/argon2": { + "version": "0.31.1", + "resolved": "https://registry.npmjs.org/argon2/-/argon2-0.31.1.tgz", + "integrity": "sha512-ik2xnJrLXazya7m4Nz1XfBSRjXj8Koq8qF9PsQC8059p20ifWc9zx/hgU3ItZh/3TnwXkv0RbhvjodPkmFf0bg==", + "hasInstallScript": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.11", + "@phc/format": "^1.0.0", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -442,8 +559,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/binary-extensions": { "version": "2.2.0", @@ -494,7 +610,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -625,6 +740,14 @@ "fsevents": "~2.3.2" } }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -662,6 +785,14 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } + }, "node_modules/commander": { "version": "9.5.0", "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", @@ -674,8 +805,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/concurrently": { "version": "8.2.0", @@ -704,6 +834,11 @@ "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" } }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -819,6 +954,11 @@ "ms": "^2.1.1" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -836,6 +976,14 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "engines": { + "node": ">=8" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -867,8 +1015,7 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/encodeurl": { "version": "1.0.2", @@ -1074,6 +1221,33 @@ "node": ">= 0.6" } }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", @@ -1093,6 +1267,25 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -1116,6 +1309,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -1200,6 +1412,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -1215,6 +1432,39 @@ "node": ">= 0.8" } }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -1241,6 +1491,15 @@ "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", "dev": true }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -1284,7 +1543,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -1342,6 +1600,39 @@ "loose-envify": "cli.js" } }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -1425,7 +1716,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1441,6 +1731,48 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/mongodb": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.6.0.tgz", @@ -1575,6 +1907,49 @@ } } }, + "node_modules/node-addon-api": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.0.0.tgz", + "integrity": "sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/nodemon": { "version": "2.0.22", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", @@ -1648,6 +2023,25 @@ "node": ">=0.10.0" } }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.12.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", @@ -1667,6 +2061,14 @@ "node": ">= 0.8" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -1675,6 +2077,14 @@ "node": ">= 0.8" } }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -1854,6 +2264,19 @@ "react": "^18.2.0" } }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -1891,6 +2314,20 @@ "node": ">=0.10.0" } }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -2026,6 +2463,11 @@ "node": ">= 0.8.0" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -2053,6 +2495,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, "node_modules/simple-update-notifier": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", @@ -2144,11 +2591,18 @@ "node": ">=10.0.0" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -2162,7 +2616,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -2215,6 +2668,22 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/tar": { + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", + "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/tiny-case": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", @@ -2362,6 +2831,11 @@ "node": ">= 0.8" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -2410,6 +2884,14 @@ "node": ">=12" } }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -2427,6 +2909,11 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -2436,6 +2923,11 @@ "node": ">=10" } }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/package.json b/package.json index 8c5673c..c516b66 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "@types/cookie-parser": "^1.4.3", "@types/crypto-js": "^4.1.1", "@types/react": "^18.2.14", + "argon2": "^0.31.1", "body-parser": "^1.20.2", "cookie": "^0.5.0", "cookie-parser": "^1.4.6", diff --git a/public/assets/signs/Bronze/Taurritarius.svg b/public/assets/signs/Bronze/Taurittarius.svg similarity index 100% rename from public/assets/signs/Bronze/Taurritarius.svg rename to public/assets/signs/Bronze/Taurittarius.svg diff --git a/public/assets/signs/Bronze/Tarusci.svg b/public/assets/signs/Bronze/Taursci.svg similarity index 100% rename from public/assets/signs/Bronze/Tarusci.svg rename to public/assets/signs/Bronze/Taursci.svg diff --git a/public/assets/signs/Rust/Arritarius.svg b/public/assets/signs/Rust/Arittarius.svg similarity index 100% rename from public/assets/signs/Rust/Arritarius.svg rename to public/assets/signs/Rust/Arittarius.svg diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..2286d6e Binary files /dev/null and b/public/favicon.ico differ diff --git a/src/components/Box/Box.module.css b/src/components/Box/Box.module.css index 6109351..b191c03 100644 --- a/src/components/Box/Box.module.css +++ b/src/components/Box/Box.module.css @@ -9,6 +9,7 @@ padding: 8px; width: max-content; max-width: 100%; + overflow: hidden; } .Box.secondary { @@ -21,11 +22,11 @@ } .Box .innerContent { - padding: 4px 4px; - padding-top: 8px; + padding: 6px 4px; display: inline-flex; flex-direction: column; gap: 8px; + max-width: 100%; } .Box .innerContentNoTitle { diff --git a/src/components/CelesteBox/CelesteBox.module.css b/src/components/CelesteBox/CelesteBox.module.css index edf7868..5d3b9b8 100644 --- a/src/components/CelesteBox/CelesteBox.module.css +++ b/src/components/CelesteBox/CelesteBox.module.css @@ -47,15 +47,6 @@ transition: transform 0.25s cubic-bezier(0, 0.25, 0.5, 1); } -.CelesteBox .TextHolder { - visibility: hidden; -} - -.CelesteBox.open .TextHolder { - visibility: visible; - transition: visibility 0.25s step-end; -} - .PortraitHolder { width: 128px; height: 128px; @@ -74,3 +65,13 @@ line-height: 35px; user-select: none; } + +.CelesteBox .TextHolder { + visibility: hidden; + display: none; +} + +.CelesteBox.open .TextHolder { + visibility: visible; + display: flex; +} diff --git a/src/components/CelesteBox/TextHandler/TextHandler.tsx b/src/components/CelesteBox/TextHandler/TextHandler.tsx index 9c269f0..145ee0f 100644 --- a/src/components/CelesteBox/TextHandler/TextHandler.tsx +++ b/src/components/CelesteBox/TextHandler/TextHandler.tsx @@ -14,44 +14,16 @@ export default function TextHandler({ wantTextboxDoneStuff: [boolean, (wantTextboxDone: boolean) => void]; }) { const textSpan = useRef(null); - const [content, setContent] = useState(Runner(dialogIndex.dialog)); + const [content, setContent] = useState(Runner(dialogIndex.dialog, "start")); const animationFrame = useRef(0); - let clickSound: AudioBuffer; - let inSound: AudioBuffer; - let outSound: AudioBuffer; - let context: AudioContext; - let gain: GainNode; - let contextGot = false; - async function getContext() { - context = new AudioContext(); - gain = context.createGain(); - gain.gain.value = 0.2; - gain.connect(context.destination); - await fetch("assets/celeste/click.wav") - .then(response => response.arrayBuffer()) - .then(arrayBuffer => context.decodeAudioData(arrayBuffer)) - .then((audioBuffer: AudioBuffer) => (clickSound = audioBuffer)); - await fetch("assets/celeste/in.wav") - .then(response => response.arrayBuffer()) - .then(arrayBuffer => context.decodeAudioData(arrayBuffer)) - .then((audioBuffer: AudioBuffer) => (inSound = audioBuffer)); - await fetch("assets/celeste/out.wav") - .then(response => response.arrayBuffer()) - .then(arrayBuffer => context.decodeAudioData(arrayBuffer)) - .then((audioBuffer: AudioBuffer) => (outSound = audioBuffer)); - } useEffect(generateContent, [dialogIndex, dialogIsOpen]); function generateContent() { console.log("generating"); if (!dialogIsOpen) return; if (textSpan.current == null) return; cancelAnimationFrame(animationFrame.current); - setContent(Runner(dialogIndex.dialog)); + setContent(Runner(dialogIndex.dialog, "start")); } - (async () => { - await getContext(); - contextGot = true; - })(); useEffect(formatContent, [content]); function formatContent() { console.log("formatting", content); @@ -134,12 +106,6 @@ export default function TextHandler({ default: waitLength = 0.025; } - // if (makeSound && contextGot) { - // let source = context.createBufferSource(); - // source.buffer = clickSound; - // source.connect(gain); - // source.start(); - // } await wait(waitLength).then(() => { animationFrame.current = requestAnimationFrame(showLetters); }); @@ -158,12 +124,18 @@ export default function TextHandler({ ); } -function Runner(text: ElementArray) { - if (typeof text === "string") return StringRunner(text); - else if (Array.isArray(text)) return {text.map(Runner)}; +function Runner(text: ElementArray, index?: string) { + if (typeof text === "string") return StringRunner(text, index); + else if (Array.isArray(text)) + return ( + + {text.map((x, i) => Runner(x, (index ?? "") + "_" + i))} + + ); else if (typeof text === "object") { return ( - {Runner(text.text)} + {Runner(text.text, index)} ); } } -function StringRunner(string: string) { +function StringRunner(string: string, index?: string) { return ( <> {string.split("").map((letter, i) => ( {letter} diff --git a/src/components/Nav/Nav.module.css b/src/components/Nav/Nav.module.css index 7a65cf5..92b19e1 100644 --- a/src/components/Nav/Nav.module.css +++ b/src/components/Nav/Nav.module.css @@ -1,61 +1,73 @@ .Nav { - background-color: var(--pri-bg); - color: var(--pri-fg); + background-color: var(--pri-bg); + color: var(--pri-fg); - position: sticky; - top: 8px; - left: 8px; - z-index: 9; - display: flex; - flex-direction: row; - align-items: center; - justify-content: center; - text-align: center; - width: calc(100vw - 16px); - height: 48px; - border: 1px solid currentColor; - border-radius: 2px; - box-sizing: border-box; - padding: 8px 12px; + position: sticky; + top: 8px; + left: 8px; + z-index: 9; + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + text-align: center; + width: calc(100vw - 16px); + height: 48px; + border: 1px solid currentColor; + border-radius: 2px; + box-sizing: border-box; + padding: 8px 12px; } .Nav .left { - display: flex; - flex-direction: row; - align-items: center; - justify-content: flex-start; - text-align: center; - width: 100%; - gap: 16px; + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + text-align: center; + width: 100%; + gap: 16px; } .Nav .right { - display: flex; - flex-direction: row; - align-items: center; - justify-content: flex-end; - text-align: center; - width: 100%; - gap: 16px; + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-end; + text-align: center; + width: 100%; + gap: 16px; } .Nav .titlePath { - display: flex; - flex-direction: column; - align-items: flex-start; - justify-content: flex-start; - text-align: left; - gap: 4px; + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: flex-start; + text-align: left; + gap: 4px; } .Nav .path { - display: flex; - flex-direction: row; - align-items: center; - justify-content: flex-start; - text-align: left; - overflow: hidden; - text-overflow: ellipsis; - gap: 6px; - max-width: 100px; + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + text-align: left; + overflow: hidden; + text-overflow: ellipsis; + gap: 6px; + max-width: 100px; +} + +.shortTitle { + display: none; +} +@media (max-width: 784px) { + .shortTitle { + display: initial; + } + .longTitle { + display: none; + } } diff --git a/src/components/Nav/Nav.tsx b/src/components/Nav/Nav.tsx index a2db16b..8c46bce 100644 --- a/src/components/Nav/Nav.tsx +++ b/src/components/Nav/Nav.tsx @@ -1,45 +1,98 @@ import globals from "@/styles/global.module.css"; import { AnyObject } from "@/types/generics"; +import AuthContext from "@/utility/react/AuthContext"; import Link from "next/link"; +import { useContext, useEffect, useState } from "react"; import styles from "./Nav.module.css"; export default function Nav(elementProps: AnyObject) { - return ( -
-
-
- - - TrollCall - - + const userCredentials = useContext(AuthContext); + // Prevent hydration error. Nav Auth section is a client-rendered element. + const [isClient, setIsClient] = useState(false); + useEffect(() => setIsClient(true), []); + return ( +
+
+
+ + + TrollCall + + + + + TC + + +
+ + + add + + + + + HS + + + + + message + + +
+
+ {isClient && + userCredentials.TROLLCALL_NAME != null && + userCredentials.TROLLCALL_NAME != "" ? ( + <> + + + group + + + + + settings + + + + + logout + + + + ) : ( + <> + )} +
- - - add - - - - - HS - - - - - groups - - -
-
- - Part of{" "} - - The Admin Clan - - - settings - logout -
-
- ); + ); } diff --git a/src/components/ads/Mothvertising/Mothvertising.module.css b/src/components/ads/Mothvertising/Mothvertising.module.css new file mode 100644 index 0000000..ff4f3f2 --- /dev/null +++ b/src/components/ads/Mothvertising/Mothvertising.module.css @@ -0,0 +1,23 @@ +.Mothvertisement { + margin-left: auto; + display: block; + margin-right: auto; + max-width: 728px; + width: 100%; + height: 90px; + border: 1px solid var(--pri-fg); + border-radius: 2px; + opacity: 0.5; + transition: opacity 0.125s; +} +.Mothvertisement:hover { + opacity: 1; +} + +@media (max-width: 750px) { + .Mothvertisement { + max-width: 300px; + width: 100%; + height: 250px; + } +} diff --git a/src/components/ads/Mothvertising/Mothvertising.tsx b/src/components/ads/Mothvertising/Mothvertising.tsx new file mode 100644 index 0000000..a309cac --- /dev/null +++ b/src/components/ads/Mothvertising/Mothvertising.tsx @@ -0,0 +1,41 @@ +import globals from "@/styles/global.module.css"; +import Link from "next/link"; +import { useEffect, useState } from "react"; +import styles from "./Mothvertising.module.css"; + +export default function Mothvertising() { + const [hide, setHide] = useState(false); + useEffect(() => { + setHide(window.localStorage.getItem("hideAds") === "true"); + }, []); + return !hide ? ( +
+ +
+ + - + + Mothvertising + +
+
+ ) : ( + <> + ); +} diff --git a/src/components/ads/NavLink/NavLink.module.css b/src/components/ads/NavLink/NavLink.module.css new file mode 100644 index 0000000..d0c6c50 --- /dev/null +++ b/src/components/ads/NavLink/NavLink.module.css @@ -0,0 +1,12 @@ +.NavLink { + margin-left: auto; + display: block; + margin-right: auto; + border: 1px solid var(--pri-fg); + border-radius: 2px; + opacity: 0.5; + transition: opacity 0.125s; +} +.NavLink:hover { + opacity: 1; +} diff --git a/src/components/ads/NavLink/NavLink.tsx b/src/components/ads/NavLink/NavLink.tsx new file mode 100644 index 0000000..2171e90 --- /dev/null +++ b/src/components/ads/NavLink/NavLink.tsx @@ -0,0 +1,44 @@ +import globals from "@/styles/global.module.css"; +import Link from "next/link"; +import { useEffect, useState } from "react"; +import styles from "./NavLink.module.css"; + +export default function NavLink() { + const [hide, setHide] = useState(false); + useEffect(() => { + setHide(window.localStorage.getItem("hideAds") === "true"); + }, []); + return !hide ? ( +
+ +
+ + - + + NavLink Ads + +
+
+ ) : ( + <> + ); +} diff --git a/src/components/cards/ClanCard/ClanCard.module.css b/src/components/cards/ClanCard/ClanCard.module.css index 8815473..9bb0230 100644 --- a/src/components/cards/ClanCard/ClanCard.module.css +++ b/src/components/cards/ClanCard/ClanCard.module.css @@ -1,6 +1,7 @@ .ClanCard { - min-width: 600px; + /* min-width: 600px; */ width: 100%; + align-items: stretch; } .ClanCard.Skeleton { @@ -9,9 +10,10 @@ } .ClanCard .headerImage { + display: flex; margin: 0 -8px; margin-top: -8px; - width: auto; + width: calc(100% + 16px); height: 100px; background-color: var(--pri-fg); border: none; @@ -25,7 +27,8 @@ .ClanCard .horizontal { display: grid; - grid-template-columns: auto 1fr; + grid-template-columns: auto auto; + justify-content: center; gap: 16px; padding: 8px; box-sizing: border-box; @@ -55,4 +58,12 @@ display: flex; flex-direction: column; gap: 4px; + overflow: hidden; + width: 100%; +} + +.ClanCard .horizontal .horizontalRight > * { + width: 100%; + text-overflow: ellipsis; + overflow: hidden; } diff --git a/src/components/cards/ClanCard/ClanCard.tsx b/src/components/cards/ClanCard/ClanCard.tsx index def522e..14bf62c 100644 --- a/src/components/cards/ClanCard/ClanCard.tsx +++ b/src/components/cards/ClanCard/ClanCard.tsx @@ -4,11 +4,17 @@ import globals from "@/styles/global.module.css"; import { Color3 } from "@/types/assist/color"; import { ClientClan } from "@/types/clan"; import { PronounGrouper } from "@/utility/language"; -import Conditional from "@/utility/react/Conditional"; +import Conditional, { ConditionalParent } from "@/utility/react/Conditional"; import Link from "next/link"; import styles from "./ClanCard.module.css"; -export default function ClanCard({ clan }: { clan: ClientClan }) { +export default function ClanCard({ + clan, + link = true +}: { + clan: ClientClan; + link?: boolean; +}) { return ( - +
-

- + ( + + {children} + + )} > {clan.displayName ?? clan.name} - +

group diff --git a/src/components/cards/SignCard/SignCard.tsx b/src/components/cards/SignCard/SignCard.tsx index df97154..b6d5105 100644 --- a/src/components/cards/SignCard/SignCard.tsx +++ b/src/components/cards/SignCard/SignCard.tsx @@ -7,36 +7,42 @@ import Link from "next/link"; import styles from "./SignCard.module.css"; export default function SignCard({ sign }: { sign: TrueSignType }) { - return ( - -

- -
-
-

- - {sign.name} - -

-

- {sign.sway.name} - + - {sign.aspect.name} -

-
- - ); + return ( + +
+ +
+
+

+ + {sign.name} + +

+

+ {sign.sway.name} + + + {sign.aspect.name} +

+
+
+ ); } diff --git a/src/components/cards/TrollCard/TrollCard.module.css b/src/components/cards/TrollCard/TrollCard.module.css index d816f3f..2b00c41 100644 --- a/src/components/cards/TrollCard/TrollCard.module.css +++ b/src/components/cards/TrollCard/TrollCard.module.css @@ -1,5 +1,5 @@ .TrollCard { - min-width: 600px; + /* min-width: 600px; */ width: 100%; } @@ -11,6 +11,7 @@ .TrollCard .top { display: grid; grid-template-columns: max-content auto; + justify-content: center; gap: 8px; } diff --git a/src/components/cards/TrollCard/TrollCard.tsx b/src/components/cards/TrollCard/TrollCard.tsx index 1802f1f..46383d5 100644 --- a/src/components/cards/TrollCard/TrollCard.tsx +++ b/src/components/cards/TrollCard/TrollCard.tsx @@ -17,11 +17,10 @@ export default function TrollCard({ troll }: { troll: ClientTroll }) { const [randomLove, setRandomLove] = useState(""); const [randomHate, setRandomHate] = useState(""); const [randomQuote, setRandomQuote] = useState(""); - const trollColor = - troll.pageColor ?? - troll.textColor ?? + const trollColor = (troll.pageColor?.map(x => x / 255) ?? + troll.textColor?.map(x => x / 255) ?? troll.falseSign?.color.color ?? - troll.trueSign?.color.color; + troll.trueSign?.color.color) as [number, number, number] | undefined; useEffect(() => { if (troll.preferences.love != null && troll.preferences.love.length > 0) setRandomLove(pickRandom(troll.preferences.love)); @@ -34,7 +33,7 @@ export default function TrollCard({ troll }: { troll: ClientTroll }) {
@@ -48,7 +47,10 @@ export default function TrollCard({ troll }: { troll: ClientTroll }) {
-

+

{ const clan = - existingOwner ?? - (await getSingleClan({ - name: query?.clan - })); + existingOwner != null || query == null + ? existingOwner + : await getSingleClan({ + name: query.clan + }); if (clan == null) return null; const troll = - existingTroll ?? - (await getSingleTroll({ - "name.0": query?.troll, - "owner": clan._id - })); + existingTroll != null || query == null + ? existingTroll + : await getSingleTroll({ + "name.0": query.troll, + "owner": clan._id + }); if (troll == null) return null; const serverTroll = await ServerTrollToClientTroll(troll); serverTroll.flairs = cutArray( diff --git a/src/lib/trollcall/perms.ts b/src/lib/trollcall/perms.ts index a864d1b..6592b1e 100644 --- a/src/lib/trollcall/perms.ts +++ b/src/lib/trollcall/perms.ts @@ -1,7 +1,6 @@ import { Levels, Permissions } from "@/permissions"; import { ServerClan } from "@/types/clan"; -import CryptoJS from "crypto-js"; -import AES from "crypto-js/aes"; +import { verify } from "argon2"; import { ObjectId } from "mongodb"; export function getLevel(clan: Partial & { flairs: ObjectId[] }) { @@ -17,18 +16,15 @@ export function compareLevels(level: string, compareLevel: string) { return Levels[level] > Levels[compareLevel]; } -export function compareCredentials( +export async function compareCredentials( clan: ServerClan, cookies: Partial<{ [key: string]: string; }> ) { - const decryptCode = AES.decrypt( - clan.code, - process.env.ENCRYPT_CODE ?? "HACKTHIS" - ).toString(CryptoJS.enc.Utf8); + if (cookies.TROLLCALL_CODE == null) return null; return ( - decryptCode === cookies.TROLLCALL_CODE && + (await verify(clan.code, cookies.TROLLCALL_CODE)) && clan.name === cookies.TROLLCALL_NAME ); } diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 93336df..7c3f799 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,13 +1,17 @@ import Box from "@/components/Box/Box"; import Nav from "@/components/Nav/Nav"; +import Mothvertising from "@/components/ads/Mothvertising/Mothvertising"; +import NavLink from "@/components/ads/NavLink/NavLink"; import "@/styles/_app.css"; import "@/styles/global.module.css"; import globals from "@/styles/global.module.css"; import { Color3 } from "@/types/assist/color"; +import AuthContext from "@/utility/react/AuthContext"; import Themer, { ThemeModeContext } from "@/utility/react/Themer"; +import { getCookies } from "cookies-next"; import type { AppProps } from "next/app"; import Link from "next/link"; -import { useState } from "react"; +import { useEffect, useState } from "react"; export default function App({ Component, pageProps }: AppProps) { const [theme, setTheme] = useState([ @@ -15,6 +19,14 @@ export default function App({ Component, pageProps }: AppProps) { new Color3(0.7, 0.7, 0.6), false ] as [Color3, Color3, boolean?]); + const cookies = getCookies() as { + TROLLCALL_NAME: string; + TROLLCALL_CODE: string; + }; + const [adService, setAdService] = useState(false); + useEffect(() => { + setAdService(Math.random() > 0.5); + }, []); return (

-
); } diff --git a/src/pages/api/clan/[clan]/index.ts b/src/pages/api/clan/[clan]/index.ts index c1dce76..da05840 100644 --- a/src/pages/api/clan/[clan]/index.ts +++ b/src/pages/api/clan/[clan]/index.ts @@ -10,8 +10,8 @@ import { getLevel } from "@/lib/trollcall/perms"; import { PartialClanSchema, SubmitClan } from "@/types/client/clan"; +import { hash } from "argon2"; import { serialize } from "cookie"; -import AES from "crypto-js/aes"; import { nanoid } from "nanoid"; import { NextApiRequest, NextApiResponse } from "next"; @@ -21,9 +21,9 @@ export default async function handler( ) { const { body, cookies, query, method } = req; if (method === "GET") { - const clan = await ClanGET(query); + const clan = await ClanGET({ name: query.clan }); if (clan == null) return res.status(404).end(); - res.json(await ClanGET(query)); + res.json(clan); } else if (method === "PUT") { let validatedClan: Partial; try { @@ -38,11 +38,14 @@ export default async function handler( }); if (checkExistingClan == null) return res.status(404).end(); let isModerator = false; - if (!compareCredentials(checkExistingClan, cookies)) { + if (!(await compareCredentials(checkExistingClan, cookies))) { const thisClan = await getSingleClan({ name: cookies.TROLLCALL_NAME }); - if (thisClan == null || !compareCredentials(thisClan, cookies)) + if ( + thisClan == null || + !(await compareCredentials(thisClan, cookies)) + ) return res.status(403).end(); if (!compareLevels(getLevel(thisClan), "MODERATOR")) return res.status(403).end(); @@ -53,10 +56,7 @@ export default async function handler( serverClan.code = checkExistingClan.code || nanoid(16); // Encrypt code lole - serverClan.code = AES.encrypt( - serverClan.code, - process.env.ENCRYPT_CODE ?? "HACKTHIS" - ).toString(); + serverClan.code = await hash(serverClan.code); if (!compareLevels(getLevel(checkExistingClan), "SUPPORTER")) { serverClan.bgimage = null; diff --git a/src/pages/api/clan/index.ts b/src/pages/api/clan/index.ts index 6e49bb6..a60e4ab 100644 --- a/src/pages/api/clan/index.ts +++ b/src/pages/api/clan/index.ts @@ -3,8 +3,8 @@ import { SubmitClanToServerClan } from "@/lib/trollcall/convert/clan"; import { compareLevels, getLevel } from "@/lib/trollcall/perms"; import { ServerClan } from "@/types/clan"; import { SubmitClanSchema } from "@/types/client/clan"; +import { hash } from "argon2"; import { serialize } from "cookie"; -import AES from "crypto-js/aes"; import { nanoid } from "nanoid"; import { NextApiRequest, NextApiResponse } from "next"; @@ -34,10 +34,7 @@ export default async function handler( if (serverClan.code == null) serverClan.code = nanoid(16); // Encrypt code lole - serverClan.code = AES.encrypt( - serverClan.code, - process.env.ENCRYPT_CODE ?? "HACKTHIS" - ).toString(); + serverClan.code = hash(serverClan.code).toString(); if (!compareLevels(getLevel(serverClan), "SUPPORTER")) serverClan.bgimage = null; diff --git a/src/pages/api/troll/.../[[...page]]/index.ts b/src/pages/api/troll/.../[[...page]]/index.ts index 049d2a3..10a6390 100644 --- a/src/pages/api/troll/.../[[...page]]/index.ts +++ b/src/pages/api/troll/.../[[...page]]/index.ts @@ -18,6 +18,7 @@ export default async function handler( thisTroll.owner = (await ClanGET({ _id: troll.owner })) as ClientClan; + console.log(thisTroll.owner); return thisTroll; }, diff --git a/src/pages/api/troll/[clan]/.../[[...page]]/index.ts b/src/pages/api/troll/[clan]/.../[[...page]]/index.ts index 360f0a9..edac7c2 100644 --- a/src/pages/api/troll/[clan]/.../[[...page]]/index.ts +++ b/src/pages/api/troll/[clan]/.../[[...page]]/index.ts @@ -2,7 +2,6 @@ import { ClanGET } from "@/lib/trollcall/api/clan"; import { getSingleClan } from "@/lib/trollcall/clan"; import { ServerTrollToClientTroll } from "@/lib/trollcall/convert/troll"; import { getManyPagedTrolls } from "@/lib/trollcall/troll"; -import { ClientClan } from "@/types/clan"; import { NextApiRequest, NextApiResponse } from "next"; export default async function handler( @@ -16,15 +15,15 @@ export default async function handler( name: query.clan }); if (clan == null) return res.status(404).end(); + const clientClan = await ClanGET(null, clan); + if (clientClan == null) return res.status(404).end(); const trolls = await getManyPagedTrolls( { "owner": clan._id }, async (troll: any) => { const thisTroll = await ServerTrollToClientTroll(troll); - thisTroll.owner = (await ClanGET({ - _id: troll.owner - })) as ClientClan; + thisTroll.owner = clientClan; return thisTroll; }, diff --git a/src/pages/api/troll/[clan]/[troll]/index.ts b/src/pages/api/troll/[clan]/[troll]/index.ts index 1dd5239..e109402 100644 --- a/src/pages/api/troll/[clan]/[troll]/index.ts +++ b/src/pages/api/troll/[clan]/[troll]/index.ts @@ -35,11 +35,14 @@ export default async function handler( name: query.clan }); if (checkClan == null) return res.status(404).end(); - if (!compareCredentials(checkClan, cookies)) { + if (!(await compareCredentials(checkClan, cookies))) { const thisClan = await getSingleClan({ name: cookies.TROLLCALL_NAME }); - if (thisClan == null || !compareCredentials(thisClan, cookies)) + if ( + thisClan == null || + !(await compareCredentials(thisClan, cookies)) + ) return res.status(403).end(); console.log(getLevel(thisClan)); if (!compareLevels(getLevel(thisClan), "MODERATOR")) diff --git a/src/pages/api/troll/[clan]/[troll]/server/index.ts b/src/pages/api/troll/[clan]/[troll]/server/index.ts index faa2625..1c1ec93 100644 --- a/src/pages/api/troll/[clan]/[troll]/server/index.ts +++ b/src/pages/api/troll/[clan]/[troll]/server/index.ts @@ -17,11 +17,14 @@ export default async function handler( name: query.clan }); if (clan == null) return res.status(404).end(); - if (!compareCredentials(clan, cookies)) { + if (!(await compareCredentials(clan, cookies))) { const thisClan = await getSingleClan({ name: cookies.TROLLCALL_NAME }); - if (thisClan == null || !compareCredentials(thisClan, cookies)) + if ( + thisClan == null || + !(await compareCredentials(thisClan, cookies)) + ) return res.status(403).end(); if (!compareLevels(getLevel(thisClan), "MODERATOR")) return res.status(403).end(); diff --git a/src/pages/api/troll/index.ts b/src/pages/api/troll/index.ts index 88428e8..dd4b5d9 100644 --- a/src/pages/api/troll/index.ts +++ b/src/pages/api/troll/index.ts @@ -24,7 +24,7 @@ export default async function handler( name: cookies.TROLLCALL_NAME }); if (checkClan == null) return res.status(404).end(); - if (!compareCredentials(checkClan, cookies)) + if (!(await compareCredentials(checkClan, cookies))) return res.status(403).end(); const checkExistingTroll = await getSingleTroll({ "name.0": validatedTroll.name[0], diff --git a/src/pages/clan/[clan]/index.tsx b/src/pages/clan/[clan]/index.tsx new file mode 100644 index 0000000..53bad5f --- /dev/null +++ b/src/pages/clan/[clan]/index.tsx @@ -0,0 +1,93 @@ +import Box from "@/components/Box/Box"; +import ClanCard from "@/components/cards/ClanCard/ClanCard"; +import TrollCard from "@/components/cards/TrollCard/TrollCard"; +import TrollSkeleton from "@/components/cards/TrollCard/TrollSkeleton"; +import { ClanGET } from "@/lib/trollcall/api/clan"; +import { Color3 } from "@/types/assist/color"; +import { ClientClan } from "@/types/clan"; +import { ThemerGetSet } from "@/types/generics"; +import { ClientTroll } from "@/types/troll"; +import Conditional from "@/utility/react/Conditional"; +import { GetServerSideProps, GetStaticPropsContext } from "next"; +import { useEffect, useState } from "react"; + +export default function Index({ + themerVars: [theme, setTheme], + clan +}: { + themerVars: ThemerGetSet; + clan: ClientClan; +}) { + const [fetchedTrolls, setFetchedTrolls] = useState( + null + ); + useEffect(() => { + async function getTroll() { + const res = await fetch("/api/troll/" + clan.name + "/..."); + const json = await res.json(); + setFetchedTrolls(json); + } + getTroll(); + const color = clan.color?.map(x => x / 255) as [number, number, number]; + if (color != null) + setTheme([new Color3(...color), new Color3(...color).darken(50)]); + }, []); + return ( + <> + + + + + + {fetchedTrolls == null ? ( + <> + + + + + ) : ( + fetchedTrolls.map((troll: ClientTroll, idx) => ( + + )) + )} + + + ); +} + +export const getServerSideProps: GetServerSideProps<{ + clan: ClientClan; +}> = async (context: GetStaticPropsContext) => { + if (context.params?.clan == null) return { notFound: true }; + const clan = await ClanGET({ name: context.params.clan }); + if (clan == null) + return { + notFound: true + }; + return { + props: { + clan + } + }; +}; diff --git a/src/pages/help/opensource/index.tsx b/src/pages/help/credits/index.tsx similarity index 80% rename from src/pages/help/opensource/index.tsx rename to src/pages/help/credits/index.tsx index cf86200..6b1abcd 100644 --- a/src/pages/help/opensource/index.tsx +++ b/src/pages/help/credits/index.tsx @@ -2,13 +2,16 @@ import Box from "@/components/Box/Box"; import globals from "@/styles/global.module.css"; import "@/styles/index.module.css"; import { ThemerGetSet } from "@/types/generics"; +import { defaultTheme } from "@/utility/react/Themer"; import Link from "next/link"; +import { useEffect } from "react"; export default function Index({ themerVars: [theme, setTheme] }: { themerVars: ThemerGetSet; }) { + useEffect(() => setTheme(defaultTheme), []); return ( <> +
  • + + argon2 + +
  • + +

    + Extended Zodiac sign SVGs created by{" "} + + Ylimegirl on DeviantArt + + . +

    +

    + Aspect symbol SVGs created by{" "} + + Meggie's Effort + {" "} + (beware popups). +

    +
    +

    + Mothvertisements served by{" "} + + moth.monster + +

    +

    + NavLink Ads served by{" "} + + dimden.dev + +

    +

    + ~>{" "} + +

    +
    + +

    + Please{" "} + + let MeowcaTheoRange know + {" "} + if you have any questions about these credits! +

    +
    + +

    + A list of people who are on the TrollCall team. +

    +
    ); } diff --git a/src/pages/hiveswap/aspects/[name]/index.tsx b/src/pages/hiveswap/aspects/[name]/index.tsx new file mode 100644 index 0000000..16bb008 --- /dev/null +++ b/src/pages/hiveswap/aspects/[name]/index.tsx @@ -0,0 +1,116 @@ +import Box from "@/components/Box/Box"; +import SignCard from "@/components/cards/SignCard/SignCard"; +import globals from "@/styles/global.module.css"; +import "@/styles/index.module.css"; +import { Color3 } from "@/types/assist/color"; +import { + Aspect, + AspectKeys, + AspectType, + AspectValues, + TrueSignValues +} from "@/types/assist/extended_zodiac"; +import { ThemerGetSet } from "@/types/generics"; +import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from "next"; +import Link from "next/link"; +import { useEffect } from "react"; + +export default function Index({ + themerVars: [theme, setTheme], + aspect +}: { + themerVars: ThemerGetSet; + aspect: AspectType; +}) { + useEffect( + () => + setTheme([ + new Color3(...aspect.color), + new Color3(...aspect.color).darken(50) + ]), + [] + ); + return ( + <> + +

    + arrow_back + + hiveswap + + / + + aspects + + / + {aspect.name} +

    +
    + +

    + + {aspect.description} +

    +
    + +
    + {TrueSignValues.filter( + x => x.aspect.name == aspect.name + ).map((sign, tsidx) => ( + + ))} +
    +
    + + ); +} + +export const getStaticPaths: GetStaticPaths = () => { + return { + paths: AspectValues.map(aspect => ({ + params: { + name: aspect.name + } + })), + fallback: true + }; +}; + +export const getStaticProps: GetStaticProps<{ + aspect: AspectType; +}> = (context: GetStaticPropsContext) => { + if (context.params?.name == null) return { notFound: true }; + const aspect = context.params.name as string; + if (!AspectKeys.includes(aspect)) return { notFound: true }; + return { + props: { aspect: Aspect[aspect] } + }; +}; diff --git a/src/pages/hiveswap/aspects/index.tsx b/src/pages/hiveswap/aspects/index.tsx new file mode 100644 index 0000000..1b7c7fe --- /dev/null +++ b/src/pages/hiveswap/aspects/index.tsx @@ -0,0 +1,67 @@ +import Box from "@/components/Box/Box"; +import globals from "@/styles/global.module.css"; +import "@/styles/index.module.css"; +import { Color3 } from "@/types/assist/color"; +import { AspectValues } from "@/types/assist/extended_zodiac"; +import { ThemerGetSet } from "@/types/generics"; +import { hiveswapTheme } from "@/utility/react/Themer"; +import Link from "next/link"; +import { useEffect } from "react"; + +export default function Index({ + themerVars: [theme, setTheme] +}: { + themerVars: ThemerGetSet; +}) { + useEffect(() => setTheme(hiveswapTheme), []); + return ( + <> + +

    + arrow_back + + hiveswap + + / + aspects +

    +
    + +

    Insert text here.

    +
    + {AspectValues.map((aspect, idx) => ( + +

    + + + {aspect.description} + +

    +
    + ))} + + ); +} diff --git a/src/pages/hiveswap/colors/[name]/index.tsx b/src/pages/hiveswap/colors/[name]/index.tsx new file mode 100644 index 0000000..a0ae726 --- /dev/null +++ b/src/pages/hiveswap/colors/[name]/index.tsx @@ -0,0 +1,115 @@ +import Box from "@/components/Box/Box"; +import SignCard from "@/components/cards/SignCard/SignCard"; +import globals from "@/styles/global.module.css"; +import "@/styles/index.module.css"; +import { Color3 } from "@/types/assist/color"; +import { + SignColor, + SignColorKeys, + SignColorType, + SignColorValues, + TrueSignValues +} from "@/types/assist/extended_zodiac"; +import { ThemerGetSet } from "@/types/generics"; +import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from "next"; +import Link from "next/link"; +import { useEffect } from "react"; + +export default function Index({ + themerVars: [theme, setTheme], + color +}: { + themerVars: ThemerGetSet; + color: SignColorType; +}) { + useEffect( + () => + setTheme([ + new Color3(...color.color), + new Color3(...color.color).darken(50) + ]), + [] + ); + return ( + <> + +

    + arrow_back + + hiveswap + + / + + aspects + + / + {color.name} +

    +
    + +

    + + {color.description} +

    +
    + +
    + {TrueSignValues.filter(x => x.color.name == color.name).map( + (sign, tsidx) => ( + + ) + )} +
    +
    + + ); +} + +export const getStaticPaths: GetStaticPaths = () => { + return { + paths: SignColorValues.map(color => ({ + params: { + name: color.name + } + })), + fallback: true + }; +}; + +export const getStaticProps: GetStaticProps<{ + color: SignColorType; +}> = (context: GetStaticPropsContext) => { + if (context.params?.name == null) return { notFound: true }; + const color = context.params.name as string; + if (!SignColorKeys.includes(color)) return { notFound: true }; + return { + props: { color: SignColor[color] } + }; +}; diff --git a/src/pages/hiveswap/colors/index.tsx b/src/pages/hiveswap/colors/index.tsx new file mode 100644 index 0000000..43e3fa3 --- /dev/null +++ b/src/pages/hiveswap/colors/index.tsx @@ -0,0 +1,67 @@ +import Box from "@/components/Box/Box"; +import globals from "@/styles/global.module.css"; +import "@/styles/index.module.css"; +import { Color3 } from "@/types/assist/color"; +import { SignColorValues } from "@/types/assist/extended_zodiac"; +import { ThemerGetSet } from "@/types/generics"; +import { hiveswapTheme } from "@/utility/react/Themer"; +import Link from "next/link"; +import { useEffect } from "react"; + +export default function Index({ + themerVars: [theme, setTheme] +}: { + themerVars: ThemerGetSet; +}) { + useEffect(() => setTheme(hiveswapTheme), []); + return ( + <> + +

    + arrow_back + + hiveswap + + / + sway +

    +
    + +

    Insert text here.

    +
    + {SignColorValues.map((color, idx) => ( + +

    + + + {color.description} + +

    +
    + ))} + + ); +} diff --git a/src/pages/hiveswap/index.tsx b/src/pages/hiveswap/index.tsx new file mode 100644 index 0000000..23fa344 --- /dev/null +++ b/src/pages/hiveswap/index.tsx @@ -0,0 +1,95 @@ +import Box from "@/components/Box/Box"; +import globals from "@/styles/global.module.css"; +import "@/styles/index.module.css"; +import { ThemerGetSet } from "@/types/generics"; +import { hiveswapTheme } from "@/utility/react/Themer"; +import Link from "next/link"; +import { useEffect } from "react"; + +export default function Index({ + themerVars: [theme, setTheme] +}: { + themerVars: ThemerGetSet; +}) { + // Make universal theme + useEffect(() => setTheme(hiveswapTheme), []); + return ( + <> + +

    + arrow_back + hiveswap +

    +
    + +

    + Welcome to the Hiveswap portion of TrollCall. Here we pay + homage to the original{" "} + + Extended Zodiac + {" "} + website by providing its services, but this time, in a kind + of cool modern statically generated way. +

    +

    Also, original writing.

    +
    +

    Aspects

    +

    Insert text here.

    +
    + + Go to Aspects page + +
    +
    +
    +

    Sway

    +

    Insert text here.

    +
    + + Go to Sway page + +
    +
    +
    +

    Sign Colors

    +

    Insert text here.

    +
    + + Go to Sign Colors page + +
    +
    +
    +

    True Signs

    +

    Insert text here.

    +
    + + Go to True Signs page + +
    +
    +
    + + ); +} diff --git a/src/pages/hiveswap/sway/[name]/index.tsx b/src/pages/hiveswap/sway/[name]/index.tsx new file mode 100644 index 0000000..4d8429d --- /dev/null +++ b/src/pages/hiveswap/sway/[name]/index.tsx @@ -0,0 +1,126 @@ +import Box from "@/components/Box/Box"; +import SignCard from "@/components/cards/SignCard/SignCard"; +import globals from "@/styles/global.module.css"; +import "@/styles/index.module.css"; +import { Color3 } from "@/types/assist/color"; +import { + SignColorValues, + Sway, + SwayKeys, + SwayType, + SwayValues, + TrueSignValues +} from "@/types/assist/extended_zodiac"; +import { ThemerGetSet } from "@/types/generics"; +import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from "next"; +import Link from "next/link"; +import { useEffect } from "react"; + +export default function Index({ + themerVars: [theme, setTheme], + sway +}: { + themerVars: ThemerGetSet; + sway: SwayType; +}) { + useEffect( + () => + setTheme([ + new Color3(...sway.color), + new Color3(...sway.color).darken(50) + ]), + [] + ); + return ( + <> + +

    + arrow_back + + hiveswap + + / + + aspects + + / + {sway.name} +

    +
    + +

    + + {sway.description} +

    +
    + +
    + {SignColorValues.map((color, idx) => ( + <> +

    {color.name}

    +
    +
    + {TrueSignValues.filter( + x => + x.sway.name == sway.name && + x.color.name == color.name + ).map((sign, tsidx) => ( + + ))} +
    + + ))} +
    + + ); +} + +export const getStaticPaths: GetStaticPaths = () => { + return { + paths: SwayValues.map(sway => ({ + params: { + name: sway.name + } + })), + fallback: true + }; +}; + +export const getStaticProps: GetStaticProps<{ + sway: SwayType; +}> = (context: GetStaticPropsContext) => { + if (context.params?.name == null) return { notFound: true }; + const sway = context.params.name as string; + if (!SwayKeys.includes(sway)) return { notFound: true }; + return { + props: { sway: Sway[sway] } + }; +}; diff --git a/src/pages/hiveswap/sway/index.tsx b/src/pages/hiveswap/sway/index.tsx new file mode 100644 index 0000000..7b7bf61 --- /dev/null +++ b/src/pages/hiveswap/sway/index.tsx @@ -0,0 +1,65 @@ +import Box from "@/components/Box/Box"; +import globals from "@/styles/global.module.css"; +import "@/styles/index.module.css"; +import { Color3 } from "@/types/assist/color"; +import { SwayValues } from "@/types/assist/extended_zodiac"; +import { ThemerGetSet } from "@/types/generics"; +import { hiveswapTheme } from "@/utility/react/Themer"; +import Link from "next/link"; +import { useEffect } from "react"; + +export default function Index({ + themerVars: [theme, setTheme] +}: { + themerVars: ThemerGetSet; +}) { + useEffect(() => setTheme(hiveswapTheme), []); + return ( + <> + +

    + arrow_back + + hiveswap + + / + sway +

    +
    + +

    Insert text here.

    +
    + {SwayValues.map((sway, idx) => ( + +

    + + {sway.description} +

    +
    + ))} + + ); +} diff --git a/src/pages/hiveswap/truesigns/[name]/index.tsx b/src/pages/hiveswap/truesigns/[name]/index.tsx new file mode 100644 index 0000000..ae9555d --- /dev/null +++ b/src/pages/hiveswap/truesigns/[name]/index.tsx @@ -0,0 +1,163 @@ +import Box from "@/components/Box/Box"; +import globals from "@/styles/global.module.css"; +import "@/styles/index.module.css"; +import { Color3 } from "@/types/assist/color"; +import { + TrueSign, + TrueSignKeys, + TrueSignType, + TrueSignValues +} from "@/types/assist/extended_zodiac"; +import { ThemerGetSet } from "@/types/generics"; +import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from "next"; +import Link from "next/link"; +import { useEffect } from "react"; + +export default function Index({ + themerVars: [theme, setTheme], + trueSign +}: { + themerVars: ThemerGetSet; + trueSign: TrueSignType; +}) { + useEffect( + () => + setTheme([ + new Color3(...trueSign.color.color), + new Color3(...trueSign.color.color).darken(50) + ]), + [] + ); + return ( + <> + +

    + arrow_back + + hiveswap + + / + + truesigns + + / + {trueSign.name} +

    +
    + +

    + + + The True Sign of {trueSign.name} represents the{" "} + {trueSign.color.name}-blooded in the world, those who + are {trueSign.aspect.name}-bound and occupy the{" "} + {trueSign.sway.name} dream realm. + +

    +
    + +

    + + + {trueSign.color.description} + +

    +
    + +

    + + + {trueSign.aspect.description} + +

    +
    + +

    + + + {trueSign.sway.description} + +

    +
    + + ); +} + +export const getStaticPaths: GetStaticPaths = () => { + return { + paths: TrueSignValues.map(trueSign => ({ + params: { + name: trueSign.name + } + })), + fallback: true + }; +}; + +export const getStaticProps: GetStaticProps<{ + trueSign: TrueSignType; +}> = (context: GetStaticPropsContext) => { + if (context.params?.name == null) return { notFound: true }; + const trueSign = context.params.name as string; + if (!TrueSignKeys.includes(trueSign)) return { notFound: true }; + return { + props: { trueSign: TrueSign[trueSign] } + }; +}; diff --git a/src/pages/hiveswap/truesigns/index.tsx b/src/pages/hiveswap/truesigns/index.tsx new file mode 100644 index 0000000..e39a43d --- /dev/null +++ b/src/pages/hiveswap/truesigns/index.tsx @@ -0,0 +1,72 @@ +import Box from "@/components/Box/Box"; +import SignCard from "@/components/cards/SignCard/SignCard"; +import globals from "@/styles/global.module.css"; +import "@/styles/index.module.css"; +import { Color3 } from "@/types/assist/color"; +import { + SignColorValues, + TrueSignValues +} from "@/types/assist/extended_zodiac"; +import { ThemerGetSet } from "@/types/generics"; +import { hiveswapTheme } from "@/utility/react/Themer"; +import Link from "next/link"; +import { useEffect } from "react"; + +export default function Index({ + themerVars: [theme, setTheme] +}: { + themerVars: ThemerGetSet; +}) { + useEffect(() => setTheme(hiveswapTheme), []); + return ( + <> + +

    + arrow_back + + hiveswap + + / + truesigns +

    +
    + +

    Insert text here.

    +
    + {SignColorValues.map((color, idx) => ( + +

    + An assortment of {color.name}-blooded signs. +

    +
    + {TrueSignValues.filter( + x => x.color.name == color.name + ).map((sign, tsidx) => ( + + ))} +
    +
    + ))} + + ); +} diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 65d6e8a..ec32fef 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -5,10 +5,13 @@ import TrollCard from "@/components/cards/TrollCard/TrollCard"; import TrollSkeleton from "@/components/cards/TrollCard/TrollSkeleton"; import globals from "@/styles/global.module.css"; import "@/styles/index.module.css"; +import { Color3 } from "@/types/assist/color"; import { ClientClan } from "@/types/clan"; import { ThemerGetSet } from "@/types/generics"; import { ClientTroll } from "@/types/troll"; +import { defaultTheme } from "@/utility/react/Themer"; import { getCookies } from "cookies-next"; +import Link from "next/link"; import { useEffect, useState } from "react"; getCookies(); @@ -35,6 +38,7 @@ export default function Index({ setFetchedClans(json); } getClan(); + setTheme(defaultTheme); }, []); return ( <> @@ -47,6 +51,25 @@ export default function Index({ > Welcome to TrollCall! + + + Indulge yourself within the Extended Zodiac and its effects + on... everything, I guess. + + + Enter the Hiveswap section + + - {/* - This is a series of cards that represent the most important - aspects of TrollCall. - */} {fetchedTrolls == null ? ( <> @@ -67,7 +86,10 @@ export default function Index({ ) : ( fetchedTrolls.map((troll: ClientTroll, idx) => ( - + )) )} @@ -79,10 +101,6 @@ export default function Index({ } }} > - {/* - This is a series of cards that represent the most important - aspects of TrollCall. - */} {fetchedClans == null ? ( <> @@ -91,7 +109,10 @@ export default function Index({ ) : ( fetchedClans.map((clan: ClientClan, idx) => ( - + )) )} diff --git a/src/pages/test/index.tsx b/src/pages/test/index.tsx index a2c6de3..ba8ec1c 100644 --- a/src/pages/test/index.tsx +++ b/src/pages/test/index.tsx @@ -11,7 +11,9 @@ import "@/styles/index.module.css"; import { Color3 } from "@/types/assist/color"; import { ThemerGetSet } from "@/types/generics"; import { ClientTroll } from "@/types/troll"; +import { defaultTheme } from "@/utility/react/Themer"; import { getCookies } from "cookies-next"; +import Link from "next/link"; import { useEffect, useState } from "react"; getCookies(); @@ -29,6 +31,7 @@ export default function Index({ setFetchedTroll(json); } getTroll(); + setTheme(defaultTheme); }, []); const [openCB, CelesteBoxInstance] = CelesteBox({ @@ -60,6 +63,24 @@ export default function Index({ }, "I am very proud of myself for making this!" ] + }, + { + character: "madeline_lol", + dialog: [ + "AAAAAWAWAWAWAWAWWAJJKKOGJNKASNGllgnwklwa klw kflfwajniopfNOKPFOIWANIOPWNWONGOKWALGNW gkwognwipngwgnwiakopgl," + ] + }, + { + character: "madeline_lol", + dialog: [ + "The quick red girl jumped over the giant mountain." + ] + }, + { + character: "madeline_lol", + dialog: [ + "BABBABABABABABAB ab abal bla balb/@?>@?>!? !.rm1//.r1m /lm2/.2 2 2 2222/22//2/2//???@?@?2/2/2/2/2/2/2" + ] } ] } @@ -143,6 +164,65 @@ export default function Index({ } }} > +

    + Here you can select some themes to test what TrollCall looks + like with ridiculous colors. It's pretty fun to try! +

    +

    General themes

    +
    + + - + + - + + - + +
    +

    Coloured themes

    +

    Experimental themes

    + - + - + + - + + - + + - + +
    +

    + Spectacular Comment Chain-adjacent themes +

    +
    + + - + + - + + - + + - + + - + +
    +

    Vine funny themes

    +
    + +
    + +

    User utility

    -

    Blah blah blah

    -

    Blah blah blah

    -

    Blah blah blah

    -

    Blah blah blah

    -

    Blah blah blah

    -

    Blah blah blah

    +

    Test all of the UI in TrollCall.

    + +

    globals.title applied to p

    + + globals.title applied to span + +

    + globals.titleSmall applied to p +

    + + globals.titleSmall applied to span + +

    + globals.blockText applied to p +

    + + globals.blockText applied to span + +

    globals.small applied to p

    + + globals.small applied to span + +

    globals.mono applied to p

    + + globals.mono applied to span + +

    globals.icon applied to p

    +

    face

    +

    globals.icon applied to span

    + face +

    globals.iconSmall applied to p

    +

    face

    +

    + globals.iconSmall applied to span +

    + face +

    globals.iconlike applied to p

    +

    HS

    +

    globals.iconlike applied to span

    + HS + + globals.link applied to a + + + + globals.linkButton applied to a + +
    ); diff --git a/src/styles/_app.css b/src/styles/_app.css index c5062e2..7743ba4 100644 --- a/src/styles/_app.css +++ b/src/styles/_app.css @@ -1,44 +1,44 @@ body, div#__next, main.App { - margin: 0; - min-height: 100vh; - width: 100vw; - box-sizing: border-box; + margin: 0; + min-height: 100vh; + width: 100vw; + box-sizing: border-box; - /* Default text styling */ - font-size: 16px; - line-height: 20px; - font-family: "Space Grotesk"; + /* Default text styling */ + font-size: 16px; + line-height: 20px; + font-family: "Space Grotesk"; } main.App { - display: flex; - flex-direction: column; - align-items: center; - justify-content: flex-start; - padding: 8px; - background-color: var(--sec-bg); - color: var(--sec-fg); - background-image: url("/assets/pattern/pattern.png"); - background-blend-mode: hard-light; + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-start; + padding: 8px; + background-color: var(--sec-bg); + color: var(--sec-fg); + background-image: url("/assets/pattern/pattern.png"); + background-blend-mode: hard-light; } main.App.inverted { - background-image: url("/assets/pattern/pattern_inv.png"); + background-image: url("/assets/pattern/pattern_inv.png"); } main.App div.mainContent { - display: flex; - box-sizing: border-box; - flex-direction: column; - align-items: center; - justify-content: flex-start; - padding: 8px 0; - gap: 8px; - width: 100%; - max-width: 768px; - /* height: 100vh; */ + display: flex; + box-sizing: border-box; + flex-direction: column; + align-items: center; + justify-content: flex-start; + padding-top: 8px; + gap: 8px; + width: 100%; + max-width: 768px; + /* height: 100vh; */ } /* Change behaviour of some elements */ @@ -46,12 +46,12 @@ main.App div.mainContent { p, ul, ol { - margin: 0; - padding: 0; - display: block; + margin: 0; + padding: 0; + display: block; } ul, ol { - list-style-position: inside; + list-style-position: inside; } diff --git a/src/styles/global.module.css b/src/styles/global.module.css index f34e84e..0a0708e 100644 --- a/src/styles/global.module.css +++ b/src/styles/global.module.css @@ -1,67 +1,5 @@ @import url(./fonts.css); -.title { - font-size: 16px; - line-height: 20px; - font-family: "TrollCall Display"; - text-transform: uppercase; -} - -.titleSmall { - font-size: 14px; - line-height: 18px; - font-family: "TrollCall Display"; - text-transform: uppercase; -} - -.text { - font-size: 16px; - line-height: 20px; - font-family: "Space Grotesk"; -} - -.blockText { - display: block; - font-size: 16px; - line-height: 20px; - font-family: "Space Grotesk"; -} - -.small { - font-size: 12px; - line-height: 14px; - font-family: "Space Grotesk"; -} - -.mono { - font-size: 16px; - line-height: 20px; - font-family: "Space Mono"; -} - -.icon { - font-size: 24px; - line-height: 24px; - font-family: "Material Symbols Outlined"; - font-variation-settings: "FILL" 1, "opsz" 24, "GRAD" 0, "wght" 400; - user-select: none; -} - -.iconSmall { - font-size: 16px; - line-height: 16px; - font-family: "Material Symbols Outlined"; - font-variation-settings: "FILL" 1, "opsz" 24, "GRAD" 0, "wght" 400; - user-select: none; -} - -.iconlike { - font-size: 20px; - line-height: 20px; - font-family: "Space Mono"; - user-select: none; -} - .link { text-decoration: none; color: inherit; @@ -75,6 +13,29 @@ text-shadow: 0 0 8px currentColor; } +.linkButton { + text-decoration: none; + color: inherit; + box-shadow: 0 0 2px currentColor; + background-color: transparent; + border: 1px solid currentColor; + + padding: 4px 8px; + border-radius: 2px; + font-size: 16px; + line-height: 20px; + font-family: "Space Grotesk"; + cursor: pointer; + text-align: center; + + transition: box-shadow 0.125s; +} + +.linkButton:hover { + text-decoration: none; + box-shadow: 0 0 8px currentColor; +} + .button { color: inherit; box-shadow: 0 0 2px currentColor; @@ -118,6 +79,82 @@ text-shadow: 0 0 8px currentColor; } +.title { + font-size: 16px; + line-height: 20px; + font-family: "TrollCall Display"; + text-transform: uppercase; +} + +.titleSmall { + font-size: 14px; + line-height: 18px; + font-family: "TrollCall Display"; + text-transform: uppercase; +} + +.text { + font-size: 16px; + line-height: 20px; + font-family: "Space Grotesk"; +} + +.blockText { + display: block; + font-size: 16px; + line-height: 20px; + font-family: "Space Grotesk"; +} + +.small { + font-size: 12px; + line-height: 14px; + font-family: "Space Grotesk"; +} + +.mono { + font-size: 16px; + line-height: 20px; + font-family: "Space Mono"; +} + +.icon { + display: inline-block; + font-size: 24px; + line-height: 24px; + height: 24px; + font-family: "Material Symbols Outlined"; + font-variation-settings: "FILL" 1, "opsz" 24, "GRAD" 0, "wght" 400; + user-select: none; +} + +.iconSmall { + display: inline-block; + font-size: 16px; + line-height: 16px; + height: 16px; + font-family: "Material Symbols Outlined"; + font-variation-settings: "FILL" 1, "opsz" 24, "GRAD" 0, "wght" 400; + user-select: none; +} + +.iconlike { + display: inline-block; + font-size: 20px; + line-height: 24px; + height: 24px; + padding-bottom: 2px; + vertical-align: middle; + font-family: "Space Mono"; + user-select: none; +} + +.boxLike { + display: inline-flex; + flex-direction: column; + gap: 8px; +} + .buttonRow, .horizontalList { display: flex; @@ -141,3 +178,76 @@ justify-content: flex-start; gap: 8px; } + +.iconTextTop { + display: flex; + flex-direction: row; + align-items: flex-start; + justify-content: flex-start; + gap: 8px; +} + +.buttonLeft { + display: grid; + grid-template-columns: max-content 1fr; + justify-content: flex-start; + align-items: center; + gap: 16px; + padding-right: 8px; +} + +.buttonRight { + display: grid; + grid-template-columns: 1fr max-content; + justify-content: flex-end; + align-items: center; + gap: 16px; + padding-left: 8px; +} + +.sep { + width: 100%; + background-color: currentColor; + color: currentColor; + padding: 0; + margin: 8px 0; + border: none; + height: 1px; +} + +.sepHeader { + width: 100%; + background-color: currentColor; + color: currentColor; + padding: 0; + margin: 0; + border: none; + height: 1px; +} + +.invisep { + width: 100%; + background-color: transparent; + color: transparent; + padding: 0; + margin: 2px 0; + border: none; + height: 1px; +} + +.invisepHeader { + width: 100%; + background-color: transparent; + color: transparent; + padding: 0; + margin: 0; + border: none; + height: 1px; +} + +.signage { + filter: drop-shadow(1px 1px 0 currentcolor) + drop-shadow(-1px -1px 0 currentcolor) + drop-shadow(1px -1px 0 currentcolor) + drop-shadow(-1px 1px 0 currentcolor); +} diff --git a/src/types/assist/extended_zodiac.ts b/src/types/assist/extended_zodiac.ts index b78b69e..c9b4075 100644 --- a/src/types/assist/extended_zodiac.ts +++ b/src/types/assist/extended_zodiac.ts @@ -217,18 +217,19 @@ export const SwaySchema = yup.object({ export type SwayType = { name: string; description: string; + color: ColorTypes; }; export const Sway: { [key: string]: SwayType } = { Prospit: { name: "Prospit", - description: - "Marked by a flexible optimism, the personalities of Prospit Dreamers are reactive and intuitive. They naturally exist in the present, rather than look to the future or obsess over the past. When making decisions Prospit Dreamers tend to rely on gut instinct and whatever emotions they are experiencing at the moment. This makes them quick to act and reliable in a crisis, but it also can make them capricious. They have trouble thinking things through, and their feelings toward specific situations and decisions can change from day to day. They solve problems with creativity rather than cold logic, often seeing multiple options with ease and clarity. Because they generally take things as they come, Prospit Dreamers are less rebellious than they are adaptable-instead of struggling against authority, they will find a way to coexist with it. Possibly because they are so instinctual and flexible, they like having a defined set of rules-a safety net for their passionate lives. Naturally trusting, they have trouble with deception or hiding their true selves, and will often worry about what others think of them. The self they project into the world is often not under their control." + description: "", + color: [1, 1, 0] }, Derse: { name: "Derse", - description: - "Derse Dreamers have personalities marked by a distinct and restless skepticism. Whatever their waking circumstances, chances are they will live in a state of dissatisfaction. Rebellion is in their blood, manifesting whether they are fighting back against a fascist dictatorship, or the most recent trend in casual footwear. Derse Dreamers are cerebral and self-aware; they have a far better grasp on the landscape of their own minds than on the world around them, which they can find alienating and confusing. But as so much of their identity is built on control, they will do their utmost to hide any insecurities, often with false humility or self-deprecating humor. They may be inflexible and pessimistic, but they are also great problem solvers, facing conflicts head-on with shrewd, calculating minds. They see one true path among an infinite snarl of wrong ones. They tend to be introverted, but if you win their trust Derse Dreamers are extremely powerful allies. However, they find sincere vulnerability difficult and will often keep people at arm's length. Letting go and living in the moment is hard for a Derse Dreamer; they constantly look toward the future and analyze the past." + description: "", + color: [1, 0, 1] } }; @@ -243,68 +244,69 @@ export const AspectSchema = yup.object({ export type AspectType = { name: string; description: string; + color: ColorTypes; }; export const Aspect: { [key: string]: AspectType } = { Time: { name: "Time", - description: - "Those bound to the aspect of Time are fighters, full stop. Their lives are often marked by struggle, not so much because fate has it in for them, but because they are fundamentally incapable of just accepting things as they come. They value action over passive acceptance, even if that may not be the wisest or safest choice. Don't try to tell a Time-bound to sit still and look pretty. They are very goal-focused, and tend to value the destination over the journey, and you won't find them making that journey in any traditional sort of way. To quote cheesy posters found on many a guidance counselor's wall-\"impossible is just a word\". If you need a miracle, they are who you call. At their best, the Time-bound are empathetic and relentless problem-solvers. At their worst they are ruthless, defensive, and impulsive. " + description: "", + color: [1, 0.125, 0] }, Space: { name: "Space", - description: - "Those bound to the aspect of Space are, as the name suggests, concerned with the big picture. They are patient, masters of the art of 'wait-and-see', and are inclined to take things as they come. That isn't to say that they're pushovers or willing to let injustice lie-they just choose their battles wisely, understanding that sometimes you have to let something burn to the ground in order to build it back better and stronger than before. To this effect, they tend to be innovators, concerned with creation and redemption. Catch them recycling the old to make the new, the fresh, and the beautiful. For the Space-bound, the journey is as, if not more, important than the destination; how they do something is as important as what they do. At their best, they are steady, impartial, and creative. At their worst, they can be detached, apathetic, and vague. " + description: "", + color: [0, 0, 0] }, Heart: { name: "Heart", - description: - "Those bound to the aspect of Heart are very concerned with their favorite subject: themselves. It wouldn't be a stretch to call them 'self-obsessed', but not necessarily in a negative way. They simply want to understand the one thing we all are stuck with for our entire lives, i.e. our own minds. Forging an identity is extremely important to the Heart-bound, and every decision and action goes toward building a coherent narrative of their own story. That isn't to say Heart-bound don't care deeply for their friends and allies; they just have a tendency to assume that everyone is as concerned with identity as they are. They are excellent at putting on and taking off masks as the situation calls for them. At their best, they are competent, imaginative, and steady. At their worst they can be overbearing, inflexible, and cold. " + description: "", + color: [0.75, 0, 0.25] }, Mind: { name: "Mind", - description: - "Those bound to the aspect of Mind are-you guessed it-the universe's great thinkers. But don't for a second think that means that they have all the answers. They are very concerned with remaining rational, and they have such a firm hold on the constant conjunction of their thinking that it's easy for them to see the multitudes of the choices laid out before them, which often leaves them frozen and unable to act. That said, when a Mind-bound finally launches into action, they can execute a plan with unbelievable grace and precision. Their identity is fluid-it can change from day-to-day, from thought-to-thought, from interaction-to-interaction. Remaining logical is more important to them than building up a solid foundation of \"self.\" At their best they are great innovators, architects, and creators. At their worst they can be nasty, inflexible, and indecisive. " + description: "", + color: [0, 1, 0.75] }, Hope: { name: "Hope", - description: - "Those bound to the aspect of Hope are driven first and foremost by their convictions. They do right for right's sake, and are quick to come to the aid of anyone they deem to be experiencing injustice. That said, their views of the world can be quite black and white, so what they see as the \"right\" thing may not always be the universally accepted view. They put great value in the power of the imagination, the ability to dream up a better and more beautiful future. If anyone could dream a better world into existence, it would be one of the Hope-bound. They may sound like all sunshine and rainbows, but they aren't adverse to a little destruction, especially if they think they can replace it with something better and more just. At their best, Hope-bound are positive, caring, and warm. At their worst they can be narrow-minded and selfish. " + description: "", + color: [1, 0.75, 0.25] }, Rage: { name: "Rage", - description: - "Those bound to the aspect of Rage are bringers of chaos. They posses great contempt for lies or false ideas, including the stability that false ideas can impart. To them, the true is far more important than the good; they would tear down a system just to destabilize it if, by their reckoning, it is built on faulty premises. Often the Rage-bound prefer anarchy to any of the alternate forms of civilization, which they believe to be riddled with lies and foolishness and obedient masses. They are bringers of confusion and doubt, and they can be frustratingly difficult to convince otherwise when they have attached themselves to an idea. If they sound dangerous, they are. The Rage-bound tend to be most volatile and unpredictable of the aspects. At their best they are original, revolutionary, and fearless. At their worst they are cruel, uncompromising, and vicious. " + description: "", + color: [0.5, 0.25, 0.75] }, Light: { name: "Light", - description: - "Those bound to the aspect of Light are the universe's knowledge-seekers. They are, above all, driven to learn and understand. They are great alchemists, able to take multiple sources of information and synthesize them into something useful. They are scholars and researchers, absolutely dedicated to knowledge for knowledge's sake. They are the ultimate students, and although that might conjure up the image of people sitting around peacefully waiting for knowledge to be brought to them, that couldn't be further from the truth. The Light-bound will go after knowledge with a fierce intensity that others may find distasteful. They aren't overly concerned with laws or norms, either. They often take rules as simple suggestions, instead searching for loopholes or work-arounds. At their best, the Light-bound are resourceful and driven. At their worst they can be fussy, pedantic, and insensitive." + description: "", + color: [1, 1, 0.25] }, Void: { name: "Void", - description: - "Those bound to the aspect of Void are the universe's secret-keepers. The unknown doesn't scare them-where others might see emptiness, they see potential. A blank page, an empty canvas, that's what the Void-bound live for. They value mystery and the unexplained, and are not particularly bothered by not having all the answers. Where others might be compelled to go out and seek answers, the Void-bound lean more toward casting doubt on what is already considered fully understood. They don't take much on faith and would rather live in a state of confusion than believe something that might be untrue or bow to intellectual authority. After all, in order for something new to be built, the old, rotting foundation must often be razed. At their best, Void-bound are wise, intuitive, and vibrant. At their worst they can be dismissive, indecisive, and apathetic. " + description: "", + color: [0, 0.125, 0.25] }, Breath: { name: "Breath", - description: - "Those bound to the aspect of Breath are, above all, expansive. Flexible and driven, they leave an impact wherever they go. Like the breeze itself, they are able to sweep others up to carry along in their wake, but also like the breeze, they can be difficult to catch hold of or tie down. Although Breath-bound do make very good leaders, breath tends to be a very personal aspect. Often, heroism comes along as an offshoot of them pursuing their own personal stories. They lead by example, and will routinely be surprised that others look up to or feel inspired by them. They have a tendency to underestimate themselves, and not always out of poor self-esteem. They were just doing their own thing. At their best Breath-bound are motivated, adaptable, and forward thinking, but at their worst they can be volatile, avoidant, and gullible." + description: "", + color: [0.25, 0.75, 1] }, Blood: { name: "Blood", - description: - 'Those bound to the aspect of Blood draw their strength from bonds, from the trust and camaraderie that blooms among a group of people who all share a single vision. Blood-bound are absolutely leaders, but they inhabit more of an inspirational role than a commanding one. They are prophets, rather than generals, giving others the strength and motivation to keep fighting. The Blood-bound can dispense excellent advice even when their own lives and interpersonal relationships are disasters. They can be very "do as I say, not as I do" types. A Blood-bound can often be found on a sinking ship, forcing an endeavor forward with sheer stubborn force of will. No matter how bad things go, a Blood-bound can always count on friends and allies. At their best, they are charismatic, uplifting, and magnetic. At their worst they can be sullen, unkind, and set-in-their-ways. ' + description: "", + color: [0.75, 0.125, 0.125] }, Life: { name: "Life", - description: - "Those bound to the aspect of Life are the universe's healers. They are concerned with the betterment of themselves and those around them, as well as the onward march of positive progress. Deeply empathetic, they have an intuitive understanding of other's suffering and the best way of righting those wrongs. If you're poisoned, chances are the Life-bound have something for what ails ya. This applies to both physical and mental suffering, though it might not be a cure you'll like. They also have the tendency to put other's needs before their own, which never ends well for anyone, because the Life-bound can grow bitter if they feel their own self-care has had to be shunted aside. At their best, they are great listeners, caretakers, and nurturers. At their worst, the Life-bound are passive aggressive, and pushy-they're certain they know best. " + description: "", + color: [0.5, 0.75, 0.25] }, Doom: { name: "Doom", - description: - "Those bound to the aspect of Doom are fate's chosen sufferers. It may not sound like an overly pleasant aspect to be aligned with, but it does come along with great wisdom and empathy. The Doom-bound understand that misery loves company, and they are ready and willing to provide said company. The Doom-bound won't fix you; they aren't healers. They are commiserators, aware that sometimes the only thing you can do for a person is let them know that they are not alone in their suffering. They are not the advice friend-they're the friend you go to when you need to vent about a rough day at work. They are not necessarily noble martyrs, either-the Doom-bound can become quite irate about their lot. At their best they are wise, kind, and non-judgemental. At their worst, bitter, resentful, and fatalistic." + description: "", + color: [0.5, 0.66, 0] } }; @@ -334,98 +336,86 @@ export const SignColor: { } = { Rust: { name: "Rust", - description: - "Adventure motivates Rust Signs more than anything else. They crave new experiences, the wilder and farther-from-home, the better. They are confident and energetic, ready to face the unknown. This dynamism makes them great leaders, but it can also make them foolhardy. Often, they don't posses the level of caution they should for someone so willing to jump into new things. Their willingness to trust can get them into trouble, but they are also incredibly resilient. Their ability to bounce back from trauma and injury leaves them as the toughest sign class on the spectrum. Rust Signs make great friends and traveling companions, but they also can be selfish and quick to anger. If what they deem to be an acceptable level of \"excitement\" isn't happening around them, they have a tendency to try to stir some up. They love the drama. They have incredibly high expectations for themselves and for romantic partners. If someone doesn't live up to these, they may deem them not worth their time. If they aren't careful, Rust Signs can end up in a cycle of excitement, followed by crushed expectations, followed by a quick recovery and new flush of excitement. ", + description: "", sign: "Aries", - color: [255, 0, 0], + color: [1, 0, 0], dates: ["March 21", "April 19"] }, Bronze: { name: "Bronze", - description: - "Bronze Signs have a warm and generous disposition, but you might not accuse them of it the first time you meet. They have a tendency toward being withdrawn and slow to open up with new people. This can make them come off as arrogant and cold, like they think they are too good for everyone, although the reality couldn't be further from the truth. In fact, they crave validation and companionship. They are very open-hearted, but if a Bronze Sign decides to dig their heels in, it can be like talking to a wall. More so than any of the other sign classes, Bronze Signs have a marked love of creature comforts. They crave stability and safety, and if they have the means, their homes will be full of beautiful things. Some might accuse them of being hedonistic; they would probably just claim to know what they like. As lovers they can be quite needy, wanting assurances that the affection they feel is reciprocated. Maybe because of this, they have a particular affinity for animals. Don't try to break a Bronze's Sign's routines-they'll resent you for it, even if oftentimes they are too polite to say so.", + description: "", sign: "Taurus", - color: [255, 128, 0], + color: [1, 0.5, 0], dates: ["April 20", "May 20"] }, Gold: { name: "Gold", - description: - "Gold Signs are the reigning geniuses of the sign class spectrum, and chances are they know it. Witty and widely read, they enjoy conversation and debate, even when that conversation gets a little one-sided. They can come off as preachy, and they have a tendency to railroad, just driving into their interlocutors with the force of their intellect. Their arguments make perfect sense to themselves, but not always to those around them. Gold Signs are interested in a wide variety of topics, so they tend to be Jacks-of-all-trade, and can have trouble dedicating themselves to just a single hobby or career. They have a tendency to be high-energy, and can stress people out, including themselves. Their anxiety is such that they often need quite a bit of time alone with their projects. They can talk circles around most people, and they aren't afraid to use their intelligence to manipulate others to get what they want. They are good at making money, and also good at spending it. They aren't great financial planners, tending toward impulse purchases. In romance they lean toward partners who can keep up with them, both with their intellect and their energy, which can both be hard to match. ", + description: "", sign: "Gemini", - color: [255, 255, 0], + color: [1, 1, 0], dates: ["May 21", "June 21"] }, Lime: { name: "Lime", - description: - "Lime Signs are tumultuous, bringing great emotion and creativity to their endeavors. They are resolute in their decisions; if they are going to do something, they do it. They have a tendency toward melodrama, especially when they feel passionately about something, and their bad moods are loud and usually difficult to conceal. Hiding their feelings does not come naturally to them, so many Lime Signs cultivate a hard outer shell to hide the passionate, caring person inside. Lime Signs tend to have a large group of friends-they draw people to them with allure and the promise of excitement, and are usually unaware that they are doing it. They tend to focus on their own flaws, rather than their good points. Although they are exceedingly kind and empathetic individuals, many Lime Signs posses a mean streak. If you catch them on a bad day, they can be incredibly vicious. But it they take care to use their power for good, they make very loyal companions. Romance is extremely important to Lime Signs, and when they fall, they fall hard. They don't take rejection well, and a breakup can send them into a tailspin requiring an extended period of recovery.", + description: "", sign: "Cancer", - color: [127, 255, 0], + color: [0.5, 1, 0], dates: ["June 22", "July 22"] }, Olive: { name: "Olive", - description: - "Olive Signs are, by and large, incredibly agreeable people. They are generous and enthusiastic, ready to offer help to anyone who needs it. Luck plays a large role in their lives; Olive Signs have a knack for being in the right place at the right time. And even in the case that their luck goes bad, they can ride rough patches out without falling too far into depression or hopelessness. That said, Olive Signs are most comfortable with things that they are familiar with; new places and ideas often alarm them, resulting in a dogmatic insistence that their way is the right way. They can be quite bossy and domineering, although that usually comes out of a genuine belief that they know best and can help the ones they care about. They are extremely faithful friends and lovers, ready to drop everything and go into helper mode. However, if their trust is breached, there's no going back. No one can hold a grudge like an Olive Sign, and they aren't afraid to just pick up and leave if they decide something isn't working for them. Romance and companionship are extremely important to them, so even if they get hurt, their hearts remain open.", + description: "", sign: "Leo", - color: [0, 255, 0], + color: [0, 1, 0], dates: ["July 23", "August 22"] }, Jade: { name: "Jade", - description: - "Jade Signs are the zodiac's caretakers. Intelligent and steady, they are excellent organizers and planners. They are detail-oriented, and can tend toward perfectionism, never satisfied with their endeavors. If you hire on a Jade Sign, be prepared for an excellent product, but also no peace until that project is flawless. They are fussy and particular, which can cause friction with those around them, although a Jade Sign holds no one to as high a standard as they hold themselves. Since they are shy with strangers and slow to open up, Jade Signs can often come off as timid or doormats, when really they just prefer to come at conflicts in a less combative way. Naturally loyal and loving, they make wonderful doctors, parents, and caretakers, whether they are taking care of people, pets, or plants. In relationships, they can be slow to open up, and need someone willing to be patient enough to go at their pace. If all of this makes Jade Signs sound soft and nurturing, they are, but keep in mind that they can also be fiercely destructive if those they care about are threatened. It takes a lot to make a Jade Sign snap, but if they do, take cover.", + description: "", sign: "Virgo", - color: [0, 255, 127], + color: [0, 1, 0.5], dates: ["August 23", "September 22"] }, Teal: { name: "Teal", - description: - "Teal Signs are natural charmers. Social and flirtatious, they are great at parties and public speaking events. Even though they aren't afraid to use their many engaging qualities in both personal and business ventures, they have a strong moral sense. Right and wrong are very obvious to a Teal Sign, and it can frustrate them that others don't see the world the same way they do. Their idealism can make them strong defenders of justice, but it can also result in them being incredibly let down. Their strict adherence to procedure can lead to errors in judgement; they can be gullible and too quick to trust. They have vibrant imaginations, and enjoy fiction and roleplaying, and often those games will resemble the lives they want to be living. Deep down, they often long for a hero, someone they can idolize and count on, with the smarts and charisma to keep up with them. Unfortunately, they have a tendency to get involved with people who are very obviously wrong for them out of a desire not to be alone. Many Teal Signs are better off being single, at least until someone really extraordinary comes along.", + description: "", sign: "Libra", - color: [0, 255, 255], + color: [0, 1, 1], dates: ["September 23", "October 23"] }, Blue: { name: "Blue", - description: - "Let's not mince words: Blue Signs are the ones to watch. Of all the sign classes, they have the potential to do the most good, but also cause the worse harm. They can be incredibly effective, and also incredibly destructive. Tell a Blue Sign this and chances are they would agree with you. They are magnetic and adaptive, able to adjust how they present themselves in any situation. They have a mask for every occasion. They are obsessively dedicated, willing to throw themselves into work, play, and everything in between. Because of this, Blue Signs are highly valuable allies and friends. However, they are very selective when it comes to who they let into their inner circle. You could be best friends with a Blue Sign and still never truly know them. They are powerful and successful, but they also tend toward jealousy. They often resent those they see as more well-positioned than they are. A well-adjusted Blue Sign is fantastically competent and inspiring, but a Blue Sign at their worst is a force for chaos. In love they can find themselves having to choose between their ambitions and their relationships, often with great difficulty.", + description: "", sign: "Scorpio", - color: [0, 127, 255], + color: [0, 0.5, 1], dates: ["October 24", "November 21"] }, Indigo: { name: "Indigo", - description: - "Indigo Signs are the enthusiasts of the sign classes. Friendly and cheerful, their optimism is contagious. Being around a well-adjusted Indigo Sign is always a good time. It's hard not to be drawn into their excitable orbit, just like they are drawn in by anything and everything that piques their interest. And those interests are liable to change at any time. Indigo Signs will often surprise their friends and family by declaring they are no longer interested in what just last week they were claiming was their jam. If you catch an Indigo Signs in a philosophical mood, they can be unexpectedly poignant and introspective. A downside of all this jovial enthusiasm is that Indigo Signs often don't know their own strength. They are known to be careless, both physically and emotionally, their conversations punctuated by jostling elbows and tactless comments. They don't usually mean to offend, and are often shocked to find out they upset anyone. When this happens, they can dig their heels in and insist they did nothing wrong. In romance, Indigo Signs need partners who can keep up with their expansive personalities, as well as forgive them for the occasional hurt feeling or two.", + description: "", sign: "Sagittarius", - color: [0, 0, 255], + color: [0, 0, 1], dates: ["November 22", "December 21"] }, Purple: { name: "Purple", - description: - "Purple Signs are the workaholics of the sign classes. Ambitious and driven, they have a very specific path in mind to reach the pinnacle of their field, and will work tirelessly toward it. However, if their practical brains convince them that their goal is unrealistic, they may be slow to trust anyone with the secret of their true desires. They are often very funny, their wit veering toward the dryly macabre. Their fatalism can be incredibly humorous or terrible, depending who you ask. Purple Signs are usually the people who will say out loud what everyone else was thinking but was too nervous to mention. They are very stubborn, and once they've made up their mind about something, whether it be a restaurant choice or a political affiliation, it is difficult to change. They have trouble admitting they were mistaken, and also that they are upset. An oft-repeated phrase of the Purple Signs is, \"It's fine, don't worry about it.\" They will let arguments fester rather than face them head on. In love they tend to be strictly monogamous and fiercely devoted, ready to pledge themselves to a person the same way they do their goals-utterly, and without reservation.", + description: "", sign: "Capricorn", - color: [127, 0, 255], + color: [0.5, 0, 1], dates: ["December 22", "January 19"] }, Violet: { name: "Violet", - description: - "Violet Signs are the universe's eccentrics. Forget marching to their own drummer-Violets built their own drum, and it's probably weird. A good deal of this is natural, but they also have a distinct bent toward contrariness. They are the sorts to give the popular thing a pass. Personable and outlandish, they are ready to make friends with anyone, although if they aren't careful their 'game for anything' attitude can come across as clingy or desperate. When their feelings are reciprocated, however, they are very loyal friends. Politics and humanitarian causes are often very important to Violet Signs, and they will turn their considerable inventive energy into a sort of noblesse oblige, happy to offer their nontraditional approaches to help others. At their very best Violet Signs are artistic and inspired, but they tread the fine line between genius and maniac. Too often their more esoteric interests can come across as perverse or untoward, and they can have a hard time holding their tempers, especially if they feel that they are being belittled or ignored. Intelligence is enormously attractive to Violet Signs, and often an intellectual connection is necessary for them to be attracted to a prospective partner.", + description: "", sign: "Aquarius", - color: [255, 0, 255], + color: [1, 0, 1], dates: ["January 20", "February 18"] }, Fuchsia: { name: "Fuchsia", - description: - "Fuchsia Signs are the final of the sign classes, fittingly, also the most enigmatic. Possessing a strong imagination, they have an otherworldly quality to them that draws others in. Often, it has more to do with what they don't tell you than what they do, giving them an air of mystery that would more than likely perplex a Fuchsia sign if you told them about it. They aren't usually trying to be alluring-they're just lost in thought. Highly emotional, Fuchsia signs are sensitive and anxious, and tend to spend a lot of time worrying-about the world, the future, and what others think of them. They are artistic and talented, but can suffer from crippling bouts of depression, holding themselves to impossibly high standards. They have rich fantasy lives, and can get so caught up in daydreams that they sometimes forget to actually do things. Many Fuchsia Signs have trouble with follow-through, and it can take a lot to kick them out of their inertia. As far as romance goes, they need partners who are willing to put in the time to go at their pace, and who can handle how sensitive and emotional they can be.", + description: "", sign: "Pisces", - color: [255, 0, 127], + color: [1, 0, 0.5], dates: ["February 19", "March 20"] } }; diff --git a/src/utility/react/AuthContext.tsx b/src/utility/react/AuthContext.tsx new file mode 100644 index 0000000..c0cee8a --- /dev/null +++ b/src/utility/react/AuthContext.tsx @@ -0,0 +1,8 @@ +import { createContext } from "react"; + +const AuthContext = createContext({ + TROLLCALL_NAME: "", + TROLLCALL_CODE: "" +}); + +export default AuthContext; diff --git a/src/utility/react/Themer.tsx b/src/utility/react/Themer.tsx index a197d90..4249972 100644 --- a/src/utility/react/Themer.tsx +++ b/src/utility/react/Themer.tsx @@ -2,16 +2,16 @@ import { Color3 } from "@/types/assist/color"; import { createContext } from "react"; export default function Themer({ - pri, - sec, - inverted, + pri, + sec, + inverted }: { - pri: Color3; - sec: Color3; - inverted?: boolean; + pri: Color3; + sec: Color3; + inverted?: boolean; }) { - return inverted ? ( - - ) : ( - - ); + ); } export const ThemeModeContext = createContext(false as boolean | undefined); + +export const defaultTheme: [Color3, Color3] = [ + new Color3(0.9, 0.9, 0.8), + new Color3(0.7, 0.7, 0.6) +]; +export const hiveswapTheme: [Color3, Color3] = [ + new Color3(0.5, 0, 1), + new Color3(0.25, 0, 0.5) +]; diff --git a/tsconfig.json b/tsconfig.json index b976dbc..6c21b25 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,6 +8,7 @@ "forceConsistentCasingInFileNames": true, "noEmit": true, "esModuleInterop": true, + "noErrorTruncation": true, "module": "esnext", "moduleResolution": "bundler", "resolveJsonModule": true,