diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000000..5008ddfcf5
Binary files /dev/null and b/.DS_Store differ
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index db0fad50b9..59fa424f05 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -21,6 +21,7 @@
"@types/react": "^18.3.6",
"@types/react-dom": "^18.3.0",
"axios": "^1.7.7",
+ "beautify": "^0.0.8",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.26.2",
@@ -3662,6 +3663,12 @@
"node": ">= 8"
}
},
+ "node_modules/@one-ini/wasm": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz",
+ "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==",
+ "license": "MIT"
+ },
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -4336,9 +4343,21 @@
}
},
"node_modules/@types/express-serve-static-core": {
- "version": "4.19.5",
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz",
- "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.0.tgz",
+ "integrity": "sha512-AbXMTZGt40T+KON9/Fdxx0B2WK5hsgxcfXJLr5bFpZ7b4JCex2WyQPTEKdXqfHiY5nKKBScZ7yCoO6Pvgxfvnw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*",
+ "@types/send": "*"
+ }
+ },
+ "node_modules/@types/express/node_modules/@types/express-serve-static-core": {
+ "version": "4.19.6",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz",
+ "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==",
"license": "MIT",
"dependencies": {
"@types/node": "*",
@@ -5013,6 +5032,15 @@
"deprecated": "Use your platform's native atob() and btoa() methods instead",
"license": "BSD-3-Clause"
},
+ "node_modules/abbrev": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz",
+ "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==",
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@@ -5848,6 +5876,20 @@
"integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==",
"license": "MIT"
},
+ "node_modules/beautify": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/beautify/-/beautify-0.0.8.tgz",
+ "integrity": "sha512-1iF6Ey2qxDkm6bPgKcoXUmwFDpoRi5IgwefQDDQBRLxlZAAYwcULoQ2IdBArXZuSsuL7AT+KvZI9xZVLeUZPRg==",
+ "license": "MIT",
+ "dependencies": {
+ "cssbeautify": "^0.3.1",
+ "html": "^1.0.0",
+ "js-beautify": "^1.6.4"
+ },
+ "bin": {
+ "beautify": "bin/beautify.js"
+ }
+ },
"node_modules/bfj": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/bfj/-/bfj-7.1.0.tgz",
@@ -6513,18 +6555,37 @@
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"license": "MIT"
},
- "node_modules/compression/node_modules/safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "license": "MIT"
- },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"license": "MIT"
},
+ "node_modules/concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "engines": [
+ "node >= 0.8"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "node_modules/config-chain": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
+ "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ini": "^1.3.4",
+ "proto-list": "~1.2.1"
+ }
+ },
"node_modules/confusing-browser-globals": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz",
@@ -6552,6 +6613,26 @@
"node": ">= 0.6"
}
},
+ "node_modules/content-disposition/node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/content-type": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
@@ -6869,6 +6950,17 @@
"integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==",
"license": "MIT"
},
+ "node_modules/cssbeautify": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/cssbeautify/-/cssbeautify-0.3.1.tgz",
+ "integrity": "sha512-ljnSOCOiMbklF+dwPbpooyB78foId02vUrTDogWzu6ca2DCNB7Kc/BHEGBnYOlUYtwXvSW0mWTwaiO2pwFIoRg==",
+ "bin": {
+ "cssbeautify": "bin/cssbeautify"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/cssdb": {
"version": "7.11.2",
"resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.11.2.tgz",
@@ -7525,6 +7617,57 @@
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"license": "MIT"
},
+ "node_modules/editorconfig": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz",
+ "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@one-ini/wasm": "0.1.1",
+ "commander": "^10.0.0",
+ "minimatch": "9.0.1",
+ "semver": "^7.5.3"
+ },
+ "bin": {
+ "editorconfig": "bin/editorconfig"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/editorconfig/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/editorconfig/node_modules/commander": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/editorconfig/node_modules/minimatch": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
+ "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -7993,9 +8136,9 @@
}
},
"node_modules/eslint-module-utils": {
- "version": "2.11.0",
- "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.11.0.tgz",
- "integrity": "sha512-gbBE5Hitek/oG6MUVj6sFuzEjA/ClzNflVrLovHi/JgLdC7fiN5gLAY1WIPW1a0V5I999MnsrvVrCOGmmVqDBQ==",
+ "version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz",
+ "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==",
"license": "MIT",
"dependencies": {
"debug": "^3.2.7"
@@ -8162,9 +8305,9 @@
}
},
"node_modules/eslint-plugin-react": {
- "version": "7.36.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.36.1.tgz",
- "integrity": "sha512-/qwbqNXZoq+VP30s1d4Nc1C5GTxjJQjk4Jzs4Wq2qzxFM7dSmuG2UkIjg2USMLh3A/aVcUNrK7v0J5U1XEGGwA==",
+ "version": "7.37.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.1.tgz",
+ "integrity": "sha512-xwTnwDqzbDRA8uJ7BMxPs/EXRB3i8ZfnOIp8BsxEQkT0nHPp+WWceqGgo6rKb9ctNi8GJLDT4Go5HAWELa/WMg==",
"license": "MIT",
"dependencies": {
"array-includes": "^3.1.8",
@@ -8572,6 +8715,26 @@
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"license": "MIT"
},
+ "node_modules/express/node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -8619,9 +8782,9 @@
"license": "MIT"
},
"node_modules/fast-uri": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz",
- "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.2.tgz",
+ "integrity": "sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==",
"license": "MIT"
},
"node_modules/fastq": {
@@ -9502,40 +9665,16 @@
"wbuf": "^1.1.0"
}
},
- "node_modules/hpack.js/node_modules/isarray": {
+ "node_modules/html": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
- "license": "MIT"
- },
- "node_modules/hpack.js/node_modules/readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "license": "MIT",
- "dependencies": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "node_modules/hpack.js/node_modules/safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "license": "MIT"
- },
- "node_modules/hpack.js/node_modules/string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/html/-/html-1.0.0.tgz",
+ "integrity": "sha512-lw/7YsdKiP3kk5PnR1INY17iJuzdAtJewxr14ozKJWbbR97znovZ0mh+WEMZ8rjc3lgTK+ID/htTjuyGKB52Kw==",
+ "license": "BSD",
"dependencies": {
- "safe-buffer": "~5.1.0"
+ "concat-stream": "^1.4.7"
+ },
+ "bin": {
+ "html": "bin/html.js"
}
},
"node_modules/html-encoding-sniffer": {
@@ -11481,6 +11620,80 @@
"jiti": "bin/jiti.js"
}
},
+ "node_modules/js-beautify": {
+ "version": "1.15.1",
+ "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.1.tgz",
+ "integrity": "sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==",
+ "license": "MIT",
+ "dependencies": {
+ "config-chain": "^1.1.13",
+ "editorconfig": "^1.0.4",
+ "glob": "^10.3.3",
+ "js-cookie": "^3.0.5",
+ "nopt": "^7.2.0"
+ },
+ "bin": {
+ "css-beautify": "js/bin/css-beautify.js",
+ "html-beautify": "js/bin/html-beautify.js",
+ "js-beautify": "js/bin/js-beautify.js"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/js-beautify/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/js-beautify/node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/js-beautify/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/js-cookie": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
+ "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -12212,6 +12425,21 @@
"integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
"license": "MIT"
},
+ "node_modules/nopt": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz",
+ "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==",
+ "license": "ISC",
+ "dependencies": {
+ "abbrev": "^2.0.0"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -12267,9 +12495,9 @@
}
},
"node_modules/nwsapi": {
- "version": "2.2.12",
- "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz",
- "integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==",
+ "version": "2.2.13",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.13.tgz",
+ "integrity": "sha512-cTGB9ptp9dY9A5VbMSe7fQBcl/tt22Vcqdq8+eN93rblOuE0aCFu4aZ2vMwct/2t+lFnosm8RkQW1I0Omb1UtQ==",
"license": "MIT"
},
"node_modules/object-assign": {
@@ -14296,6 +14524,12 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"license": "MIT"
},
+ "node_modules/proto-list": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==",
+ "license": "ISC"
+ },
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -14698,19 +14932,26 @@
}
},
"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==",
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"license": "MIT",
"dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- },
- "engines": {
- "node": ">= 6"
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
}
},
+ "node_modules/readable-stream/node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "license": "MIT"
+ },
"node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -15058,9 +15299,9 @@
}
},
"node_modules/rollup": {
- "version": "2.79.1",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
- "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
+ "version": "2.79.2",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz",
+ "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
"license": "MIT",
"bin": {
"rollup": "dist/bin/rollup"
@@ -15153,23 +15394,9 @@
}
},
"node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"license": "MIT"
},
"node_modules/safe-regex-test": {
@@ -15764,6 +15991,20 @@
"wbuf": "^1.7.3"
}
},
+ "node_modules/spdy-transport/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==",
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -15926,12 +16167,12 @@
}
},
"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==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"license": "MIT",
"dependencies": {
- "safe-buffer": "~5.2.0"
+ "safe-buffer": "~5.1.0"
}
},
"node_modules/string-length": {
@@ -16522,9 +16763,9 @@
"license": "MIT"
},
"node_modules/tailwindcss": {
- "version": "3.4.12",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.12.tgz",
- "integrity": "sha512-Htf/gHj2+soPb9UayUNci/Ja3d8pTmu9ONTfh4QY8r3MATTZOzmv6UYWF7ZwikEIC8okpfqmGqrmDehua8mF8w==",
+ "version": "3.4.13",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.13.tgz",
+ "integrity": "sha512-KqjHOJKogOUt5Bs752ykCeiwvi0fKVkr5oqsFNt/8px/tA8scFPIlkygsf6jXrfCqGHz7VflA6+yytWuM+XhFw==",
"license": "MIT",
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
@@ -16623,9 +16864,9 @@
}
},
"node_modules/terser": {
- "version": "5.33.0",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.33.0.tgz",
- "integrity": "sha512-JuPVaB7s1gdFKPKTelwUyRq5Sid2A3Gko2S0PncwdBq7kN9Ti9HPWDQ06MPsEDGsZeVESjKEnyGy68quBk1w6g==",
+ "version": "5.34.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.34.1.tgz",
+ "integrity": "sha512-FsJZ7iZLd/BXkz+4xrRTGJ26o/6VTjQytUk8b8OxkwcD2I+79VPJlz7qss1+zE7h8GNIScFqXcDyJ/KqBYZFVA==",
"license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
@@ -17014,6 +17255,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
+ "license": "MIT"
+ },
"node_modules/typedarray-to-buffer": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
@@ -17329,9 +17576,9 @@
}
},
"node_modules/webpack": {
- "version": "5.94.0",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz",
- "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==",
+ "version": "5.95.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz",
+ "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==",
"license": "MIT",
"dependencies": {
"@types/estree": "^1.0.5",
diff --git a/frontend/package.json b/frontend/package.json
index 42c19ba67c..0200783247 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -16,6 +16,7 @@
"@types/react": "^18.3.6",
"@types/react-dom": "^18.3.0",
"axios": "^1.7.7",
+ "beautify": "^0.0.8",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.26.2",
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 768083fe6d..310bb908c9 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -3,6 +3,8 @@ import "@fontsource/lexend";
import { ReactElement } from "react";
import { Route, Routes } from "react-router-dom";
import Home from "./pages/Home/Home";
+import SignUp from "./pages/SignUp/SignUp";
+import Login from "./pages/Login/Login";
//import QuestionList from "./pages/QuestionList/QuestionList";
import { createTheme, ThemeProvider } from "@mui/material";
import { MainDialogContextProvider } from "./contexts/MainDialogContext";
@@ -62,6 +64,8 @@ const App = (): ReactElement => {
} />
+ } />
+ } />
{/* } /> */}
diff --git a/frontend/src/components/Navbar/Navbar.scss b/frontend/src/components/Navbar/Navbar.scss
index a1831e89bb..76951cd53a 100644
--- a/frontend/src/components/Navbar/Navbar.scss
+++ b/frontend/src/components/Navbar/Navbar.scss
@@ -1,4 +1,5 @@
.Navbar {
+ width: 90%;
display: flex;
padding: 20px 34px;
justify-content: space-between;
diff --git a/frontend/src/components/Navbar/Navbar.tsx b/frontend/src/components/Navbar/Navbar.tsx
index f221cf89a1..77d4c3357c 100644
--- a/frontend/src/components/Navbar/Navbar.tsx
+++ b/frontend/src/components/Navbar/Navbar.tsx
@@ -1,16 +1,20 @@
import { Box, Button, Typography } from "@mui/material";
import { ReactElement } from "react";
+import { useNavigate } from "react-router-dom"; // Import useNavigate for navigation
import "./Navbar.scss";
import ApiIcon from "@mui/icons-material/Api";
import { useMainDialog } from "../../contexts/MainDialogContext";
const Navbar = (): ReactElement => {
const { openMainDialog, setMainDialogTitle, setMainDialogContent } = useMainDialog();
+ const navigate = useNavigate();
- const login = () => {
- setMainDialogTitle("Work in Progress");
- setMainDialogContent("User service is under construction. Check back in a future milestone!");
- openMainDialog();
+ const redirectToSignUp = () => {
+ navigate("/signup");
+ };
+
+ const redirectToLogin = () => {
+ navigate("/login");
};
return (
@@ -20,10 +24,10 @@ const Navbar = (): ReactElement => {
LuckyJinx
-
diff --git a/frontend/src/pages/Home/Home.tsx b/frontend/src/pages/Home/Home.tsx
index e3357aa7ef..e85ad2e1b3 100644
--- a/frontend/src/pages/Home/Home.tsx
+++ b/frontend/src/pages/Home/Home.tsx
@@ -8,12 +8,6 @@ import Footer from "../../components/Footer/Footer";
import QuestionList from "../../components/QuestionList/QuestionList";
const Home = (): ReactElement => {
- // const navigate = useNavigate();
-
- // const goToQuestionList = () => {
- // navigate("/questions");
- // };
-
return (
diff --git a/frontend/src/pages/Login/Login.scss b/frontend/src/pages/Login/Login.scss
new file mode 100644
index 0000000000..1c455fc25d
--- /dev/null
+++ b/frontend/src/pages/Login/Login.scss
@@ -0,0 +1,150 @@
+.Login {
+ background: var(--Grey-10, #1a1a1a);
+ min-height: 100vh;
+ padding: 40px 80px;
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+ align-items: center;
+
+ &-container {
+ padding-block: 40px;
+ width: 100%;
+ max-width: 1000px;
+ background: var(--Grey-20, #252525);
+ border-radius: 10px;
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ }
+
+ &-title {
+ font-size: 2.5rem;
+ font-weight: 700;
+ color: #d4ff50;
+ margin-bottom: 40px;
+ }
+
+ &-subtitle {
+ font-size: 1rem;
+ font-weight: 300;
+ color: #b5b5b5;
+ text-align: center;
+ margin-bottom: 40px;
+ }
+
+ &-form {
+ width: 100%;
+ max-width: 900px;
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 40px;
+ align-items: center;
+
+ .MuiTextField-root {
+ background-color: #333;
+ border-radius: 50px;
+ padding: 10px 15px;
+
+ .MuiOutlinedInput-notchedOutline {
+ border-color: #555;
+ border-radius: 50px;
+ }
+
+ .MuiInputLabel-root {
+ color: #999;
+ }
+ }
+
+ .SignUp-password {
+ position: relative;
+
+ .password-eye-icon {
+ position: absolute;
+ top: 50%;
+ right: 10px;
+ transform: translateY(-50%);
+ cursor: pointer;
+ color: #999;
+ }
+ }
+ }
+
+ &-button {
+ grid-column: span 2;
+ background-color: #d4ff50;
+ color: black;
+ padding: 10px 20px;
+ border-radius: 5px;
+ font-size: 1.2rem;
+ text-transform: none;
+ margin-top: 20px;
+
+ &:hover {
+ background-color: #c3ff40;
+ }
+ }
+
+ &-signup {
+ grid-column: span 2;
+ color: #e4e4e7;
+ margin-top: 20px;
+ font-size: 0.9rem;
+ text-align: center;
+
+ a {
+ color: #d4ff50;
+ text-decoration: none;
+ font-weight: 500;
+
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+ }
+
+ &-or {
+ grid-column: span 2;
+ color: #999;
+ font-size: 0.85rem;
+ margin: 20px 0;
+ }
+
+ &-social {
+ grid-column: span 2;
+ display: flex;
+ justify-content: center;
+ gap: 1.5rem;
+
+ .SignUp-social-button {
+ width: 50px;
+ height: 50px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 50%;
+ background-color: #333;
+ cursor: pointer;
+ transition: background-color 0.3s;
+
+ &:hover {
+ background-color: #444;
+ }
+
+ img {
+ width: 30px;
+ height: 30px;
+ }
+ }
+ }
+}
+
+.forgot-password {
+ color: #3f51b5;
+ cursor: pointer;
+
+ &:hover {
+ text-decoration: underline;
+ }
+}
diff --git a/frontend/src/pages/Login/Login.tsx b/frontend/src/pages/Login/Login.tsx
new file mode 100644
index 0000000000..7c56b52697
--- /dev/null
+++ b/frontend/src/pages/Login/Login.tsx
@@ -0,0 +1,73 @@
+import { ReactElement, useState } from "react";
+import { Box, Button, Typography, TextField, IconButton, InputAdornment } from "@mui/material";
+import Navbar from "../../components/Navbar/Navbar";
+import Footer from "../../components/Footer/Footer";
+import Visibility from "@mui/icons-material/Visibility";
+import VisibilityOff from "@mui/icons-material/VisibilityOff";
+import "./Login.scss";
+
+const Login = (): ReactElement => {
+ const [showPassword, setShowPassword] = useState(false);
+
+ const togglePasswordVisibility = () => {
+ setShowPassword((prev) => !prev);
+ };
+
+ return (
+
+
+
+
+
+ Login
+
+
+ Welcome back! Please log in to access your account.
+
+
+
+
+
+
+
+ {showPassword ? : }
+
+
+ ),
+ }}
+ />
+
+
+ Forgot password?
+
+
+
+ Login
+
+
+
+ Not registered yet? Sign Up
+
+
+ {/* Or Continue with */}
+
+
+
+
+
+ );
+};
+
+export default Login;
diff --git a/frontend/src/pages/SignUp/SignUp.scss b/frontend/src/pages/SignUp/SignUp.scss
new file mode 100644
index 0000000000..ffae9665f0
--- /dev/null
+++ b/frontend/src/pages/SignUp/SignUp.scss
@@ -0,0 +1,141 @@
+.SignUp {
+ background: var(--Grey-10, #1a1a1a);
+ min-height: 100vh;
+ padding: 40px 80px;
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+ align-items: center;
+
+ &-container {
+ padding-block: 40px;
+ width: 100%;
+ max-width: 1000px;
+ background: var(--Grey-20, #252525);
+ border-radius: 10px;
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ }
+
+ &-title {
+ font-size: 2.5rem;
+ font-weight: 700;
+ color: #d4ff50;
+ margin-bottom: 40px;
+ }
+
+ &-subtitle {
+ font-size: 1rem;
+ font-weight: 300;
+ color: #b5b5b5;
+ text-align: center;
+ margin-bottom: 40px;
+ }
+
+ &-form {
+ width: 100%;
+ max-width: 900px;
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 40px;
+ align-items: center;
+
+ .MuiTextField-root {
+ background-color: #333;
+ border-radius: 50px;
+ padding: 10px 15px;
+
+ .MuiOutlinedInput-notchedOutline {
+ border-color: #555;
+ border-radius: 50px;
+ }
+
+ .MuiInputLabel-root {
+ color: #999;
+ }
+ }
+
+ .SignUp-password {
+ position: relative;
+
+ .password-eye-icon {
+ position: absolute;
+ top: 50%;
+ right: 10px;
+ transform: translateY(-50%);
+ cursor: pointer;
+ color: #999;
+ }
+ }
+ }
+
+ &-button {
+ grid-column: span 2;
+ background-color: #d4ff50;
+ color: black;
+ padding: 10px 20px;
+ border-radius: 5px;
+ font-size: 1.2rem;
+ text-transform: none;
+ margin-top: 20px;
+
+ &:hover {
+ background-color: #c3ff40;
+ }
+ }
+
+ &-login {
+ grid-column: span 2;
+ color: #e4e4e7;
+ margin-top: 20px;
+ font-size: 0.9rem;
+ text-align: center;
+
+ a {
+ color: #d4ff50;
+ text-decoration: none;
+ font-weight: 500;
+
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+ }
+
+ &-or {
+ grid-column: span 2;
+ color: #999;
+ font-size: 0.85rem;
+ margin: 20px 0;
+ }
+
+ &-social {
+ grid-column: span 2;
+ display: flex;
+ justify-content: center;
+ gap: 1.5rem;
+
+ .SignUp-social-button {
+ width: 50px;
+ height: 50px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 50%;
+ background-color: #333;
+ cursor: pointer;
+ transition: background-color 0.3s;
+
+ &:hover {
+ background-color: #444;
+ }
+
+ img {
+ width: 30px;
+ height: 30px;
+ }
+ }
+ }
+}
diff --git a/frontend/src/pages/SignUp/SignUp.tsx b/frontend/src/pages/SignUp/SignUp.tsx
new file mode 100644
index 0000000000..9b40aaf02e
--- /dev/null
+++ b/frontend/src/pages/SignUp/SignUp.tsx
@@ -0,0 +1,67 @@
+import { ReactElement, useState } from "react";
+import { Box, Button, Typography, TextField, IconButton, InputAdornment } from "@mui/material";
+import Navbar from "../../components/Navbar/Navbar";
+import Footer from "../../components/Footer/Footer";
+import Visibility from "@mui/icons-material/Visibility";
+import VisibilityOff from "@mui/icons-material/VisibilityOff";
+import "./SignUp.scss";
+
+const SignUp = (): ReactElement => {
+ const [showPassword, setShowPassword] = useState(false);
+
+ const togglePasswordVisibility = () => {
+ setShowPassword((prev) => !prev);
+ };
+
+ return (
+
+
+
+
+
+ Sign Up
+
+
+ Empower your interview preparation today! Create an account to unlock exclusive features and personalized
+ experiences.
+
+
+
+
+
+
+
+
+ {showPassword ? : }
+
+
+ ),
+ }}
+ />
+
+
+ Sign Up
+
+
+
+ Already have an account? Login
+
+
+ {/* Or Continue with */}
+
+
+
+
+
+ );
+};
+
+export default SignUp;