mirror of
https://github.com/PhaseII-eAmusement-Network/PhaseWeb3-Vue.git
synced 2026-03-21 17:54:26 -05:00
This took way too long, but i finally fixed all of the bugs i created in making this update
This commit is contained in:
parent
2a18ef1f89
commit
93c9732094
|
|
@ -1,7 +1,9 @@
|
|||
VITE_APP_VERSION="3.1.1"
|
||||
VITE_APP_VERSION="3.1.2"
|
||||
VITE_API_URL="http://localhost:8000/"
|
||||
VITE_API_KEY="your_api_key_should_be_here"
|
||||
VITE_ASSET_PATH="/assets"
|
||||
VITE_GAME_ASSET_PATH="https://cdn.phaseii.network/file/PhaseII/game-assets"
|
||||
VITE_DISCORD_OAUTH_URL="https://discord.com/oauth2/authorize?client_id=947985989421395988&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A5173%2F%23%2Fprofile%2Fintegrate%2Fdiscord&scope=identify"
|
||||
VITE_TACHI_OAUTH_URL="https://kamai.tachi.ac/oauth/request-auth?clientID=CIb72d1ff81fcfdc001ead8bde3a0ae1a7e0663a37"
|
||||
VITE_TACHI_OAUTH_URL="https://kamai.tachi.ac/oauth/request-auth?clientID=CIb72d1ff81fcfdc001ead8bde3a0ae1a7e0663a37"
|
||||
VITE_DISCORD_URL="https://discord.gg/mNmjpX33cd"
|
||||
VITE_DOCS_URL="https://docs.phaseii.network"
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
VITE_APP_VERSION="3.1.1"
|
||||
VITE_APP_VERSION="3.1.2"
|
||||
VITE_API_URL="https://restfulsleep.phaseii.network"
|
||||
VITE_API_KEY="your_api_key_should_be_here"
|
||||
VITE_ASSET_PATH="https://cdn.phaseii.network/file/PhaseII/web-assets"
|
||||
VITE_GAME_ASSET_PATH="https://cdn.phaseii.network/file/PhaseII/game-assets"
|
||||
VITE_DISCORD_OAUTH_URL="https://discord.com/oauth2/authorize?client_id=947985989421395988&response_type=code&redirect_uri=https%3A%2F%2Fweb3.phaseii.network%2Fprofile%2Fintegrate%2Fdiscord&scope=identify"
|
||||
VITE_TACHI_OAUTH_URL="https://kamai.tachi.ac/oauth/request-auth?clientID=CIce4260e1939ceed11c8e48ee857a3aef2a87ba56"
|
||||
VITE_TACHI_OAUTH_URL="https://kamai.tachi.ac/oauth/request-auth?clientID=CIce4260e1939ceed11c8e48ee857a3aef2a87ba56"
|
||||
VITE_DISCORD_URL="https://discord.gg/mNmjpX33cd"
|
||||
VITE_DOCS_URL="https://docs.phaseii.network"
|
||||
211
package-lock.json
generated
211
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "phaseweb3",
|
||||
"version": "3.1.0-RC",
|
||||
"version": "3.1.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "phaseweb3",
|
||||
"version": "3.1.0-RC",
|
||||
"version": "3.1.1",
|
||||
"dependencies": {
|
||||
"@phosphor-icons/vue": "^2.2.1",
|
||||
"@tailwindcss/vite": "^4.1.11",
|
||||
|
|
@ -507,9 +507,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@eslint-community/eslint-utils": {
|
||||
"version": "4.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz",
|
||||
"integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==",
|
||||
"version": "4.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
|
||||
"integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"eslint-visitor-keys": "^3.4.3"
|
||||
|
|
@ -534,13 +534,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@eslint/config-array": {
|
||||
"version": "0.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz",
|
||||
"integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==",
|
||||
"version": "0.21.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz",
|
||||
"integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@eslint/object-schema": "^2.1.6",
|
||||
"@eslint/object-schema": "^2.1.7",
|
||||
"debug": "^4.3.1",
|
||||
"minimatch": "^3.1.2"
|
||||
},
|
||||
|
|
@ -549,21 +548,22 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@eslint/config-helpers": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz",
|
||||
"integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==",
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
|
||||
"integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@eslint/core": "^0.17.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/core": {
|
||||
"version": "0.15.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz",
|
||||
"integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==",
|
||||
"version": "0.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
|
||||
"integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.15"
|
||||
},
|
||||
|
|
@ -572,11 +572,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
|
||||
"integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz",
|
||||
"integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.3.2",
|
||||
|
|
@ -584,7 +583,7 @@
|
|||
"globals": "^14.0.0",
|
||||
"ignore": "^5.2.0",
|
||||
"import-fresh": "^3.2.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"js-yaml": "^4.1.1",
|
||||
"minimatch": "^3.1.2",
|
||||
"strip-json-comments": "^3.1.1"
|
||||
},
|
||||
|
|
@ -609,11 +608,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@eslint/js": {
|
||||
"version": "9.32.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz",
|
||||
"integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==",
|
||||
"version": "9.39.2",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz",
|
||||
"integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
|
|
@ -622,23 +620,21 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@eslint/object-schema": {
|
||||
"version": "2.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
|
||||
"integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
|
||||
"version": "2.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
|
||||
"integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/plugin-kit": {
|
||||
"version": "0.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.4.tgz",
|
||||
"integrity": "sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==",
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
|
||||
"integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@eslint/core": "^0.15.1",
|
||||
"@eslint/core": "^0.17.0",
|
||||
"levn": "^0.4.1"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -777,7 +773,6 @@
|
|||
"resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz",
|
||||
"integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.18.0 || >=16.0.0"
|
||||
},
|
||||
|
|
@ -1384,8 +1379,7 @@
|
|||
"version": "7.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
||||
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@vitejs/plugin-vue": {
|
||||
"version": "6.0.1",
|
||||
|
|
@ -1666,12 +1660,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz",
|
||||
"integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==",
|
||||
"version": "1.13.5",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz",
|
||||
"integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.4",
|
||||
"follow-redirects": "^1.15.11",
|
||||
"form-data": "^4.0.5",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
|
|
@ -2120,25 +2114,23 @@
|
|||
}
|
||||
},
|
||||
"node_modules/eslint": {
|
||||
"version": "9.32.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.32.0.tgz",
|
||||
"integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==",
|
||||
"version": "9.39.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz",
|
||||
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/eslint-utils": "^4.8.0",
|
||||
"@eslint-community/regexpp": "^4.12.1",
|
||||
"@eslint/config-array": "^0.21.0",
|
||||
"@eslint/config-helpers": "^0.3.0",
|
||||
"@eslint/core": "^0.15.0",
|
||||
"@eslint/config-array": "^0.21.1",
|
||||
"@eslint/config-helpers": "^0.4.2",
|
||||
"@eslint/core": "^0.17.0",
|
||||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@eslint/js": "9.32.0",
|
||||
"@eslint/plugin-kit": "^0.3.4",
|
||||
"@eslint/js": "9.39.2",
|
||||
"@eslint/plugin-kit": "^0.4.1",
|
||||
"@humanfs/node": "^0.16.6",
|
||||
"@humanwhocodes/module-importer": "^1.0.1",
|
||||
"@humanwhocodes/retry": "^0.4.2",
|
||||
"@types/estree": "^1.0.6",
|
||||
"@types/json-schema": "^7.0.15",
|
||||
"ajv": "^6.12.4",
|
||||
"chalk": "^4.0.0",
|
||||
"cross-spawn": "^7.0.6",
|
||||
|
|
@ -2197,14 +2189,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-prettier": {
|
||||
"version": "5.5.3",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.3.tgz",
|
||||
"integrity": "sha512-NAdMYww51ehKfDyDhv59/eIItUVzU0Io9H2E8nHNGKEeeqlnci+1gCvrHib6EmZdf6GxF+LCV5K7UC65Ezvw7w==",
|
||||
"version": "5.5.5",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.5.tgz",
|
||||
"integrity": "sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prettier-linter-helpers": "^1.0.0",
|
||||
"synckit": "^0.11.7"
|
||||
"prettier-linter-helpers": "^1.0.1",
|
||||
"synckit": "^0.11.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.18.0 || >=16.0.0"
|
||||
|
|
@ -2228,16 +2219,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-vue": {
|
||||
"version": "10.3.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.3.0.tgz",
|
||||
"integrity": "sha512-A0u9snqjCfYaPnqqOaH6MBLVWDUIN4trXn8J3x67uDcXvR7X6Ut8p16N+nYhMCQ9Y7edg2BIRGzfyZsY0IdqoQ==",
|
||||
"version": "10.8.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.8.0.tgz",
|
||||
"integrity": "sha512-f1J/tcbnrpgC8suPN5AtdJ5MQjuXbSU9pGRSSYAuF3SHoiYCOdEX6O22pLaRyLHXvDcOe+O5ENgc1owQ587agA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.4.0",
|
||||
"natural-compare": "^1.4.0",
|
||||
"nth-check": "^2.1.1",
|
||||
"postcss-selector-parser": "^6.0.15",
|
||||
"postcss-selector-parser": "^7.1.0",
|
||||
"semver": "^7.6.3",
|
||||
"xml-name-validator": "^4.0.0"
|
||||
},
|
||||
|
|
@ -2245,11 +2235,15 @@
|
|||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@stylistic/eslint-plugin": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0",
|
||||
"@typescript-eslint/parser": "^7.0.0 || ^8.0.0",
|
||||
"eslint": "^8.57.0 || ^9.0.0",
|
||||
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
|
||||
"vue-eslint-parser": "^10.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@stylistic/eslint-plugin": {
|
||||
"optional": true
|
||||
},
|
||||
"@typescript-eslint/parser": {
|
||||
"optional": true
|
||||
}
|
||||
|
|
@ -2388,8 +2382,7 @@
|
|||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
|
||||
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fast-json-stable-stringify": {
|
||||
"version": "2.1.0",
|
||||
|
|
@ -2471,9 +2464,9 @@
|
|||
"license": "ISC"
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.9",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
|
||||
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
|
||||
"version": "1.15.11",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
|
||||
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
|
|
@ -2490,10 +2483,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
|
||||
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
|
||||
"license": "MIT",
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
|
||||
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
|
|
@ -3145,10 +3137,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/minizlib": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz",
|
||||
"integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==",
|
||||
"license": "MIT",
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz",
|
||||
"integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==",
|
||||
"dependencies": {
|
||||
"minipass": "^7.1.2"
|
||||
},
|
||||
|
|
@ -3162,21 +3153,6 @@
|
|||
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/mkdirp": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
|
||||
"integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"mkdirp": "dist/cjs/src/bin.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
|
|
@ -3439,9 +3415,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/postcss-selector-parser": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
|
||||
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
|
||||
"integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
|
|
@ -3483,11 +3459,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/prettier-linter-helpers": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
|
||||
"integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz",
|
||||
"integrity": "sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-diff": "^1.1.2"
|
||||
},
|
||||
|
|
@ -3694,11 +3669,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/synckit": {
|
||||
"version": "0.11.11",
|
||||
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz",
|
||||
"integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==",
|
||||
"version": "0.11.12",
|
||||
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz",
|
||||
"integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@pkgr/core": "^0.2.9"
|
||||
},
|
||||
|
|
@ -3725,16 +3699,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/tar": {
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz",
|
||||
"integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==",
|
||||
"license": "ISC",
|
||||
"version": "7.5.9",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.9.tgz",
|
||||
"integrity": "sha512-BTLcK0xsDh2+PUe9F6c2TlRp4zOOBMTkoQHQIWSIzI0R7KG46uEwq4OPk2W7bZcprBMsuaeFsqwYr7pjh6CuHg==",
|
||||
"dependencies": {
|
||||
"@isaacs/fs-minipass": "^4.0.0",
|
||||
"chownr": "^3.0.0",
|
||||
"minipass": "^7.1.2",
|
||||
"minizlib": "^3.0.1",
|
||||
"mkdirp": "^3.0.1",
|
||||
"minizlib": "^3.1.0",
|
||||
"yallist": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -3918,16 +3890,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/vue-eslint-parser": {
|
||||
"version": "10.2.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-10.2.0.tgz",
|
||||
"integrity": "sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==",
|
||||
"version": "10.4.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-10.4.0.tgz",
|
||||
"integrity": "sha512-Vxi9pJdbN3ZnVGLODVtZ7y4Y2kzAAE2Cm0CZ3ZDRvydVYxZ6VrnBhLikBsRS+dpwj4Jv4UCv21PTEwF5rQ9WXg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.4.0",
|
||||
"eslint-scope": "^8.2.0",
|
||||
"eslint-visitor-keys": "^4.2.0",
|
||||
"espree": "^10.3.0",
|
||||
"eslint-scope": "^8.2.0 || ^9.0.0",
|
||||
"eslint-visitor-keys": "^4.2.0 || ^5.0.0",
|
||||
"espree": "^10.3.0 || ^11.0.0",
|
||||
"esquery": "^1.6.0",
|
||||
"semver": "^7.6.3"
|
||||
},
|
||||
|
|
@ -3938,7 +3909,7 @@
|
|||
"url": "https://github.com/sponsors/mysticatea"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^8.57.0 || ^9.0.0"
|
||||
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "phaseweb3",
|
||||
"version": "3.1.1",
|
||||
"version": "3.1.2",
|
||||
"scripts": {
|
||||
"dev": "vite --host",
|
||||
"build": "vite build",
|
||||
|
|
|
|||
|
|
@ -47,5 +47,6 @@
|
|||
"3.0.45": ["- (Bugfix) Fix Timeline not loading", "- (Major) Add a filter to the data in the timeline for private profiles", "- (Game) Add SDVX 6th chart", "- (Bugfix) Fix floats for jubeat difficulties"],
|
||||
"3.1.0-RC": ["- (Feature) Add onboarding page", "- (Minor) Add BaseImage component", "- (Minor) Add BaseAccordion component, - (Admin) Finish admin event log page"],
|
||||
"3.1.0": ["- (Major) WebUI V3 full release"],
|
||||
"3.1.1": ["- (Admin) Add more admin stats for users", "- (Minor) Add new greetings"]
|
||||
"3.1.1": ["- (Admin) Add more admin stats for users", "- (Minor) Add new greetings"],
|
||||
"3.1.2": ["- (Major) Add initial code for oAuth pages", "- (Major) Add redirect to target page after login", "- (Minor) Add quick links to navbar", "- (Minor) Add new greetings", "- (Minor) Replace login page background", "- (Minor) Add animation to loading modal", "- (Bugfix) Refactor loading modal", "- (Bugfix) Refactor overlay layer", "- (Bugfix) Optimize main layouts", "- (Bugfix) Fix loading states around site", "- (Bugfix) Optimize news read api calls", "- (Minor) Add simple auth checkers to router, blocking access at webui level"]
|
||||
}
|
||||
66
src/App.vue
66
src/App.vue
|
|
@ -1,7 +1,71 @@
|
|||
<script setup>
|
||||
import { computed, ref, watch } from "vue";
|
||||
import { RouterView } from "vue-router";
|
||||
import { useMainStore } from "@/stores/main.js";
|
||||
import { useStyleStore } from "@/stores/style.js";
|
||||
import OverlayLayer from "@/components/OverlayLayer.vue";
|
||||
import LoadingModal from "@/components/Modal/LoadingModal.vue";
|
||||
|
||||
const mainStore = useMainStore();
|
||||
const styleStore = useStyleStore();
|
||||
|
||||
const loading = computed(() => mainStore.activeRequests !== 0);
|
||||
const saving = computed(() => mainStore.activeSavingRequests !== 0);
|
||||
const errorCode = computed(() => mainStore.errorCode);
|
||||
const isActive = computed(() => loading.value || saving.value);
|
||||
|
||||
const showModal = ref(false);
|
||||
|
||||
watch(isActive, (val) => {
|
||||
if (val) {
|
||||
showModal.value = true;
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
if (!isActive.value) {
|
||||
showModal.value = false;
|
||||
}
|
||||
}, 250);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<RouterView :key="$route.fullPath" />
|
||||
<div :class="{ dark: styleStore.darkMode }">
|
||||
<OverlayLayer
|
||||
:active="showModal"
|
||||
:transparent="saving"
|
||||
:z-index="showModal ? 'z-55' : '-z-150'"
|
||||
>
|
||||
<Transition name="modal-fade">
|
||||
<LoadingModal
|
||||
v-if="showModal"
|
||||
:active="showModal"
|
||||
:is-save="saving"
|
||||
:error-code="errorCode"
|
||||
/>
|
||||
</Transition>
|
||||
</OverlayLayer>
|
||||
|
||||
<RouterView
|
||||
:key="$route.path"
|
||||
:class="showModal && !saving ? 'hidden' : 'block'"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.modal-fade-enter-active,
|
||||
.modal-fade-leave-active {
|
||||
transition: all 0.15s ease-in;
|
||||
}
|
||||
|
||||
.modal-fade-enter-from,
|
||||
.modal-fade-leave-to {
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
.modal-fade-enter-to,
|
||||
.modal-fade-leave-from {
|
||||
transform: scale(1);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<script setup>
|
||||
import { defineProps } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { PhArrowLineUpRight } from "@phosphor-icons/vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
<script setup>
|
||||
import { defineProps } from "vue";
|
||||
|
||||
defineProps({
|
||||
musicData: {
|
||||
type: Object,
|
||||
|
|
|
|||
|
|
@ -34,9 +34,10 @@ const computedValue = computed({
|
|||
},
|
||||
});
|
||||
|
||||
const inputType = computed(() =>
|
||||
props.type === "radio" ? "radio" : "checkbox",
|
||||
);
|
||||
const inputType = computed(() => {
|
||||
if (props.type === "radio") return "radio";
|
||||
return "checkbox";
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<script setup>
|
||||
import { useRouter } from "vue-router";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import OverlayLayer from "@/components/OverlayLayer.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import { useMainStore } from "@/stores/main";
|
||||
|
|
@ -36,89 +35,87 @@ function hotReload() {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<OverlayLayer v-if="active" :transparent="isSave">
|
||||
<CardBox
|
||||
class="shadow-lg max-h-modal w-11/12 md:w-3/5 lg:w-2/5 xl:w-4/12 z-50 text-white/90"
|
||||
<CardBox
|
||||
class="shadow-lg max-h-modal w-11/12 md:w-3/5 lg:w-2/5 xl:w-4/12 z-50 text-white/90"
|
||||
>
|
||||
<div
|
||||
v-if="!isFinished && !errorCode"
|
||||
class="grid text-center justify-center grid-cols-1 gap-3"
|
||||
>
|
||||
<div
|
||||
v-if="!isFinished && !errorCode"
|
||||
class="grid text-center justify-center grid-cols-1 gap-3"
|
||||
>
|
||||
<template v-if="!mainStore.userCustomize.shrimpLinks">
|
||||
<img
|
||||
class="rounded-full place-self-center"
|
||||
src="/icon.gif"
|
||||
width="70"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<BaseIcon
|
||||
:icon="PhShrimp"
|
||||
size="70"
|
||||
w="w-50"
|
||||
color="text-pink-400"
|
||||
class="m-5 animate animate-spin place-self-center"
|
||||
/>
|
||||
</template>
|
||||
<h1 class="text-xl md:text-2xl">
|
||||
<template v-if="!mainStore.userCustomize.shrimpLinks">
|
||||
<img
|
||||
class="rounded-full place-self-center"
|
||||
src="/icon.gif"
|
||||
width="70"
|
||||
/>
|
||||
{{ isSave ? `Submitting...` : `Loading...` }}
|
||||
</template>
|
||||
<template v-else>
|
||||
<BaseIcon
|
||||
:icon="PhShrimp"
|
||||
size="70"
|
||||
w="w-50"
|
||||
color="text-pink-400"
|
||||
class="m-5 animate animate-spin place-self-center"
|
||||
/>
|
||||
<span class="text-pink-200">
|
||||
{{ isSave ? `Shrimping...` : `Krilling...` }}
|
||||
</span>
|
||||
</template>
|
||||
<h1 class="text-xl md:text-2xl">
|
||||
<template v-if="!mainStore.userCustomize.shrimpLinks">
|
||||
{{ isSave ? `Submitting...` : `Loading...` }}
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="text-pink-200">
|
||||
{{ isSave ? `Shrimping...` : `Krilling...` }}
|
||||
</span>
|
||||
</template>
|
||||
</h1>
|
||||
<p class="text-lg md:text-xl">
|
||||
<template v-if="!mainStore.userCustomize.shrimpLinks">
|
||||
Please wait
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="text-pink-400">Shrimply wait</span>
|
||||
</template>
|
||||
</p>
|
||||
</div>
|
||||
</h1>
|
||||
<p class="text-lg md:text-xl">
|
||||
<template v-if="!mainStore.userCustomize.shrimpLinks">
|
||||
Please wait
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="text-pink-400">Shrimply wait</span>
|
||||
</template>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="isSave && isFinished && !errorCode"
|
||||
class="grid text-center justify-center grid-cols-1 gap-3"
|
||||
>
|
||||
<div class="place-self-center">
|
||||
<BaseIcon
|
||||
:icon="PhCloudCheck"
|
||||
class="text-green-700"
|
||||
w="w-20"
|
||||
:size="45"
|
||||
/>
|
||||
</div>
|
||||
<h1 class="text-xl md:text-2xl">Saved!</h1>
|
||||
<div
|
||||
v-if="isSave && isFinished && !errorCode"
|
||||
class="grid text-center justify-center grid-cols-1 gap-3"
|
||||
>
|
||||
<div class="place-self-center">
|
||||
<BaseIcon
|
||||
:icon="PhCloudCheck"
|
||||
class="text-green-700"
|
||||
w="w-20"
|
||||
:size="45"
|
||||
/>
|
||||
</div>
|
||||
<h1 class="text-xl md:text-2xl">Saved!</h1>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="errorCode"
|
||||
class="grid text-center justify-center grid-cols-1 gap-3"
|
||||
>
|
||||
<div class="place-self-center">
|
||||
<BaseIcon :icon="PhCloudX" class="text-red-500" w="w-20" :size="45" />
|
||||
</div>
|
||||
<h1 class="text-xl md:text-2xl">Uh Oh!</h1>
|
||||
<h1 class="text-lg md:text-xl">
|
||||
The server had some trouble processing your request at this time.
|
||||
</h1>
|
||||
<h1 class="text-lg md:text-xl">
|
||||
Error: <span class="text-red-500">{{ errorCode }}</span>
|
||||
</h1>
|
||||
<div>
|
||||
<BaseButton
|
||||
type="submit"
|
||||
color="info"
|
||||
label="Reload"
|
||||
:small="false"
|
||||
@click="hotReload()"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="errorCode"
|
||||
class="grid text-center justify-center grid-cols-1 gap-3"
|
||||
>
|
||||
<div class="place-self-center">
|
||||
<BaseIcon :icon="PhCloudX" class="text-red-500" w="w-20" :size="45" />
|
||||
</div>
|
||||
</CardBox>
|
||||
</OverlayLayer>
|
||||
<h1 class="text-xl md:text-2xl">Uh Oh!</h1>
|
||||
<h1 class="text-lg md:text-xl">
|
||||
The server had some trouble processing your request at this time.
|
||||
</h1>
|
||||
<h1 class="text-lg md:text-xl">
|
||||
Error: <span class="text-red-500">{{ errorCode }}</span>
|
||||
</h1>
|
||||
<div>
|
||||
<BaseButton
|
||||
type="submit"
|
||||
color="info"
|
||||
label="Reload"
|
||||
:small="false"
|
||||
@click="hotReload()"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</CardBox>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ const isMenuNavBarActive = ref(false);
|
|||
|
||||
<template>
|
||||
<nav
|
||||
class="top-0 inset-x-0 fixed bg-gray-50 h-14 z-30 transition-position duration-150 ease-in-out w-screen lg:w-auto dark:bg-slate-900"
|
||||
class="top-0 left-0 right-0 inset-x-0 fixed bg-gray-50 h-14 z-30 transition-position duration-150 ease-in-out w-full lg:w-auto dark:bg-slate-900"
|
||||
>
|
||||
<div class="flex lg:items-stretch" :class="containerMaxW">
|
||||
<div class="flex flex-1 items-stretch h-14">
|
||||
|
|
@ -44,7 +44,7 @@ const isMenuNavBarActive = ref(false);
|
|||
</NavBarItemPlain>
|
||||
</div>
|
||||
<div
|
||||
class="max-h-screen-menu overflow-y-auto lg:overflow-visible absolute w-screen top-14 left-0 bg-gray-50 shadow-lg lg:w-auto lg:flex lg:static lg:shadow-none dark:bg-slate-900"
|
||||
class="max-h-screen-menu overflow-y-auto lg:overflow-visible fixed w-screen top-14 left-0 bg-gray-50 shadow-lg lg:w-auto lg:flex lg:static lg:shadow-none dark:bg-slate-900"
|
||||
:class="[isMenuNavBarActive ? 'block' : 'hidden']"
|
||||
>
|
||||
<NavBarMenuList :menu="menu" @menu-click="menuClick" />
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ defineProps({
|
|||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["overlay-click"]);
|
||||
|
|
@ -26,33 +30,20 @@ const styleStore = useStyleStore();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="[type, zIndex]"
|
||||
class="items-center flex-col justify-center md:h-full fixed inset-0"
|
||||
>
|
||||
<transition
|
||||
enter-active-class="transition duration-150 ease-in"
|
||||
enter-from-class="opacity-0"
|
||||
enter-to-class="opacity-100"
|
||||
leave-active-class="transition duration-150 ease-in"
|
||||
leave-from-class="opacity-100"
|
||||
leave-to-class="opacity-0"
|
||||
<Transition name="overlay-fade">
|
||||
<div
|
||||
v-show="active"
|
||||
:class="[type, zIndex]"
|
||||
class="fixed inset-0 flex flex-col items-center justify-center bg-linear-to-tr dark:from-gray-700 dark:via-gray-900 dark:to-gray-700 transform"
|
||||
>
|
||||
<div
|
||||
class="absolute inset-0 bg-linear-to-tr dark:from-gray-700 dark:via-gray-900 dark:to-gray-700 h-screen"
|
||||
class="absolute inset-0"
|
||||
:class="`${styleStore.overlayStyle} ${
|
||||
transparent ? 'opacity-90' : 'opacity-100'
|
||||
}`"
|
||||
@click="overlayClick"
|
||||
/>
|
||||
</transition>
|
||||
<transition
|
||||
enter-active-class="transition duration-100 ease-out"
|
||||
enter-from-class="transform scale-95 opacity-0"
|
||||
enter-to-class="transform scale-100 opacity-100"
|
||||
leave-active-class="animate-fade-out"
|
||||
>
|
||||
<slot />
|
||||
</transition>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</template>
|
||||
|
|
|
|||
80
src/constants/developer/index.js
Normal file
80
src/constants/developer/index.js
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
export const applicationIntents = [
|
||||
{
|
||||
id: "network",
|
||||
label: "Read Network",
|
||||
tip: "View network news, public profiles, and public arcades",
|
||||
},
|
||||
{
|
||||
id: "read_user",
|
||||
label: "Read User",
|
||||
tip: "Allows this app to read a user that has authenticated through it",
|
||||
},
|
||||
{
|
||||
id: "update_user",
|
||||
label: "Update User",
|
||||
tip: "Allows this app to update a user that has authenticated through it",
|
||||
},
|
||||
{
|
||||
id: "read_profiles",
|
||||
label: "Read Profiles",
|
||||
tip: "Allows this app to read the game profiles of a user that has authenticated through it",
|
||||
},
|
||||
{
|
||||
id: "update_profiles",
|
||||
label: "Update Profiles",
|
||||
tip: "Allows this app to update the game profiles of a user that has authenticated through it",
|
||||
},
|
||||
{
|
||||
id: "read_scores",
|
||||
label: "Read Scores",
|
||||
tip: "Allows this app to read the scores and records of a user that has authenticated through it",
|
||||
},
|
||||
{
|
||||
id: "read_arcade",
|
||||
label: "Read Arcades",
|
||||
tip: "Allows this app to read the arcades of a user that has authenticated through it",
|
||||
},
|
||||
{
|
||||
id: "update_arcade",
|
||||
label: "Update Arcades",
|
||||
tip: "Allows this app to update an arcade of a user that has authenticated through it",
|
||||
},
|
||||
{
|
||||
id: "webhook",
|
||||
label: "Webhooks",
|
||||
tip: "Allows this app to add and remove webhooks for a user that has authenticated through it",
|
||||
},
|
||||
];
|
||||
|
||||
export const applicationWebhooks = [
|
||||
{
|
||||
id: "network.news",
|
||||
type: "network",
|
||||
short: "news",
|
||||
label: "Network News",
|
||||
tip: "Called when a new news post is uploaded",
|
||||
},
|
||||
{
|
||||
id: "network.maintenance",
|
||||
type: "network",
|
||||
short: "maintenance",
|
||||
label: "Network Maintenance",
|
||||
tip: "Called when a maintenance window is posted",
|
||||
},
|
||||
{
|
||||
id: "arcade.event",
|
||||
type: "arcade",
|
||||
short: "event",
|
||||
label: "Arcade PCB Events",
|
||||
tip: "Called when a PCB event is sent. Requires an arcade to be specified",
|
||||
fields: ["arcadeId"],
|
||||
},
|
||||
{
|
||||
id: "arcade.paseli",
|
||||
type: "arcade",
|
||||
short: "paseli",
|
||||
label: "Arcade PASELI",
|
||||
tip: "Called when a PASELI transaction completes. Requires an arcade to be specified",
|
||||
fields: ["arcadeId"],
|
||||
},
|
||||
];
|
||||
|
|
@ -635,5 +635,25 @@
|
|||
"author": "superaustin7",
|
||||
"header": "Why does <username> need Konami Original Songs?",
|
||||
"comment": "We ❤️ Pop'n Music!"
|
||||
},
|
||||
{
|
||||
"author": "57z",
|
||||
"header": "<username>, I once again am asking you to",
|
||||
"comment": "submit welcome greetings."
|
||||
},
|
||||
{
|
||||
"author": "Anonymous",
|
||||
"header": "Welcome to StepManiaX, <username>!",
|
||||
"comment": "Kyle Ward will sue"
|
||||
},
|
||||
{
|
||||
"author": "Dadrewster569",
|
||||
"header": "Konnichihello, <username>",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"author": "superaustin7",
|
||||
"header": "Welcome to jubeat, <username>",
|
||||
"comment": "THAT WON'T MAKE IT IN TIME FOR THIS SCHEDULE."
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -10,13 +10,14 @@ import {
|
|||
PhFilmSlate,
|
||||
PhArchive,
|
||||
PhGitMerge,
|
||||
PhCode,
|
||||
PhDiscordLogo,
|
||||
PhTextAa,
|
||||
} from "@phosphor-icons/vue";
|
||||
import { ref, watch, onMounted, computed } from "vue";
|
||||
import { ref, computed } from "vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import menuNavBar from "@/menuNavBar.js";
|
||||
import { useMainStore } from "@/stores/main.js";
|
||||
import { useStyleStore } from "@/stores/style.js";
|
||||
import LoadingModal from "@/components/Modal/LoadingModal.vue";
|
||||
// import EmailModal from "@/components/Modal/EmailModal.vue";
|
||||
import UpdateModal from "@/components/Modal/UpdateModal.vue";
|
||||
import WelcomeModal from "@/components/Modal/WelcomeModal.vue";
|
||||
|
|
@ -26,75 +27,20 @@ import NavBarItemPlain from "@/components/NavBarItemPlain.vue";
|
|||
import AsideMenu from "@/components/Menus/AsideMenu.vue";
|
||||
import FooterBar from "@/components/FooterBar.vue";
|
||||
import { gameData } from "@/constants";
|
||||
// import BaseButton from "@/components/BaseButton.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
const DISCORD_URL = import.meta.env.VITE_DISCORD_URL;
|
||||
const DOCS_URL = import.meta.env.VITE_DOCS_URL;
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
const mainStore = useMainStore();
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const validSession = await mainStore.loadUser();
|
||||
if (!validSession) {
|
||||
mainStore.deleteUserSession();
|
||||
router.push({
|
||||
name: "login",
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to check SessionID:", error);
|
||||
mainStore.deleteUserSession();
|
||||
router.push({
|
||||
name: "login",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const loading = ref(mainStore.activeRequests !== 0);
|
||||
const saving = ref(mainStore.activeSavingRequests !== 0);
|
||||
const errorCode = ref(mainStore.errorCode);
|
||||
const userLoaded = ref(mainStore.userLoaded);
|
||||
const userArcades = ref(mainStore.userArcades);
|
||||
|
||||
watch(
|
||||
() => mainStore.activeRequests !== 0,
|
||||
(newValue) => {
|
||||
loading.value = newValue;
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => mainStore.activeSavingRequests !== 0,
|
||||
(newValue) => {
|
||||
saving.value = newValue;
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => mainStore.errorCode,
|
||||
(newValue) => {
|
||||
errorCode.value = newValue;
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => mainStore.userLoaded,
|
||||
(newValue) => {
|
||||
userLoaded.value = newValue;
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => mainStore.userArcades,
|
||||
(newValue) => {
|
||||
userArcades.value = newValue;
|
||||
},
|
||||
);
|
||||
const userLoaded = computed(() => mainStore.userLoaded);
|
||||
const userCustomize = computed(() => mainStore.userCustomize);
|
||||
|
||||
const layoutAsidePadding = "xl:pl-60";
|
||||
|
||||
const styleStore = useStyleStore();
|
||||
|
||||
const isAsideMobileExpanded = ref(false);
|
||||
const isAsideLgActive = ref(false);
|
||||
|
||||
|
|
@ -224,6 +170,14 @@ const menuAside = computed(() => {
|
|||
label: "Changelog Archive",
|
||||
});
|
||||
|
||||
if (mainStore.userAdmin) {
|
||||
sideMenu.push({
|
||||
label: "Developer Portal",
|
||||
icon: PhCode,
|
||||
to: "/developer",
|
||||
});
|
||||
}
|
||||
|
||||
return sideMenu;
|
||||
});
|
||||
</script>
|
||||
|
|
@ -232,23 +186,12 @@ const menuAside = computed(() => {
|
|||
<div
|
||||
:key="route.fullPath"
|
||||
:class="{
|
||||
dark: styleStore.darkMode,
|
||||
'overflow-hidden lg:overflow-visible': isAsideMobileExpanded,
|
||||
}"
|
||||
>
|
||||
<LoadingModal
|
||||
:active="loading || saving"
|
||||
:is-save="saving"
|
||||
:error-code="errorCode"
|
||||
class="transition-opacity duration-300 ease-out"
|
||||
:class="{
|
||||
'opacity-100': loading || saving,
|
||||
'opacity-0': !loading && !saving,
|
||||
}"
|
||||
/>
|
||||
<template v-if="userLoaded">
|
||||
<WelcomeModal class="transition-opacity duration-300 ease-out">
|
||||
<UpdateModal class="transition-opacity duration-300 ease-out" />
|
||||
<WelcomeModal>
|
||||
<UpdateModal />
|
||||
</WelcomeModal>
|
||||
<!-- <EmailModal class="transition-opacity duration-300 ease-out" /> -->
|
||||
</template>
|
||||
|
|
@ -285,14 +228,26 @@ const menuAside = computed(() => {
|
|||
<BaseIcon :icon="PhDotsThreeCircle" size="24" />
|
||||
</NavBarItemPlain>
|
||||
|
||||
<div class="h-full flex place-items-center ml-4 gap-4">
|
||||
<!-- <span>You can add up to 4 buttons here</span>
|
||||
<BaseButton small label="QuickNav" color="info" />
|
||||
<BaseButton small label="QuickNav" color="success" />
|
||||
<BaseButton small label="QuickNav" color="warning" />
|
||||
<BaseButton small label="QuickNav" color="danger" />
|
||||
<span>They're sticky!</span> -->
|
||||
</div>
|
||||
<template v-if="!userCustomize.hideQuickLinks">
|
||||
<div class="h-full flex place-items-center ml-4 gap-4">
|
||||
<BaseButton
|
||||
small
|
||||
label="Discord"
|
||||
:icon="PhDiscordLogo"
|
||||
color="info"
|
||||
:href="DISCORD_URL"
|
||||
target="_blank"
|
||||
/>
|
||||
<BaseButton
|
||||
small
|
||||
label="Docs"
|
||||
:icon="PhTextAa"
|
||||
color="info"
|
||||
:href="DOCS_URL"
|
||||
target="_blank"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</NavBar>
|
||||
<AsideMenu
|
||||
:is-aside-mobile-expanded="isAsideMobileExpanded"
|
||||
|
|
|
|||
|
|
@ -1,53 +1,12 @@
|
|||
<script setup>
|
||||
import { useMainStore } from "@/stores/main.js";
|
||||
import { useStyleStore } from "@/stores/style.js";
|
||||
import { ref, watch } from "vue";
|
||||
import LoadingModal from "@/components/Modal/LoadingModal.vue";
|
||||
const mainStore = useMainStore();
|
||||
|
||||
const loading = ref(mainStore.isLoading);
|
||||
const saving = ref(mainStore.isSaving);
|
||||
const errorCode = ref(mainStore.errorCode);
|
||||
const styleStore = useStyleStore();
|
||||
|
||||
watch(
|
||||
() => mainStore.isLoading,
|
||||
(newValue) => {
|
||||
loading.value = newValue;
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => mainStore.isSaving,
|
||||
(newValue) => {
|
||||
saving.value = newValue;
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => mainStore.errorCode,
|
||||
(newValue) => {
|
||||
errorCode.value = newValue;
|
||||
},
|
||||
);
|
||||
</script>
|
||||
<script setup></script>
|
||||
|
||||
<template>
|
||||
<div :class="{ dark: styleStore.darkMode }">
|
||||
<LoadingModal
|
||||
:active="loading || saving"
|
||||
:is-save="saving"
|
||||
:error-code="errorCode"
|
||||
class="transition-opacity duration-300 ease-out"
|
||||
:class="{
|
||||
'opacity-100': loading || saving,
|
||||
'opacity-0': !loading && !saving,
|
||||
}"
|
||||
<div class="bg-gray-950 dark:text-slate-100">
|
||||
<div
|
||||
class="hidden md:block absolute inset-0 z-0 bg-[radial-gradient(125%_125%_at_50%_10%,#000000_40%,#0d1a36_100%)]"
|
||||
/>
|
||||
<div class="bg-gray-950 dark:text-slate-100">
|
||||
<div class="animated animatedFadeInUp fadeInUp">
|
||||
<slot />
|
||||
</div>
|
||||
<div class="animated animatedFadeInUp fadeInUp">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import { useMainStore } from "@/stores/main";
|
||||
import Home from "@/views/HomeView.vue";
|
||||
|
||||
const routes = [
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Dashboard",
|
||||
},
|
||||
path: "/",
|
||||
|
|
@ -12,6 +14,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "News Archive",
|
||||
},
|
||||
path: "/news",
|
||||
|
|
@ -20,6 +23,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "News Post",
|
||||
},
|
||||
path: "/news/:id",
|
||||
|
|
@ -28,6 +32,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "WebUI Changelog",
|
||||
},
|
||||
path: "/changelog",
|
||||
|
|
@ -60,6 +65,16 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Authorize an App",
|
||||
},
|
||||
path: "/profile/authorize",
|
||||
name: "authorize_service",
|
||||
component: () => import("@/views/Auth/AuthorizeView.vue"),
|
||||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Profile",
|
||||
},
|
||||
path: "/profile",
|
||||
|
|
@ -68,6 +83,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Customizations",
|
||||
},
|
||||
path: "/profile/customize",
|
||||
|
|
@ -76,6 +92,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Integrations",
|
||||
},
|
||||
path: "/profile/integrate",
|
||||
|
|
@ -84,6 +101,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Integration Callback",
|
||||
},
|
||||
path: "/profile/integrate/:service",
|
||||
|
|
@ -92,6 +110,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Login Cards",
|
||||
},
|
||||
path: "/profile/cards",
|
||||
|
|
@ -100,6 +119,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Claim a Profile",
|
||||
},
|
||||
path: "/profile/claim",
|
||||
|
|
@ -108,6 +128,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Data Export",
|
||||
},
|
||||
path: "/profile/export",
|
||||
|
|
@ -124,6 +145,7 @@ const routes = [
|
|||
// },
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Play Videos",
|
||||
},
|
||||
path: "/profile/videos",
|
||||
|
|
@ -132,6 +154,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Game Images",
|
||||
},
|
||||
path: "/profile/content",
|
||||
|
|
@ -140,6 +163,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "View User",
|
||||
},
|
||||
path: "/profiles/:id",
|
||||
|
|
@ -151,6 +175,8 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresAdmin: true,
|
||||
title: "Admin Dashboard",
|
||||
},
|
||||
path: "/admin",
|
||||
|
|
@ -159,6 +185,8 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresAdmin: true,
|
||||
title: "Onboarding",
|
||||
},
|
||||
path: "/admin/onboarding",
|
||||
|
|
@ -167,6 +195,8 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresAdmin: true,
|
||||
title: "Auto-Onboarding",
|
||||
},
|
||||
path: "/admin/onboarding/:data",
|
||||
|
|
@ -175,6 +205,8 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresAdmin: true,
|
||||
title: "Network Maintenance",
|
||||
},
|
||||
path: "/admin/maint",
|
||||
|
|
@ -183,6 +215,8 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresAdmin: true,
|
||||
title: "Events",
|
||||
},
|
||||
path: "/admin/events",
|
||||
|
|
@ -191,6 +225,8 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresAdmin: true,
|
||||
title: "Data API",
|
||||
},
|
||||
path: "/admin/api",
|
||||
|
|
@ -199,6 +235,8 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresAdmin: true,
|
||||
title: "Arcades",
|
||||
},
|
||||
path: "/admin/arcades",
|
||||
|
|
@ -207,6 +245,8 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresAdmin: true,
|
||||
title: "Users",
|
||||
},
|
||||
path: "/admin/users",
|
||||
|
|
@ -215,6 +255,8 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresAdmin: true,
|
||||
title: "News",
|
||||
},
|
||||
path: "/admin/news",
|
||||
|
|
@ -223,6 +265,8 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresAdmin: true,
|
||||
title: "OTA Updates",
|
||||
},
|
||||
path: "/admin/ota",
|
||||
|
|
@ -239,6 +283,7 @@ const routes = [
|
|||
// },
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Arcade Overview",
|
||||
},
|
||||
path: "/arcade/:id",
|
||||
|
|
@ -247,6 +292,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Event Settings",
|
||||
},
|
||||
path: "/arcade/:id/events",
|
||||
|
|
@ -258,6 +304,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Machine List",
|
||||
},
|
||||
path: "/arcade/:id/machines",
|
||||
|
|
@ -269,6 +316,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "PASELI Transactions",
|
||||
},
|
||||
path: "/arcade/:id/paseli",
|
||||
|
|
@ -280,6 +328,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Claim an Arcade",
|
||||
},
|
||||
path: "/arcade/claim",
|
||||
|
|
@ -288,6 +337,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Game Overview",
|
||||
},
|
||||
path: "/games/:id/",
|
||||
|
|
@ -299,6 +349,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "View Profile",
|
||||
},
|
||||
path: "/games/:game/profiles/:userId/",
|
||||
|
|
@ -310,6 +361,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Edit Profile",
|
||||
},
|
||||
path: "/games/:game/edit",
|
||||
|
|
@ -321,6 +373,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Rivals",
|
||||
},
|
||||
path: "/games/:game/rivals",
|
||||
|
|
@ -332,6 +385,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Song Overview",
|
||||
},
|
||||
path: "/games/:game/song/:songId",
|
||||
|
|
@ -343,6 +397,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "View Scores",
|
||||
},
|
||||
path: "/games/:game/scores/:userId",
|
||||
|
|
@ -354,6 +409,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Network Scores",
|
||||
},
|
||||
path: "/games/:game/scores",
|
||||
|
|
@ -365,6 +421,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Error",
|
||||
},
|
||||
path: "/:catchAll(.*)",
|
||||
|
|
@ -373,6 +430,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "View Records",
|
||||
},
|
||||
path: "/games/:game/records/:userId",
|
||||
|
|
@ -384,6 +442,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: "Network Records",
|
||||
},
|
||||
path: "/games/:game/records",
|
||||
|
|
@ -395,11 +454,23 @@ const routes = [
|
|||
},
|
||||
{
|
||||
meta: {
|
||||
title: "Error",
|
||||
requiresAuth: true,
|
||||
requiresDev: true,
|
||||
title: "Developer Portal",
|
||||
},
|
||||
path: "/:catchAll(.*)",
|
||||
name: "ErrorPage",
|
||||
component: () => import("@/views/ErrorView.vue"),
|
||||
path: "/developer",
|
||||
name: "Developer Portal",
|
||||
component: () => import("@/views/Developer/PortalView.vue"),
|
||||
},
|
||||
{
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
requiresDev: true,
|
||||
title: "App Registration",
|
||||
},
|
||||
path: "/developer/register",
|
||||
name: "App Registration",
|
||||
component: () => import("@/views/Developer/RegisterView.vue"),
|
||||
},
|
||||
];
|
||||
|
||||
|
|
@ -411,4 +482,48 @@ const router = createRouter({
|
|||
},
|
||||
});
|
||||
|
||||
router.beforeEach(async (to) => {
|
||||
const mainStore = useMainStore();
|
||||
mainStore.errorCode = null;
|
||||
|
||||
if (to.meta.requiresAuth) {
|
||||
const validSession = await mainStore.loadUser();
|
||||
|
||||
if (!validSession) {
|
||||
mainStore.deleteUserSession();
|
||||
|
||||
return {
|
||||
name: "login",
|
||||
query: { redirect: to.fullPath },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (to.meta.requiresAdmin) {
|
||||
const validSession = await mainStore.loadUser();
|
||||
|
||||
if (!validSession || !mainStore.userAdmin) {
|
||||
console.log("You're not an admin!");
|
||||
window.alert("You're not an admin!");
|
||||
return {
|
||||
name: "dashboard",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (to.meta.requiresDev) {
|
||||
const validSession = await mainStore.loadUser();
|
||||
|
||||
if (!validSession || !mainStore.userAdmin) {
|
||||
console.log("You're not a dev!");
|
||||
window.alert("You're not a dev!");
|
||||
return {
|
||||
name: "dashboard",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
|
|
|||
|
|
@ -288,8 +288,9 @@ export async function APIUserReadNews(newsId) {
|
|||
newsId: newsId,
|
||||
});
|
||||
|
||||
mainStore.userLoaded = false;
|
||||
await mainStore.loadUser();
|
||||
const seen_news = await mainStore.userData.seen_news;
|
||||
seen_news[newsId] = true;
|
||||
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.log(`Error saving user!`, error);
|
||||
|
|
|
|||
119
src/views/Auth/AuthorizeView.vue
Normal file
119
src/views/Auth/AuthorizeView.vue
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
<script setup>
|
||||
import { useRouter } from "vue-router";
|
||||
import { reactive } from "vue";
|
||||
import { useMainStore } from "@/stores/main.js";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import LayoutGuest from "@/layouts/LayoutGuest.vue";
|
||||
|
||||
const router = useRouter();
|
||||
const mainStore = useMainStore();
|
||||
|
||||
const form = reactive({
|
||||
spinin: false,
|
||||
});
|
||||
|
||||
const submit = async () => {
|
||||
const response = await mainStore.createUserSession();
|
||||
if (response) {
|
||||
router.push("/");
|
||||
}
|
||||
};
|
||||
|
||||
const appInfo = {
|
||||
name: "Edi",
|
||||
image: "/edi512x512_2.png",
|
||||
manager: "Lumen",
|
||||
about:
|
||||
"Edi is a DDR score tracking app that offers a direct connection to your PhaseII account.",
|
||||
intents: ["user", "account", "webhook_scores"],
|
||||
internal: false,
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LayoutGuest>
|
||||
<div class="flex md:min-h-screen md:items-center md:justify-center">
|
||||
<CardBox
|
||||
class="w-full md:w-auto rounded-none md:rounded-xl md:drop-shadow-xl"
|
||||
:class="form.spinin ? 'animate-spin' : 'animate-none'"
|
||||
has-table
|
||||
is-auth
|
||||
>
|
||||
<div
|
||||
class="p-4 flex flex-col md:flex-row w-full space-y-2 md:space-y-0 md:space-x-4"
|
||||
>
|
||||
<div class="flex flex-col items-center text-wrap h-full md:mt-5">
|
||||
<div class="flex flex-col items-center text-wrap">
|
||||
<img src="/favicon.png" class="rounded-full shadow-lg mb-2" />
|
||||
<h1 class="text-xl"><samp>PhaseII</samp></h1>
|
||||
<button
|
||||
class="text-sm text-gray-700 dark:text-white/75 hover:cursor-pointer"
|
||||
@click="form.spinin = !form.spinin"
|
||||
>
|
||||
Spinnin' since 2021
|
||||
</button>
|
||||
</div>
|
||||
<hr class="border-r my-1 w-full mb-4" />
|
||||
<p class="text-lg relative bottom-0">Authorize App</p>
|
||||
</div>
|
||||
<div class="md:border-r" />
|
||||
<form @submit.prevent="submit()">
|
||||
<div class="flex flex-col items-center text-wrap">
|
||||
<h1 class="text-lg md:text-xl mb-2">
|
||||
Integrate with <span class="font-bold">{{ appInfo.name }}</span>
|
||||
</h1>
|
||||
<img
|
||||
:src="appInfo.image"
|
||||
width="75"
|
||||
class="rounded-full shadow-lg mb-2"
|
||||
/>
|
||||
<p class="text-md max-w-md wrap-break-word text-center">
|
||||
{{ appInfo.about }}
|
||||
</p>
|
||||
|
||||
<hr class="border-r my-2 w-full" />
|
||||
|
||||
<h2 class="text-md md:text-lg">
|
||||
<span class="font-bold">{{ appInfo.name }}</span> will have
|
||||
access to:
|
||||
</h2>
|
||||
<ul class="text-sm md:text-md text-center">
|
||||
<li v-for="intent of appInfo.intents" :v-key="intent">
|
||||
- {{ intent }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2 mt-4">
|
||||
<BaseButton label="Authorize" color="success" type="submit" />
|
||||
</div>
|
||||
<hr class="border-t my-4 w-full" />
|
||||
|
||||
<div class="flex flex-col items-center">
|
||||
<p
|
||||
v-if="!appInfo.internal"
|
||||
class="text-sm max-w-md wrap-break-word text-center mb-2"
|
||||
>
|
||||
Please note that
|
||||
<span class="font-bold">{{ appInfo.name }}</span> is not a
|
||||
<samp>PhaseII</samp> provided service, and that any issues
|
||||
should be directed to the appropriate channels.
|
||||
</p>
|
||||
<p class="text-sm max-w-md wrap-break-word text-center">
|
||||
<span class="font-bold">{{ appInfo.name }}</span> is managed by
|
||||
<span class="font-bold">{{ appInfo.manager }}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<hr class="border-t my-4 w-full" />
|
||||
<div class="flex flex-col gap-2 my-4">
|
||||
<h2>I changed my mind...</h2>
|
||||
<BaseButton label="Go back" color="danger" to="/" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</CardBox>
|
||||
</div>
|
||||
</LayoutGuest>
|
||||
</template>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { useRouter } from "vue-router";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import { PhUser, PhPassword } from "@phosphor-icons/vue";
|
||||
import { reactive } from "vue";
|
||||
import { useMainStore } from "@/stores/main.js";
|
||||
|
|
@ -11,7 +11,9 @@ import BaseButton from "@/components/BaseButton.vue";
|
|||
import LayoutGuest from "@/layouts/LayoutGuest.vue";
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const mainStore = useMainStore();
|
||||
const redirectPath = route.query.redirect || "/";
|
||||
|
||||
// Reactive form data
|
||||
const form = reactive({
|
||||
|
|
@ -33,7 +35,7 @@ const submit = async () => {
|
|||
form.remember,
|
||||
);
|
||||
if (response) {
|
||||
router.push("/");
|
||||
router.push(redirectPath);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
97
src/views/Developer/PortalView.vue
Normal file
97
src/views/Developer/PortalView.vue
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
<script setup>
|
||||
import { ref, onMounted, reactive } from "vue";
|
||||
import { PhCloud, PhCode } from "@phosphor-icons/vue";
|
||||
import { dashCode } from "@/constants/userData.js";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import UserCard from "@/components/UserCard.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import FormField from "@/components/FormField.vue";
|
||||
import FormControl from "@/components/FormControl.vue";
|
||||
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
|
||||
import SectionTitleLine from "@/components/SectionTitleLine.vue";
|
||||
const DOCS_URL = import.meta.env.VITE_DOCS_URL;
|
||||
|
||||
const copyToClipboard = (text) => {
|
||||
navigator.clipboard
|
||||
.writeText(text)
|
||||
.then(() => {
|
||||
alert("Copied to clipboard!");
|
||||
})
|
||||
.catch(() => {
|
||||
alert("Failed to copy to clipboard!");
|
||||
});
|
||||
};
|
||||
|
||||
const appInfo = {
|
||||
name: "Edi",
|
||||
image: "/edi512x512_2.png",
|
||||
manager: "Lumen",
|
||||
about:
|
||||
"Edi is a DDR score tracking app that offers a direct connection to your PhaseII account.",
|
||||
intents: ["user", "account", "webhook_scores"],
|
||||
webhooks: ["scores"],
|
||||
useOAuth: true,
|
||||
internal: false,
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LayoutAuthenticated>
|
||||
<SectionMain>
|
||||
<UserCard class="mb-6" use-small even-smaller />
|
||||
|
||||
<SectionTitleLine :icon="PhCode" title="Developer Portal" main />
|
||||
<CardBox class="row-span-2 mb-6">
|
||||
<h1 class="text-xl md:text-2xl">
|
||||
Welcome to the <samp>PhaseII</samp> Developer Portal!
|
||||
</h1>
|
||||
<h2 class="text-lg">You're gonna do great 😄</h2>
|
||||
|
||||
<p>
|
||||
If you're just now getting started, please read the
|
||||
<a
|
||||
class="text-blue-400 hover:text-blue-600"
|
||||
:href="`${DOCS_URL}/developer`"
|
||||
target="_blank"
|
||||
>
|
||||
developer docs
|
||||
</a>
|
||||
</p>
|
||||
<hr class="border-r my-2 w-full" />
|
||||
<p>Create or manage your applications below</p>
|
||||
</CardBox>
|
||||
|
||||
<SectionTitleLine :icon="PhCloud" title="My Applications" main>
|
||||
<BaseButton
|
||||
label="Add Application"
|
||||
color="success"
|
||||
to="/developer/register"
|
||||
/>
|
||||
</SectionTitleLine>
|
||||
<CardBox class="row-span-2 mb-6">
|
||||
<div class="flex">
|
||||
<div
|
||||
class="flex flex-col justify-center p-4 rounded-xl bg-slate-700 hover:drop-shadow-xl transition-all"
|
||||
>
|
||||
<div class="w-full flex justify-center">
|
||||
<img
|
||||
:src="appInfo.image"
|
||||
width="75"
|
||||
class="rounded-full shadow-lg mb-2"
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-2 text-center">
|
||||
<h1 class="text-lg md:text-xl font-bold">
|
||||
{{ appInfo.name }}
|
||||
</h1>
|
||||
<h2 v-if="appInfo.useOAuth">OAuth Enabled</h2>
|
||||
<h2>{{ appInfo.webhooks?.length || 0 }} Webhook(s)</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardBox>
|
||||
</SectionMain>
|
||||
</LayoutAuthenticated>
|
||||
</template>
|
||||
344
src/views/Developer/RegisterView.vue
Normal file
344
src/views/Developer/RegisterView.vue
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
<script setup>
|
||||
import { reactive } from "vue";
|
||||
import {
|
||||
PhCloudArrowUp,
|
||||
PhFileImage,
|
||||
PhKey,
|
||||
PhLinkSimple,
|
||||
PhStorefront,
|
||||
PhTextbox,
|
||||
PhWebhooksLogo,
|
||||
} from "@phosphor-icons/vue";
|
||||
import SectionMain from "@/components/SectionMain.vue";
|
||||
import UserCard from "@/components/UserCard.vue";
|
||||
import PillTag from "@/components/PillTag.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import FormField from "@/components/FormField.vue";
|
||||
import FormCheckRadio from "@/components/FormCheckRadio.vue";
|
||||
import FormFilePicker from "@/components/FormFilePicker.vue";
|
||||
import FormControl from "@/components/FormControl.vue";
|
||||
import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue";
|
||||
import SectionTitleLine from "@/components/SectionTitleLine.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import { useMainStore } from "@/stores/main";
|
||||
import { applicationIntents, applicationWebhooks } from "@/constants/developer";
|
||||
|
||||
const mainStore = useMainStore();
|
||||
|
||||
const appForm = reactive({
|
||||
name: "",
|
||||
about: "",
|
||||
image: null,
|
||||
useOAuth: false,
|
||||
callbackUri: null,
|
||||
intents: [],
|
||||
useWebhooks: false,
|
||||
webhookList: [],
|
||||
});
|
||||
|
||||
const initWebhook = {
|
||||
type: "network.news",
|
||||
name: "",
|
||||
endpoint: "",
|
||||
authKey: "",
|
||||
fields: {},
|
||||
};
|
||||
|
||||
const newWebhook = reactive({
|
||||
...initWebhook,
|
||||
});
|
||||
|
||||
const sortedArcades = mainStore.userArcades.map((arcade) => ({
|
||||
label: arcade.name,
|
||||
id: arcade.id,
|
||||
}));
|
||||
|
||||
function isValidUrl(value, { requireHttps = true } = {}) {
|
||||
if (!value || typeof value !== "string") return false;
|
||||
|
||||
try {
|
||||
const url = new URL(value);
|
||||
|
||||
if (!["http:", "https:"].includes(url.protocol)) return false;
|
||||
if (requireHttps && url.protocol !== "https:") return false;
|
||||
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function isValidAuthKey(key) {
|
||||
return typeof key === "string" && key.length >= 40;
|
||||
}
|
||||
|
||||
async function addWebhook() {
|
||||
const tmpWebhook = JSON.parse(
|
||||
JSON.stringify({
|
||||
type: newWebhook.type,
|
||||
name: newWebhook.name,
|
||||
endpoint: newWebhook.endpoint,
|
||||
authKey: newWebhook.authKey,
|
||||
fields: newWebhook.fields,
|
||||
}),
|
||||
);
|
||||
|
||||
if (!tmpWebhook.name?.trim()) {
|
||||
return alert("Webhook name is required.");
|
||||
}
|
||||
if (!isValidUrl(tmpWebhook.endpoint)) {
|
||||
return alert("Webhook endpoint must be a valid HTTPS URL.");
|
||||
}
|
||||
if (!isValidAuthKey(tmpWebhook.authKey)) {
|
||||
return alert("Auth key must be at least 40 characters.");
|
||||
}
|
||||
|
||||
const webhookMeta = applicationWebhooks.find((w) => w.id === tmpWebhook.type);
|
||||
if (webhookMeta?.fields?.includes("arcadeId")) {
|
||||
if (!tmpWebhook.fields.arcadeId) {
|
||||
return alert("Arcade selection is required.");
|
||||
}
|
||||
} else {
|
||||
tmpWebhook.fields = {};
|
||||
}
|
||||
|
||||
appForm.webhookList.push(tmpWebhook);
|
||||
Object.assign(newWebhook, initWebhook);
|
||||
}
|
||||
|
||||
function removeWebhook(authKey) {
|
||||
appForm.webhookList = appForm.webhookList.filter(
|
||||
(webhook) => webhook.authKey !== authKey,
|
||||
);
|
||||
}
|
||||
|
||||
async function requestApp() {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LayoutAuthenticated>
|
||||
<SectionMain>
|
||||
<UserCard class="mb-6" use-small even-smaller />
|
||||
|
||||
<SectionTitleLine
|
||||
:icon="PhCloudArrowUp"
|
||||
title="Create an Application"
|
||||
main
|
||||
/>
|
||||
<CardBox class="row-span-2 mb-6">
|
||||
<PillTag color="info" label="General" class="mb-2" />
|
||||
<FormField label="Name">
|
||||
<FormControl
|
||||
v-model="appForm.name"
|
||||
:icon="PhTextbox"
|
||||
name="name"
|
||||
required
|
||||
/>
|
||||
</FormField>
|
||||
<FormField label="About">
|
||||
<FormControl
|
||||
v-model="appForm.about"
|
||||
name="about"
|
||||
type="textarea"
|
||||
required
|
||||
/>
|
||||
</FormField>
|
||||
<FormField label="App Logo">
|
||||
<FormFilePicker
|
||||
v-model="appForm.image"
|
||||
label="Image Upload"
|
||||
accept="image/*"
|
||||
:icon="PhFileImage"
|
||||
/>
|
||||
</FormField>
|
||||
</CardBox>
|
||||
<CardBox class="row-span-2 mb-6">
|
||||
<PillTag color="warning" label="OAuth2.0" class="mb-2" />
|
||||
<FormField label="Enable OAuth">
|
||||
<FormCheckRadio
|
||||
v-model="appForm.useOAuth"
|
||||
name="useOAuth"
|
||||
:model-value="appForm.useOAuth"
|
||||
:input-value="appForm.useOAuth"
|
||||
type="switch"
|
||||
/>
|
||||
</FormField>
|
||||
<template v-if="appForm.useOAuth">
|
||||
<FormField
|
||||
label="Callback URI"
|
||||
help="The URL that the user will be redirected to from the authorization page (ex: input of https://mycoolapp.my.domain/callback/url will redirect user to https://address/callback/url?code= )"
|
||||
>
|
||||
<FormControl
|
||||
v-model="appForm.callbackUri"
|
||||
:icon="PhLinkSimple"
|
||||
name="callbackUri"
|
||||
placeholder="https://my.domain/callback/url"
|
||||
required
|
||||
/>
|
||||
</FormField>
|
||||
<FormField
|
||||
label="Intents"
|
||||
help="Select what you'd like your app to do"
|
||||
>
|
||||
<template v-for="intent in applicationIntents" :key="intent.id">
|
||||
<div class="grid md:flex justify-between">
|
||||
<FormCheckRadio
|
||||
v-model="appForm.intents"
|
||||
:name="'intents'"
|
||||
:label="intent.label"
|
||||
:input-value="intent.id"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
class="text-slate-400 hover:text-slate-200 font-thin transition-all delay-0"
|
||||
>
|
||||
{{ intent.tip ?? "" }}
|
||||
</span>
|
||||
</div>
|
||||
<hr class="border-r my-3 w-full" />
|
||||
</template>
|
||||
</FormField>
|
||||
</template>
|
||||
</CardBox>
|
||||
<CardBox class="row-span-2 mb-6">
|
||||
<PillTag color="success" label="Webhooks" class="mb-2" />
|
||||
<FormField
|
||||
label="Enable Application Webhooks"
|
||||
help="These are different from user webhooks!"
|
||||
>
|
||||
<FormCheckRadio
|
||||
v-model="appForm.useWebhooks"
|
||||
name="useWebhooks"
|
||||
:model-value="appForm.useWebhooks"
|
||||
:input-value="appForm.useWebhooks"
|
||||
type="switch"
|
||||
/>
|
||||
</FormField>
|
||||
<template v-if="appForm.useWebhooks">
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<form class="h-full" @submit.prevent="addWebhook()">
|
||||
<PillTag color="info" label="New Webhook" class="mb-4" />
|
||||
<FormField
|
||||
label="Webhook Type"
|
||||
:help="
|
||||
applicationWebhooks.find(
|
||||
(webhook) => webhook.id === newWebhook.type,
|
||||
)?.tip
|
||||
"
|
||||
>
|
||||
<FormControl
|
||||
v-model="newWebhook.type"
|
||||
name="type"
|
||||
:icon="PhWebhooksLogo"
|
||||
:options="applicationWebhooks"
|
||||
required
|
||||
/>
|
||||
</FormField>
|
||||
<FormField label="Name">
|
||||
<FormControl
|
||||
v-model="newWebhook.name"
|
||||
name="name"
|
||||
:icon="PhTextbox"
|
||||
required
|
||||
/>
|
||||
</FormField>
|
||||
<FormField
|
||||
label="API Endpoint"
|
||||
help="The URL that the Webhook server will contact"
|
||||
>
|
||||
<FormControl
|
||||
v-model="newWebhook.endpoint"
|
||||
name="name"
|
||||
placeholder="https://my.domain/endpoint/url"
|
||||
:icon="PhLinkSimple"
|
||||
required
|
||||
/>
|
||||
</FormField>
|
||||
<FormField
|
||||
label="API Auth Key"
|
||||
help="Sent as headers x-api-key, x-webhook-key, authorization"
|
||||
>
|
||||
<FormControl
|
||||
v-model="newWebhook.authKey"
|
||||
name="authKey"
|
||||
:icon="PhKey"
|
||||
required
|
||||
:minlength="40"
|
||||
/>
|
||||
</FormField>
|
||||
<template
|
||||
v-for="field of applicationWebhooks.find(
|
||||
(webhookData) => webhookData.id === newWebhook.type,
|
||||
)?.fields"
|
||||
>
|
||||
<template v-if="field === 'arcadeId'">
|
||||
<FormField
|
||||
label="Arcade"
|
||||
help="The arcade that this Webhook will track"
|
||||
>
|
||||
<FormControl
|
||||
v-model="newWebhook.fields.arcadeId"
|
||||
name="arcadeId"
|
||||
:icon="PhStorefront"
|
||||
:options="sortedArcades"
|
||||
required
|
||||
/>
|
||||
</FormField>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<BaseButton color="success" type="submit" label="Add Webhook" />
|
||||
</form>
|
||||
|
||||
<div>
|
||||
<PillTag color="warning" label="Queue" class="mb-4" />
|
||||
<div class="grid gap-4">
|
||||
<CardBox
|
||||
v-for="webhook of appForm.webhookList"
|
||||
:key="webhook.type"
|
||||
color-prop="bg-slate-800 dark:bg-slate-800"
|
||||
>
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="m-[-5px]">
|
||||
<PillTag
|
||||
color="info"
|
||||
:label="webhook.type"
|
||||
class="mb-4"
|
||||
small
|
||||
/>
|
||||
<h1 class="text-md font-bold">{{ webhook.name }}</h1>
|
||||
<samp
|
||||
class="text-sm font-mono p-1 bg-slate-900 rounded-lg"
|
||||
>
|
||||
{{ webhook.endpoint }}
|
||||
</samp>
|
||||
<h2
|
||||
v-for="(value, field) of webhook.fields"
|
||||
class="text-sm font-mono mt-2"
|
||||
>
|
||||
{{ field }}: {{ value }}
|
||||
</h2>
|
||||
</div>
|
||||
<BaseButton
|
||||
color="danger"
|
||||
label="Remove"
|
||||
@click="removeWebhook(webhook.authKey)"
|
||||
/>
|
||||
</div>
|
||||
</CardBox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</CardBox>
|
||||
<BaseButton
|
||||
:small="false"
|
||||
label="Submit"
|
||||
color="success"
|
||||
@click="console.log(appForm)"
|
||||
/>
|
||||
</SectionMain>
|
||||
</LayoutAuthenticated>
|
||||
</template>
|
||||
|
|
@ -20,9 +20,7 @@ import { getGameInfo } from "@/constants";
|
|||
import { dashCode } from "@/constants/userData";
|
||||
import { getIIDXDan } from "@/constants/danClass";
|
||||
import { formatSortableDate } from "@/constants/date";
|
||||
import { useMainStore } from "@/stores/main";
|
||||
|
||||
const mainStore = useMainStore();
|
||||
const $route = useRoute();
|
||||
const $router = useRouter();
|
||||
var gameID = null;
|
||||
|
|
@ -44,15 +42,9 @@ const versionForm = reactive({
|
|||
watch(
|
||||
() => versionForm.currentVersion,
|
||||
() => {
|
||||
mainStore.continueLoad = true;
|
||||
mainStore.isLoading = true;
|
||||
mainStore.activeRequests = 1;
|
||||
loadGame(versionForm.currentVersion, profiles.length != 0);
|
||||
loadProfile();
|
||||
musicIds.value = [];
|
||||
mainStore.continueLoad = false;
|
||||
mainStore.isLoading = false;
|
||||
mainStore.activeRequests = 0;
|
||||
},
|
||||
);
|
||||
|
||||
|
|
@ -69,12 +61,8 @@ if (thisGame == null) {
|
|||
}
|
||||
|
||||
onMounted(async () => {
|
||||
mainStore.continueLoad = true;
|
||||
await loadProfile();
|
||||
await loadGame(null, profiles.length == 0);
|
||||
mainStore.continueLoad = false;
|
||||
mainStore.isLoading = false;
|
||||
mainStore.activeRequests = 0;
|
||||
});
|
||||
|
||||
async function loadGame(version, noUsers) {
|
||||
|
|
|
|||
|
|
@ -147,6 +147,18 @@ async function revert() {
|
|||
/>
|
||||
</FormField>
|
||||
|
||||
<FormField
|
||||
label="Hide QuickLinks"
|
||||
help="Turns off the buttons in the navbar"
|
||||
>
|
||||
<FormCheckRadio
|
||||
v-model="userCustomize.hideQuickLinks"
|
||||
type="switch"
|
||||
:input-value="userCustomize.hideQuickLinks ?? false"
|
||||
name="hideQuickLinks"
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<div class="space-x-2">
|
||||
<BaseButton type="submit" color="success" label="Save" />
|
||||
<BaseButton
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user