diff --git a/next.config.js b/next.config.js
index cb41d95..ec07ce3 100644
--- a/next.config.js
+++ b/next.config.js
@@ -1,8 +1,9 @@
/** @type {import('next').NextConfig} */
const withPlugins = require('next-compose-plugins');
const withTM = require('next-transpile-modules')(['react-syntax-highlighter']);
+const withFonts = require('next-fonts');
-const nextConfig = withPlugins([withTM], {
+const nextConfig = withPlugins([withFonts, withTM], {
reactStrictMode: false,
output: 'export',
images: {
@@ -11,14 +12,14 @@ const nextConfig = withPlugins([withTM], {
basePath: '/tools',
async redirects() {
return [
- {
- source: '/',
- destination: '/tools',
- basePath: false,
- permanent: true
- }
+ {
+ source: '/',
+ destination: '/tools',
+ basePath: false,
+ permanent: true
+ }
]
-}
+ }
});
module.exports = nextConfig;
diff --git a/package-lock.json b/package-lock.json
index bf74635..d2b227d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -19,6 +19,7 @@
"@mui/material": "^5.13.0",
"@tanstack/react-query": "^4.29.7",
"ace-builds": "^1.32.2",
+ "ahooks": "^3.7.8",
"axios": "^1.4.0",
"big-integer": "^1.6.52",
"crypto-js": "^4.2.0",
@@ -62,7 +63,8 @@
"eslint-plugin-next": "^0.0.0",
"eslint-plugin-prettier": "^5.1.0",
"husky": "^8.0.0",
- "lint-staged": "^15.2.0"
+ "lint-staged": "^15.2.0",
+ "next-fonts": "^1.5.1"
},
"engines": {
"node": ">=16.0.0",
@@ -1045,6 +1047,70 @@
"resolved": "https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz",
"integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw=="
},
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+ "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
+ "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+ "dev": true,
+ "peer": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "dev": true,
+ "peer": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.5.tgz",
+ "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.15",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+ "dev": true,
+ "peer": true
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.20",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
+ "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
"node_modules/@mui/base": {
"version": "5.0.0-beta.28",
"resolved": "https://registry.npmmirror.com/@mui/base/-/base-5.0.0-beta.28.tgz",
@@ -1581,6 +1647,35 @@
"@types/ms": "*"
}
},
+ "node_modules/@types/eslint": {
+ "version": "8.56.0",
+ "resolved": "https://registry.npmmirror.com/@types/eslint/-/eslint-8.56.0.tgz",
+ "integrity": "sha512-FlsN0p4FhuYRjIxpbdXovvHQhtlG05O1GG/RNWvdAxTboR438IOTwmrY/vLA+Xfgg06BTkP045M3vpFwTMv1dg==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@types/estree": "*",
+ "@types/json-schema": "*"
+ }
+ },
+ "node_modules/@types/eslint-scope": {
+ "version": "3.7.7",
+ "resolved": "https://registry.npmmirror.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
+ "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@types/eslint": "*",
+ "@types/estree": "*"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.5.tgz",
+ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
+ "dev": true,
+ "peer": true
+ },
"node_modules/@types/extend": {
"version": "3.0.4",
"resolved": "https://registry.npmmirror.com/@types/extend/-/extend-3.0.4.tgz",
@@ -1594,6 +1689,17 @@
"@types/unist": "^2"
}
},
+ "node_modules/@types/js-cookie": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmmirror.com/@types/js-cookie/-/js-cookie-2.2.7.tgz",
+ "integrity": "sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA=="
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true
+ },
"node_modules/@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmmirror.com/@types/json5/-/json5-0.0.29.tgz",
@@ -1778,6 +1884,181 @@
"node": "^16.0.0 || >=18.0.0"
}
},
+ "node_modules/@webassemblyjs/ast": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/ast/-/ast-1.11.6.tgz",
+ "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@webassemblyjs/helper-numbers": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/floating-point-hex-parser": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
+ "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==",
+ "dev": true,
+ "peer": true
+ },
+ "node_modules/@webassemblyjs/helper-api-error": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
+ "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==",
+ "dev": true,
+ "peer": true
+ },
+ "node_modules/@webassemblyjs/helper-buffer": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
+ "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
+ "dev": true,
+ "peer": true
+ },
+ "node_modules/@webassemblyjs/helper-numbers": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
+ "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@webassemblyjs/floating-point-hex-parser": "1.11.6",
+ "@webassemblyjs/helper-api-error": "1.11.6",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
+ "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==",
+ "dev": true,
+ "peer": true
+ },
+ "node_modules/@webassemblyjs/helper-wasm-section": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
+ "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/ieee754": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
+ "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@xtuc/ieee754": "^1.2.0"
+ }
+ },
+ "node_modules/@webassemblyjs/leb128": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
+ "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/utf8": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
+ "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==",
+ "dev": true,
+ "peer": true
+ },
+ "node_modules/@webassemblyjs/wasm-edit": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
+ "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/helper-wasm-section": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6",
+ "@webassemblyjs/wasm-opt": "1.11.6",
+ "@webassemblyjs/wasm-parser": "1.11.6",
+ "@webassemblyjs/wast-printer": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-gen": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
+ "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/ieee754": "1.11.6",
+ "@webassemblyjs/leb128": "1.11.6",
+ "@webassemblyjs/utf8": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-opt": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
+ "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6",
+ "@webassemblyjs/wasm-parser": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-parser": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
+ "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-api-error": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/ieee754": "1.11.6",
+ "@webassemblyjs/leb128": "1.11.6",
+ "@webassemblyjs/utf8": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/wast-printer": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
+ "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@xtuc/ieee754": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmmirror.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+ "dev": true,
+ "peer": true
+ },
+ "node_modules/@xtuc/long": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmmirror.com/@xtuc/long/-/long-4.2.2.tgz",
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+ "dev": true,
+ "peer": true
+ },
"node_modules/ace-builds": {
"version": "1.32.2",
"resolved": "https://registry.npmmirror.com/ace-builds/-/ace-builds-1.32.2.tgz",
@@ -1794,6 +2075,16 @@
"node": ">=0.4.0"
}
},
+ "node_modules/acorn-import-assertions": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmmirror.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
+ "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
+ "dev": true,
+ "peer": true,
+ "peerDependencies": {
+ "acorn": "^8"
+ }
+ },
"node_modules/acorn-jsx": {
"version": "5.3.2",
"resolved": "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
@@ -1810,6 +2101,34 @@
"node": ">=0.8"
}
},
+ "node_modules/ahooks": {
+ "version": "3.7.8",
+ "resolved": "https://registry.npmmirror.com/ahooks/-/ahooks-3.7.8.tgz",
+ "integrity": "sha512-e/NMlQWoCjaUtncNFIZk3FG1ImSkV/JhScQSkTqnftakRwdfZWSw6zzoWSG9OMYqPNs2MguDYBUFFC6THelWXA==",
+ "dependencies": {
+ "@babel/runtime": "^7.21.0",
+ "@types/js-cookie": "^2.x.x",
+ "ahooks-v3-count": "^1.0.0",
+ "dayjs": "^1.9.1",
+ "intersection-observer": "^0.12.0",
+ "js-cookie": "^2.x.x",
+ "lodash": "^4.17.21",
+ "resize-observer-polyfill": "^1.5.1",
+ "screenfull": "^5.0.0",
+ "tslib": "^2.4.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
+ "node_modules/ahooks-v3-count": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/ahooks-v3-count/-/ahooks-v3-count-1.0.0.tgz",
+ "integrity": "sha512-V7uUvAwnimu6eh/PED4mCDjE7tokeZQLKlxg9lCTMPhN+NjsSbtdacByVlR1oluXQzD3MOw55wylDmQo4+S9ZQ=="
+ },
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz",
@@ -1821,6 +2140,15 @@
"uri-js": "^4.2.2"
}
},
+ "node_modules/ajv-keywords": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+ "dev": true,
+ "peerDependencies": {
+ "ajv": "^6.9.1"
+ }
+ },
"node_modules/ansi-escapes": {
"version": "6.2.0",
"resolved": "https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-6.2.0.tgz",
@@ -2077,6 +2405,15 @@
"node": ">=0.6"
}
},
+ "node_modules/big.js": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmmirror.com/big.js/-/big.js-5.2.2.tgz",
+ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+ "dev": true,
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/bplist-parser": {
"version": "0.2.0",
"resolved": "https://registry.npmmirror.com/bplist-parser/-/bplist-parser-0.2.0.tgz",
@@ -2109,6 +2446,25 @@
"node": ">=8"
}
},
+ "node_modules/browserslist": {
+ "version": "4.22.2",
+ "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.22.2.tgz",
+ "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001565",
+ "electron-to-chromium": "^1.4.601",
+ "node-releases": "^2.0.14",
+ "update-browserslist-db": "^1.0.13"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
"node_modules/buffer-from": {
"version": "0.1.2",
"resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-0.1.2.tgz",
@@ -2227,6 +2583,16 @@
"resolved": "https://registry.npmmirror.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
"integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg=="
},
+ "node_modules/chrome-trace-event": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
+ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
+ "dev": true,
+ "peer": true,
+ "engines": {
+ "node": ">=6.0"
+ }
+ },
"node_modules/classnames": {
"version": "2.3.2",
"resolved": "https://registry.npmmirror.com/classnames/-/classnames-2.3.2.tgz",
@@ -2520,6 +2886,11 @@
"node": ">=8"
}
},
+ "node_modules/dayjs": {
+ "version": "1.11.10",
+ "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.10.tgz",
+ "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ=="
+ },
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz",
@@ -2779,11 +3150,27 @@
"safe-buffer": "~5.1.0"
}
},
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.616",
+ "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz",
+ "integrity": "sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg==",
+ "dev": true,
+ "peer": true
+ },
"node_modules/emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz",
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
},
+ "node_modules/emojis-list": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/emojis-list/-/emojis-list-3.0.0.tgz",
+ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
"node_modules/enhanced-resolve": {
"version": "5.15.0",
"resolved": "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
@@ -2874,6 +3261,13 @@
"safe-array-concat": "^1.0.1"
}
},
+ "node_modules/es-module-lexer": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-1.4.1.tgz",
+ "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==",
+ "dev": true,
+ "peer": true
+ },
"node_modules/es-set-tostringtag": {
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz",
@@ -3346,6 +3740,16 @@
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
"dev": true
},
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmmirror.com/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "dev": true,
+ "peer": true,
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
"node_modules/execa": {
"version": "7.2.0",
"resolved": "https://registry.npmmirror.com/execa/-/execa-7.2.0.tgz",
@@ -3445,6 +3849,22 @@
"node": "^10.12.0 || >=12.0.0"
}
},
+ "node_modules/file-loader": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmmirror.com/file-loader/-/file-loader-6.2.0.tgz",
+ "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==",
+ "dev": true,
+ "dependencies": {
+ "loader-utils": "^2.0.0",
+ "schema-utils": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "peerDependencies": {
+ "webpack": "^4.0.0 || ^5.0.0"
+ }
+ },
"node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz",
@@ -4160,6 +4580,11 @@
"node": ">= 0.4"
}
},
+ "node_modules/intersection-observer": {
+ "version": "0.12.2",
+ "resolved": "https://registry.npmmirror.com/intersection-observer/-/intersection-observer-0.12.2.tgz",
+ "integrity": "sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg=="
+ },
"node_modules/is-alphabetical": {
"version": "1.0.4",
"resolved": "https://registry.npmmirror.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
@@ -4543,6 +4968,34 @@
"set-function-name": "^2.0.1"
}
},
+ "node_modules/jest-worker": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmmirror.com/jest-worker/-/jest-worker-27.5.1.tgz",
+ "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/jiti": {
"version": "1.21.0",
"resolved": "https://registry.npmmirror.com/jiti/-/jiti-1.21.0.tgz",
@@ -4558,6 +5011,11 @@
"integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==",
"peer": true
},
+ "node_modules/js-cookie": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmmirror.com/js-cookie/-/js-cookie-2.2.1.tgz",
+ "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ=="
+ },
"node_modules/js-sdsl": {
"version": "4.4.2",
"resolved": "https://registry.npmmirror.com/js-sdsl/-/js-sdsl-4.4.2.tgz",
@@ -4846,6 +5304,42 @@
"node": ">=18.0.0"
}
},
+ "node_modules/loader-runner": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmmirror.com/loader-runner/-/loader-runner-4.3.0.tgz",
+ "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
+ "dev": true,
+ "peer": true,
+ "engines": {
+ "node": ">=6.11.5"
+ }
+ },
+ "node_modules/loader-utils": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
+ "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+ "dev": true,
+ "dependencies": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ },
+ "engines": {
+ "node": ">=8.9.0"
+ }
+ },
+ "node_modules/loader-utils/node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz",
@@ -4860,8 +5354,7 @@
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
- "dev": true
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/lodash.camelcase": {
"version": "4.3.0",
@@ -5672,6 +6165,13 @@
"resolved": "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz",
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
},
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmmirror.com/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true,
+ "peer": true
+ },
"node_modules/next": {
"version": "14.0.4",
"resolved": "https://registry.npmmirror.com/next/-/next-14.0.4.tgz",
@@ -5723,6 +6223,19 @@
"resolved": "https://registry.npmmirror.com/next-compose-plugins/-/next-compose-plugins-2.2.1.tgz",
"integrity": "sha512-OjJ+fV15FXO2uQXQagLD4C0abYErBjyjE0I0FHpOEIB8upw0hg1ldFP6cqHTJBH1cZqy96OeR3u1dJ+Ez2D4Bg=="
},
+ "node_modules/next-fonts": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmmirror.com/next-fonts/-/next-fonts-1.5.1.tgz",
+ "integrity": "sha512-pgEJ40xO1oRhM6RqhQJ9CzuZOFp6Zq+aAD/V1P9sq/wdepvLzhFxDm3lCZNoE7+78NSuMKgT6b1qeXSsqWuUMQ==",
+ "dev": true,
+ "dependencies": {
+ "file-loader": "^6.0.0",
+ "url-loader": "^4.0.0"
+ },
+ "peerDependencies": {
+ "webpack": "^4.0.0 || ^5.0.0"
+ }
+ },
"node_modules/next-transpile-modules": {
"version": "10.0.1",
"resolved": "https://registry.npmmirror.com/next-transpile-modules/-/next-transpile-modules-10.0.1.tgz",
@@ -5731,6 +6244,13 @@
"enhanced-resolve": "^5.10.0"
}
},
+ "node_modules/node-releases": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.14.tgz",
+ "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
+ "dev": true,
+ "peer": true
+ },
"node_modules/normalize-package-data": {
"version": "3.0.3",
"resolved": "https://registry.npmmirror.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
@@ -6169,6 +6689,16 @@
"node": ">=8"
}
},
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
"node_modules/rc-resize-observer": {
"version": "1.4.0",
"resolved": "https://registry.npmmirror.com/rc-resize-observer/-/rc-resize-observer-1.4.0.tgz",
@@ -6914,6 +7444,28 @@
"loose-envify": "^1.1.0"
}
},
+ "node_modules/schema-utils": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-3.3.0.tgz",
+ "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/screenfull": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmmirror.com/screenfull/-/screenfull-5.2.0.tgz",
+ "integrity": "sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.5.4.tgz",
@@ -6928,6 +7480,16 @@
"node": ">=10"
}
},
+ "node_modules/serialize-javascript": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz",
+ "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
"node_modules/set-function-length": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.1.1.tgz",
@@ -7044,6 +7606,34 @@
"node": ">=0.10.0"
}
},
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/source-map-support/node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true,
+ "peer": true
+ },
+ "node_modules/source-map-support/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/space-separated-tokens": {
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
@@ -7363,6 +7953,63 @@
"node": ">=6"
}
},
+ "node_modules/terser": {
+ "version": "5.26.0",
+ "resolved": "https://registry.npmmirror.com/terser/-/terser-5.26.0.tgz",
+ "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.8.2",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/terser-webpack-plugin": {
+ "version": "5.3.9",
+ "resolved": "https://registry.npmmirror.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz",
+ "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.17",
+ "jest-worker": "^27.4.5",
+ "schema-utils": "^3.1.1",
+ "serialize-javascript": "^6.0.1",
+ "terser": "^5.16.8"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "peerDependencies": {
+ "webpack": "^5.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "uglify-js": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/terser/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true,
+ "peer": true
+ },
"node_modules/text-extensions": {
"version": "2.4.0",
"resolved": "https://registry.npmmirror.com/text-extensions/-/text-extensions-2.4.0.tgz",
@@ -7650,6 +8297,23 @@
"node": ">=8"
}
},
+ "node_modules/update-browserslist-db": {
+ "version": "1.0.13",
+ "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
+ "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz",
@@ -7658,6 +8322,29 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/url-loader": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmmirror.com/url-loader/-/url-loader-4.1.1.tgz",
+ "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==",
+ "dev": true,
+ "dependencies": {
+ "loader-utils": "^2.0.0",
+ "mime-types": "^2.1.27",
+ "schema-utils": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "peerDependencies": {
+ "file-loader": "*",
+ "webpack": "^4.0.0 || ^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "file-loader": {
+ "optional": true
+ }
+ }
+ },
"node_modules/use-sync-external-store": {
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
@@ -7730,6 +8417,84 @@
"node": ">=10.13.0"
}
},
+ "node_modules/webpack": {
+ "version": "5.89.0",
+ "resolved": "https://registry.npmmirror.com/webpack/-/webpack-5.89.0.tgz",
+ "integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@types/eslint-scope": "^3.7.3",
+ "@types/estree": "^1.0.0",
+ "@webassemblyjs/ast": "^1.11.5",
+ "@webassemblyjs/wasm-edit": "^1.11.5",
+ "@webassemblyjs/wasm-parser": "^1.11.5",
+ "acorn": "^8.7.1",
+ "acorn-import-assertions": "^1.9.0",
+ "browserslist": "^4.14.5",
+ "chrome-trace-event": "^1.0.2",
+ "enhanced-resolve": "^5.15.0",
+ "es-module-lexer": "^1.2.1",
+ "eslint-scope": "5.1.1",
+ "events": "^3.2.0",
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.2.9",
+ "json-parse-even-better-errors": "^2.3.1",
+ "loader-runner": "^4.2.0",
+ "mime-types": "^2.1.27",
+ "neo-async": "^2.6.2",
+ "schema-utils": "^3.2.0",
+ "tapable": "^2.1.1",
+ "terser-webpack-plugin": "^5.3.7",
+ "watchpack": "^2.4.0",
+ "webpack-sources": "^3.2.3"
+ },
+ "bin": {
+ "webpack": "bin/webpack.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "peerDependenciesMeta": {
+ "webpack-cli": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-sources": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-3.2.3.tgz",
+ "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
+ "dev": true,
+ "peer": true,
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/webpack/node_modules/eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/webpack/node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true,
+ "peer": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz",
diff --git a/package.json b/package.json
index c703958..a24a9cd 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
"@mui/material": "^5.13.0",
"@tanstack/react-query": "^4.29.7",
"ace-builds": "^1.32.2",
+ "ahooks": "^3.7.8",
"axios": "^1.4.0",
"big-integer": "^1.6.52",
"crypto-js": "^4.2.0",
@@ -78,6 +79,7 @@
"eslint-plugin-next": "^0.0.0",
"eslint-plugin-prettier": "^5.1.0",
"husky": "^8.0.0",
- "lint-staged": "^15.2.0"
+ "lint-staged": "^15.2.0",
+ "next-fonts": "^1.5.1"
}
}
diff --git a/public/cnzz.js b/public/cnzz.js
index eda09d7..b33a41a 100644
--- a/public/cnzz.js
+++ b/public/cnzz.js
@@ -2,8 +2,8 @@ if (
[
'rivers.chaitin.cn',
'dev.rivers.ctopt.cn',
- '127.0.0.1',
- 'localhost',
+ // '127.0.0.1',
+ // 'localhost',
].includes(document.domain)
) {
window.is_river = true;
diff --git a/src/asset/tag/dev.svg b/src/asset/tag/dev.svg
new file mode 100644
index 0000000..319fbd8
--- /dev/null
+++ b/src/asset/tag/dev.svg
@@ -0,0 +1,25 @@
+
+
\ No newline at end of file
diff --git a/src/asset/tag/dev_check.svg b/src/asset/tag/dev_check.svg
new file mode 100644
index 0000000..aaf8ccc
--- /dev/null
+++ b/src/asset/tag/dev_check.svg
@@ -0,0 +1,25 @@
+
+
\ No newline at end of file
diff --git a/src/asset/tag/encode.svg b/src/asset/tag/encode.svg
new file mode 100644
index 0000000..0deadf3
--- /dev/null
+++ b/src/asset/tag/encode.svg
@@ -0,0 +1,24 @@
+
+
\ No newline at end of file
diff --git a/src/asset/tag/encode_check.svg b/src/asset/tag/encode_check.svg
new file mode 100644
index 0000000..d18a955
--- /dev/null
+++ b/src/asset/tag/encode_check.svg
@@ -0,0 +1,24 @@
+
+
\ No newline at end of file
diff --git a/src/asset/tag/encryption.svg b/src/asset/tag/encryption.svg
new file mode 100644
index 0000000..259832b
--- /dev/null
+++ b/src/asset/tag/encryption.svg
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file
diff --git a/src/asset/tag/encryption_check.svg b/src/asset/tag/encryption_check.svg
new file mode 100644
index 0000000..236a9a2
--- /dev/null
+++ b/src/asset/tag/encryption_check.svg
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file
diff --git a/src/asset/tag/hot.svg b/src/asset/tag/hot.svg
new file mode 100644
index 0000000..9383ebf
--- /dev/null
+++ b/src/asset/tag/hot.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/src/asset/tag/hot_check.svg b/src/asset/tag/hot_check.svg
new file mode 100644
index 0000000..29f12c1
--- /dev/null
+++ b/src/asset/tag/hot_check.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/src/asset/tag/hover_red_like.svg b/src/asset/tag/hover_red_like.svg
new file mode 100644
index 0000000..dede3ee
--- /dev/null
+++ b/src/asset/tag/hover_red_like.svg
@@ -0,0 +1,12 @@
+
+
+
\ No newline at end of file
diff --git a/src/asset/tag/image.svg b/src/asset/tag/image.svg
new file mode 100644
index 0000000..36d1098
--- /dev/null
+++ b/src/asset/tag/image.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/src/asset/tag/image_check.svg b/src/asset/tag/image_check.svg
new file mode 100644
index 0000000..7aa9d6f
--- /dev/null
+++ b/src/asset/tag/image_check.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/src/asset/tag/json.svg b/src/asset/tag/json.svg
new file mode 100644
index 0000000..dbb819c
--- /dev/null
+++ b/src/asset/tag/json.svg
@@ -0,0 +1,24 @@
+
+
\ No newline at end of file
diff --git a/src/asset/tag/json_check.svg b/src/asset/tag/json_check.svg
new file mode 100644
index 0000000..e89ffe2
--- /dev/null
+++ b/src/asset/tag/json_check.svg
@@ -0,0 +1,24 @@
+
+
\ No newline at end of file
diff --git a/src/asset/tag/like.svg b/src/asset/tag/like.svg
new file mode 100644
index 0000000..6564274
--- /dev/null
+++ b/src/asset/tag/like.svg
@@ -0,0 +1,24 @@
+
+
\ No newline at end of file
diff --git a/src/asset/tag/like_check.svg b/src/asset/tag/like_check.svg
new file mode 100644
index 0000000..d812add
--- /dev/null
+++ b/src/asset/tag/like_check.svg
@@ -0,0 +1,24 @@
+
+
\ No newline at end of file
diff --git a/src/asset/tag/no_like.png b/src/asset/tag/no_like.png
new file mode 100644
index 0000000..28191f1
Binary files /dev/null and b/src/asset/tag/no_like.png differ
diff --git a/src/asset/tag/other.svg b/src/asset/tag/other.svg
new file mode 100644
index 0000000..8a65f70
--- /dev/null
+++ b/src/asset/tag/other.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/src/asset/tag/other_check.svg b/src/asset/tag/other_check.svg
new file mode 100644
index 0000000..8f3f5ad
--- /dev/null
+++ b/src/asset/tag/other_check.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/src/asset/tag/red_like.png b/src/asset/tag/red_like.png
new file mode 100644
index 0000000..ee015f1
Binary files /dev/null and b/src/asset/tag/red_like.png differ
diff --git a/src/asset/tag/red_like_check.png b/src/asset/tag/red_like_check.png
new file mode 100644
index 0000000..22a7ccf
Binary files /dev/null and b/src/asset/tag/red_like_check.png differ
diff --git a/src/asset/tag/text.svg b/src/asset/tag/text.svg
new file mode 100644
index 0000000..cd5e891
--- /dev/null
+++ b/src/asset/tag/text.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/src/asset/tag/text_check.svg b/src/asset/tag/text_check.svg
new file mode 100644
index 0000000..7431db7
--- /dev/null
+++ b/src/asset/tag/text_check.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx
index 942405d..682f820 100644
--- a/src/components/Button/index.tsx
+++ b/src/components/Button/index.tsx
@@ -105,7 +105,7 @@ const ButtonStyle: { [key in ButtonType]: object } = {
},
},
highlight: {
- background: 'linear-gradient(270deg, #11AF60 0%, #52C41A 100%)',
+ background: 'linear-gradient(270deg, #11AF60 0%, rgba(52, 90, 255, 1) 100%)',
boxShadow: '0px 10px 30px 0px rgba(82,196,26,0.2)',
color: '#fff',
},
diff --git a/src/components/LikeIcon/index.tsx b/src/components/LikeIcon/index.tsx
new file mode 100644
index 0000000..fed025d
--- /dev/null
+++ b/src/components/LikeIcon/index.tsx
@@ -0,0 +1,50 @@
+import RedTag from '@/asset/tag/red_like.png';
+import RedTagCheck from '@/asset/tag/red_like_check.png';
+import HoverRedTagCheck from '@/asset/tag/hover_red_like.svg';
+import { LikeContext } from '@/hooks/useLikeList';
+import React, { useContext, useMemo } from 'react';
+import { Box } from '@mui/material';
+
+const LikeIcon: React.FC<{ path: string, style: React.CSSProperties }> = (props) => {
+ const { path, style = {} } = props
+ const { likeList, updateLikeList } = useContext(LikeContext)
+
+ const hanldeLike = (event: React.MouseEvent, path: string) => {
+ event.preventDefault()
+ if (typeof window !== 'undefined' && window.localStorage) {
+ try {
+ let newLike = []
+ if (likeList?.includes(path)) {
+ newLike = likeList.filter(item => item !== path)
+ } else {
+ newLike = [...(likeList || []), path]
+ }
+ updateLikeList(newLike)
+ } finally {
+ console.log('Get like list error')
+ }
+ }
+ }
+ const isCheck = useMemo(() => {
+ return likeList?.includes(path)
+ }, [likeList, path])
+
+ return (
+ hanldeLike(event, path)}/>
+ );
+};
+
+export default LikeIcon;
diff --git a/src/components/MenuView/components.tsx b/src/components/MenuView/components.tsx
deleted file mode 100644
index 966894d..0000000
--- a/src/components/MenuView/components.tsx
+++ /dev/null
@@ -1,137 +0,0 @@
-import { defaultText, grayBg, grayBorder, grayText } from '@/constant';
-import { Box } from '@mui/material';
-import { styled } from '@mui/material/styles';
-
-export const MenuPage = styled(Box)(() => ({
- display: 'flex',
- height: '100% ',
- backgroundColor: grayBg,
- borderTop: `1px solid ${grayBorder}`,
- paddingBottom: '16px',
- paddingRight: '16px',
- '& .Mui-selected': {
- backgroundColor: 'rgba(0, 0, 0, 0.04)!important',
- },
-}));
-
-export const Main = styled('div')(() => ({
- flex: 1,
- padding: '24px',
- paddingBottom: '0',
- overflowY: 'auto',
- display: 'flex',
- flexDirection: 'column',
- gap: '24px',
- '& code, & code *': {
- fontFamily: 'Mono',
- },
- '& code .linenumber': {
- backgroundColor: 'rgba(82, 196, 26, 0.08)',
- marginRight: '24px',
- paddingRight: '5px!important',
- minWidth: '2em!important',
- },
- '& pre': {
- borderRadius: '4px',
- minHeight: '150px',
- },
-}));
-
-export const SideMenu = styled('div')(() => ({
- display: 'flex',
- flexDirection: 'column',
- alignItems: 'stretch',
- padding: '16px 16px 0 16px',
- gap: '8px',
- height: '100%',
-}));
-
-export const SubMenu = styled('div', {
- shouldForwardProp: (prop) => prop !== 'expand' && prop !== 'height',
-})<{ expand: string; height: number | string }>(({ expand, height }) => ({
- display: 'flex',
- flexDirection: 'column',
- alignItems: 'stretch',
- gap: '12px',
- height: 0,
- transition: 'height 0.2s linear',
- overflow: 'hidden',
- ...(expand === 'true' && {
- height: height ?? 'auto',
- transition: 'height 0.2s linear',
- }),
-}));
-
-export const Breadcrumbs = styled('div')(() => ({
- display: 'flex',
- alignItems: 'center',
- width: '100%',
- gap: '4px',
- marginTop: '16px',
-}));
-
-export const BreadcrumbsItem = styled(Box)(() => ({
- color: grayText,
- cursor: 'pointer',
- '&:hover': {
- color: defaultText,
- },
- fontSize: '14px',
-}));
-
-export const ToolsIcon = styled(Box)(() => ({
- width: '60px',
- height: '60px',
- background: 'linear-gradient(180deg, #230970 0%, #1C0254 100%)',
- borderRadius: '8px',
-}));
-
-export const Tag = styled('div', {
- shouldForwardProp: (prop) => prop !== 'highlight',
-})<{ highlight: 'true' | 'false' }>(({ highlight }) => ({
- display: 'inline-block',
- width: '24px',
- lineHeight: '14px',
- fontSize: '10px',
- borderRadius: '4px',
- textAlign: 'center',
- color: '#fff',
- backgroundColor: '#FF665D',
- ...(highlight === 'true' && { color: '#FF665D', backgroundColor: '#fff' }),
-}));
-
-export const ScrollY = styled('div')(() => ({
- height: '100%',
- overflow: 'auto',
- ...(navigator?.userAgent?.indexOf('Chrome') != -1 && { overflow: 'overlay' }),
-}));
-
-export const SubTitle = styled('div')(() => ({
- height: '20px',
- padding: '12px',
- background: 'rgba(30, 111, 255, 0.1)',
- borderRadius: '4px',
-}));
-
-export const Container = styled(Box)(() => ({
- background: '#fff',
- borderRadius: '4px',
- boxShadow: '0px 4px 10px 0px rgba(145,158,171,0.1)',
- overflow: 'auto',
- minHeight: '100%',
- '& > *': {
- '@media(min-width: 1520px)': {
- marginLeft: 'auto',
- marginRight: 'auto',
- },
- },
- '& > .MuiGrid-container': {
- '@media(min-width: 1520px)': {
- marginLeft: 'auto!important',
- marginRight: 'auto!important',
- '& > .MuiGrid-item:first-of-type': {
- paddingLeft: '0!important',
- },
- },
- },
-}));
diff --git a/src/components/MenuView/index.tsx b/src/components/MenuView/index.tsx
index 74758ed..b4f65ee 100644
--- a/src/components/MenuView/index.tsx
+++ b/src/components/MenuView/index.tsx
@@ -1,25 +1,14 @@
-import { defaultTextClick, secondaryClick } from '@/constant';
+import { grayText } from '@/constant';
import { usePath } from '@/hooks';
-import { AllTags, Tags, Tool, routesMenu } from '@/utils/tools';
-import ErrorIcon from '@mui/icons-material/Error';
-import SearchIcon from '@mui/icons-material/Search';
+import { allTags } from '@/utils/tags';
+import { Tool, allTools } from '@/utils/tools';
import {
Box,
- Button,
- Grid,
- IconButton,
- InputBase,
- ListItemText,
Paper,
- Typography,
+ Stack,
+ Typography
} from '@mui/material';
-import List from '@mui/material/List';
-import ListItemButton from '@mui/material/ListItemButton';
-import Head from 'next/head';
-import { useRouter } from 'next/router';
-import React, { useEffect, useMemo } from 'react';
-import { Container, Main, MenuPage, SideMenu } from './components';
-import Link from 'next/link';
+import React from 'react';
export interface MenuProps {
children: React.ReactElement;
@@ -31,224 +20,41 @@ const ifChecked = (currentPath: string, itemPath: string) => {
const MenuView: React.FC = ({ children }) => {
const { path } = usePath();
- const [tags, setTags] = React.useState([]);
- const [tools, setTools] = React.useState(routesMenu);
- const [searchText, setSearchText] = React.useState('');
- const [openStaus, setOpenStatus] = React.useState(
- routesMenu.map((item) => true)
- );
- const router = useRouter();
-
- const currentItem = useMemo(() => {
- const _item = routesMenu.find((item) => item.path === path);
- if (_item) return _item;
- }, [path]);
- const checkTags = (tag: Tags) => {
- const _index = tags.findIndex((item) => item === tag);
- const _tags = [...tags];
- if (_index >= 0) {
- _tags.splice(_index, 1);
- } else {
- _tags.push(tag);
- }
- setTags(_tags);
- };
-
- useEffect(() => {
- let toolsFilter: Tool[] = [];
- if (tags.length)
- toolsFilter = routesMenu.filter((item) =>
- item.tags.some((tag) => tags.includes(tag))
- );
- else toolsFilter = routesMenu;
- setTools(
- toolsFilter.filter((item) => {
- return (
- item.label.toUpperCase().includes(searchText?.toUpperCase()) ||
- item.subTitle.toUpperCase().includes(searchText?.toUpperCase())
- );
- })
- );
- }, [tags, searchText]);
+ const [tool] = React.useState(allTools.find(item => item.path === path));
return (
- <>
-
- {currentItem?.label + ' - 长亭百川云工具库'}
-
-
-
-
-
+
+
+
-
-
-
-
- setSearchText(event.target.value)}
- placeholder='输入关键词搜索工具'
- inputProps={{ 'aria-label': 'search icons' }}
- sx={{ grow: 1, fontSize: '12px' }}
- />
-
-
- {AllTags.map((item) => (
-
- ))}
-
-
-
- {tools.map((item, index) => (
-
-
-
-
-
- ))}
-
-
-
-
-
-
-
-
-
-
- {currentItem?.label}
-
-
-
- {currentItem?.subTitle ? (
-
-
- {currentItem?.subTitle}
-
- ) : null}
-
-
-
-
- {children}
-
-
-
- >
+ {tool?.label}
+
+
+
+ {allTags.filter(tag => tool?.tags.includes(tag.name)).map(tag => {tag.label})}
+
+
+ {tool?.subTitle}
+ {children}
+
);
};
diff --git a/src/components/ToolCard/index.tsx b/src/components/ToolCard/index.tsx
new file mode 100644
index 0000000..6aac4bd
--- /dev/null
+++ b/src/components/ToolCard/index.tsx
@@ -0,0 +1,34 @@
+import { Tag } from "@/utils/tags"
+import { Tool } from "@/utils/tools"
+import { Avatar, CardHeader, Typography } from "@mui/material"
+import LikeIcon from "../LikeIcon"
+import { grayText2 } from "@/constant"
+
+export const ToolCard = (props: { tool: Tool, tag?: Tag, showStar?: boolean }) => {
+ const { tool, tag, showStar = true } = props
+ return (
+ <>
+
+ {tool.label[0]}
+
+ }
+ action={
+
+ }
+ title={tool.label}
+ />
+ {tool.subTitle}
+ >
+ )
+}
\ No newline at end of file
diff --git a/src/components/Tools/home.tsx b/src/components/Tools/home.tsx
deleted file mode 100644
index 3b7da73..0000000
--- a/src/components/Tools/home.tsx
+++ /dev/null
@@ -1,118 +0,0 @@
-import {
- Autocomplete,
- Box,
- Button,
- IconButton,
- Paper,
- Stack,
- TextField,
- Typography,
-} from '@mui/material';
-
-import { primary } from '@/constant';
-import { AllTags, routesMenu, type Tool } from '@/utils/tools';
-import SearchIcon from '@mui/icons-material/Search';
-import Link from 'next/link';
-import { useRouter } from 'next/router';
-import { useState } from 'react';
-
-export default function App() {
- const router = useRouter();
-
- // const [searchText, setSearchText] = useState('')
- const [tools] = useState(routesMenu);
- const [tags] = useState<(typeof AllTags)[number][]>(AllTags);
-
- return (
-
-
-
-
- X
-
- TOOLS
-
-
-
- menu.filter((item) => {
- return (
- item.label
- .toUpperCase()
- .includes(state.inputValue?.toUpperCase()) ||
- item.subTitle
- .toUpperCase()
- .includes(state.inputValue?.toUpperCase())
- );
- })
- }
- onInputChange={(v: any) => {
- setTimeout(() => {
- const item = routesMenu.find((item) =>
- [v.target.textContent, v.target.value].includes(item.label)
- );
- if (item) {
- router.push(item.path);
- }
- });
- }}
- options={routesMenu}
- sx={{ height: '100%' }}
- renderInput={(params) => (
-
-
-
-
-
-
- )}
- />
-
-
-
- {tags.map((section) => [
-
-
- {section.label}
- ,
-
- {tools
- .filter((tool) => tool.tags.includes(section.name))
- .map((item) => (
-
-
-
- ))}
- ,
- ])}
-
-
- );
-}
diff --git a/src/components/Tools/index.tsx b/src/components/Tools/index.tsx
index 3c4b0eb..2934244 100644
--- a/src/components/Tools/index.tsx
+++ b/src/components/Tools/index.tsx
@@ -18,7 +18,7 @@ export const ToolsForm = styled(Box)(() => ({
pt: '10px',
display: 'flex',
flexDirection: 'column',
- width: '838px',
+
margin: 'auto',
gap: 16,
'& .MuiOutlinedInput-root': {
@@ -35,7 +35,6 @@ export const ToolsForm = styled(Box)(() => ({
width: '155px',
color: defaultTextClick,
fontSize: '14px',
- maxWidth: '838px',
},
'& .MuiOutlinedInput-notchedOutline': {
borderColor: '#E3E8EF',
diff --git a/src/constant/color.ts b/src/constant/color.ts
index 404b5c6..bda3d69 100644
--- a/src/constant/color.ts
+++ b/src/constant/color.ts
@@ -1,4 +1,4 @@
-export const primary = '#52C41A';
+export const primary = 'rgba(52, 90, 255, 1)';
export const primaryHover = '#73D13C';
export const primaryClick = '#389E0E';
@@ -10,7 +10,7 @@ export const secondary = '#ECF9E6';
export const secondaryHover = '#F3FDEE';
export const secondaryClick = '#DAE8D4';
-export const special = 'linear-gradient(270deg, #11AF60 0%, #52C41A 100%)';
+export const special = 'linear-gradient(270deg, #11AF60 0%, rgba(52, 90, 255, 1) 100%)';
export const dangerHover = 'linear-gradient(225deg, #FF1F1F 0%, #F78900 100%)';
export const disabled = '#F7F7F7';
@@ -31,12 +31,12 @@ export const leastTextClick = '#737373';
export const disabledText = '#BFBFBF';
export const specialText = '#737971';
-export const success = '#52C41A';
+export const success = 'rgba(52, 90, 255, 1)';
export const warning = '#FFBF00';
export const error = '#FF1F1F';
-export const grayText = '#0B310440';
-export const grayText2 = '#97A4B0';
+export const grayText = '#0B2562';
+export const grayText2 = 'rgba(11,37,98,0.5)';
export const errorText = '#FF1F1F';
export const infoText = '#2F7CE9';
diff --git a/src/hooks/useAnchor.tsx b/src/hooks/useAnchor.tsx
new file mode 100644
index 0000000..13bc791
--- /dev/null
+++ b/src/hooks/useAnchor.tsx
@@ -0,0 +1,22 @@
+import { useLocalStorageState } from 'ahooks';
+import { createContext, useState } from "react";
+
+export interface Anchor {
+ anchor: string;
+ updateAnchor: (value: string) => void;
+}
+
+export const AnchorContext = createContext(null as any);
+
+export const AnchorContextProvider = ({ children }: any) => {
+ const [anchor, setAnchor] = useState('');
+ const updateAnchor = (newValue: string) => {
+ setAnchor(newValue)
+ };
+ const contextValue = {
+ anchor,
+ updateAnchor,
+ };
+
+ return {children};
+};
\ No newline at end of file
diff --git a/src/hooks/useLikeList.tsx b/src/hooks/useLikeList.tsx
new file mode 100644
index 0000000..a195037
--- /dev/null
+++ b/src/hooks/useLikeList.tsx
@@ -0,0 +1,24 @@
+import { useLocalStorageState } from 'ahooks';
+import { createContext, useState } from "react";
+
+export interface Like {
+ likeList: string[];
+ updateLikeList: (value: string[]) => void;
+}
+
+export const LikeContext = createContext(null as any);
+
+export const LikeContextProvider = ({ children }: any) => {
+ const [localList = [], setLocalList] = useLocalStorageState('like_list', { defaultValue: [] })
+ const [likeList, setValue] = useState(localList);
+ const updateLikeList = (newValue: string[]) => {
+ setValue(newValue);
+ setLocalList(newValue)
+ };
+ const contextValue = {
+ likeList,
+ updateLikeList,
+ };
+
+ return {children};
+};
\ No newline at end of file
diff --git a/src/icon/Copy.tsx b/src/icon/Copy.tsx
index 355e8e5..78820d2 100644
--- a/src/icon/Copy.tsx
+++ b/src/icon/Copy.tsx
@@ -10,7 +10,7 @@ export const Copy = (props: SvgIconProps) => {
({
+ background: 'linear-gradient(180deg, rgba(255, 182, 85, 0.2) 0%, rgba(255, 58, 116, 0.2) 100%)',
+ filter: 'blur(1px)',
+ width: '14px',
+ height: '14px',
+ borderRadius: '50%',
+ justifyContent: 'center',
+ alignItems: 'center',
+ marginLeft: 'auto',
+}));
+export const IssueIcon = styled(Box)(() => ({
+ width: '8px',
+ height: '8px',
+ borderRadius: '50%',
+ background: 'linear-gradient(141deg, #FFB655 0%, #FF3A74 100%)',
+}));
diff --git a/src/layouts/Header/index.tsx b/src/layouts/Header/index.tsx
new file mode 100644
index 0000000..b066be4
--- /dev/null
+++ b/src/layouts/Header/index.tsx
@@ -0,0 +1,151 @@
+import { usePath } from '@/hooks';
+import { Tags } from '@/utils/tags';
+import { Tool, allTools } from '@/utils/tools';
+import GitHubIcon from '@mui/icons-material/GitHub';
+import SearchIcon from '@mui/icons-material/Search';
+import {
+ Autocomplete,
+ Box,
+ Paper,
+ Stack,
+ TextField,
+ Typography
+} from '@mui/material';
+import Link from 'next/link';
+import { useRouter } from 'next/router';
+import React, { useEffect, useMemo } from 'react';
+import { IssueIcon, IssueIconWrap } from './components';
+import { ToolCard } from '@/components/ToolCard';
+
+const ifChecked = (currentPath: string, itemPath: string) => {
+ return currentPath === itemPath;
+};
+
+const Header: React.FC<{}> = () => {
+ const { path } = usePath();
+ const [tags, setTags] = React.useState([]);
+ const [tools, setTools] = React.useState(allTools);
+ const [openSearch, setOpenSearch] = React.useState(false);
+ const [searchText, setSearchText] = React.useState('');
+
+ const [openStaus, setOpenStatus] = React.useState(
+ allTools.map((item) => true)
+ );
+ const router = useRouter();
+
+ const currentItem = useMemo(() => {
+ const _item = allTools.find((item) => item.path === path);
+ if (_item) return _item;
+ }, [path]);
+ const checkTags = (tag: Tags) => {
+ const _index = tags.findIndex((item) => item === tag);
+ const _tags = [...tags];
+ if (_index >= 0) {
+ _tags.splice(_index, 1);
+ } else {
+ _tags.push(tag);
+ }
+ setTags(_tags);
+ };
+
+ useEffect(() => {
+ let toolsFilter: Tool[] = [];
+ if (tags.length)
+ toolsFilter = allTools.filter((item) =>
+ item.tags.some((tag) => tags.includes(tag))
+ );
+ else toolsFilter = allTools;
+ setTools(
+ toolsFilter.filter((item) => {
+ return (
+ item.label.toUpperCase().includes(searchText?.toUpperCase()) ||
+ item.subTitle.toUpperCase().includes(searchText?.toUpperCase())
+ );
+ })
+ );
+ }, [tags, searchText]);
+
+ return (
+
+
+ 百川在线工具箱
+
+
+
+
+
+ 工具不够?提个需求
+
+
+ setOpenSearch(false)}
+ onOpen={() => setOpenSearch(true)}
+ filterOptions={(menu, state) =>
+ menu.filter((item) => {
+ return (
+ item.label
+ .toUpperCase()
+ .includes(state.inputValue?.toUpperCase()) ||
+ item.subTitle
+ .toUpperCase()
+ .includes(state.inputValue?.toUpperCase())
+ );
+ })
+ }
+ onInputChange={(v: any) => {
+ const item = allTools.find((item) =>
+ [v.target.textContent, v.target.value].includes(item.label)
+ );
+ }}
+ options={allTools}
+ renderOption={(props: object, option: Tool, state: object, ownerState: object) => (
+
+ setOpenSearch(false)}>
+
+
+
+ )}
+ sx={{ height: '100%' }}
+ renderInput={(params) => (
+
+
+
+
+ )}
+ />
+
+
+ );
+};
+
+export default Header;
diff --git a/src/layouts/LoginLayout/copyright.tsx b/src/layouts/LoginLayout/copyright.tsx
deleted file mode 100644
index b4d0468..0000000
--- a/src/layouts/LoginLayout/copyright.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import React, { useCallback } from 'react';
-import emblem from '@/asset/img/emblem.webp';
-import { ImageIcon } from '@/icon';
-import { Stack, SxProps } from '@mui/material';
-import Text from '@/components/Text';
-import { useMobileView } from '@/hooks';
-import { Side_Margin } from '@/styles/colors';
-
-const Copyright: React.FC<{ sx?: SxProps; fontColor?: string }> = ({
- sx,
- fontColor,
-}) => {
- const isMobile = useMobileView();
-
- const openBeianLink = useCallback(() => {
- window.open('https://beian.miit.gov.cn/#/Integrated/recordQuery', '_blank');
- }, []);
-
- return (
-
-
- Copyright ©2022 北京长亭未来科技有限公司
-
- a': { color: 'inherit' },
- }}
- onClick={openBeianLink}
- >
-
- 京ICP备 19035216号-1
-
-
- );
-};
-
-export default Copyright;
diff --git a/src/layouts/LoginLayout/index.tsx b/src/layouts/LoginLayout/index.tsx
deleted file mode 100644
index 9b1a5a8..0000000
--- a/src/layouts/LoginLayout/index.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import React from 'react';
-import Navbar from '@/layouts/Navbar';
-import { Stack } from '@mui/material';
-import Copyright from './copyright';
-import { useMobileView } from '@/hooks';
-import banner1 from '@/asset/img/banner1.webp';
-import mobile_login from '@/asset/img/mobile_login.webp';
-import Image from 'next/image';
-
-const LoginLayout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
- const isMobile = useMobileView();
- return (
- <>
-
-
-
- {children}
-
-
- >
- );
-};
-
-export default LoginLayout;
diff --git a/src/layouts/Logo/index.tsx b/src/layouts/Logo/index.tsx
deleted file mode 100644
index 60234b5..0000000
--- a/src/layouts/Logo/index.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import React, { useCallback } from 'react';
-import { styled } from '@mui/material/styles';
-import { useNavigateParams } from '@/hooks';
-import { Logo as CompanyLogo } from '@/icon';
-import Text from '@/components/Text';
-import { useMobileView } from '@/hooks';
-import { primary, defaultText } from '@/styles/colors';
-
-const LogoComponent = styled('a')(({ theme }) => ({
- display: 'flex',
- userSelect: 'none',
- margin: '8px',
- marginRight: '60px',
- fontSize: '20px',
- cursor: 'pointer',
- [theme.breakpoints.down('sm')]: {
- margin: '24px 8px',
- marginRight: '0px',
- },
-}));
-
-const Logo: React.FC = () => {
- const navigate = useNavigateParams();
- const isMobile = useMobileView();
-
- const toHome = useCallback(() => navigate('/'), [navigate]);
-
- return (
-
-
-
- 长亭百川云平台
-
-
- );
-};
-
-export default Logo;
diff --git a/src/layouts/Navbar/components.tsx b/src/layouts/Navbar/components.tsx
deleted file mode 100644
index 6a7f8d1..0000000
--- a/src/layouts/Navbar/components.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import React from 'react';
-import { styled } from '@mui/material/styles';
-
-export interface BarProps {
- children: React.ReactNode;
- view?: 'default' | 'login';
- id?: string;
-}
-
-const BarBase = styled('div', {
- shouldForwardProp: (prop) => prop !== 'view',
-})<{ view?: 'default' | 'login' }>(({ theme, view = 'default' }) => ({
- width: '100%',
- position: 'fixed',
- top: '0px',
- zIndex: theme.zIndex.drawer + 3,
- // boxShadow: theme.shadows[4],
- backgroundColor: view === 'default' ? 'rgba(255,255,255,0.6)' : 'transparent',
- backdropFilter: 'blur(4px)',
- [theme.breakpoints.down('sm')]: {
- zIndex: theme.zIndex.drawer - 1,
- },
-}));
-const BarContent = styled('div')(({ theme }) => ({
- display: 'flex',
- alignItems: 'center',
- height: '64px',
- justifyContent: 'flex-start',
- margin: `0 28px`,
- marginRight: '0',
- [theme.breakpoints.down('sm')]: { marginLeft: '12px' },
-}));
-
-const Bar: React.FC = (props) => {
- const { children, view, id } = props;
- return (
-
- {children}
-
- );
-};
-
-export default Bar;
diff --git a/src/layouts/Navbar/index.tsx b/src/layouts/Navbar/index.tsx
deleted file mode 100644
index b81f207..0000000
--- a/src/layouts/Navbar/index.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import React from 'react';
-import Bar from './components';
-import Logo from '@/layouts/Logo';
-import NavMenu from './items/menu';
-import { ApplicationInfo } from '@/types';
-
-interface NavBarMenuData {
- apps: ApplicationInfo[];
-}
-
-const renderNavContent = (menuData: ApplicationInfo[]) => {
- return [, ];
-};
-
-const DefaultNavbar: React.FC = ({ apps }) => {
- return (
-
- {renderNavContent(apps)}
-
- );
-};
-
-const LoginNavbar: React.FC<{}> = () => {
- return (
-
-
-
- );
-};
-
-const Navbar = { default: DefaultNavbar, login: LoginNavbar };
-
-export default Navbar;
diff --git a/src/layouts/Navbar/items/menu/index.tsx b/src/layouts/Navbar/items/menu/index.tsx
deleted file mode 100644
index 8ec0e2b..0000000
--- a/src/layouts/Navbar/items/menu/index.tsx
+++ /dev/null
@@ -1,87 +0,0 @@
-import { useMobileView } from '@/hooks';
-import { ApplicationInfo, NavMenuProps } from '@/types';
-import DehazeIcon from '@mui/icons-material/Dehaze';
-import { styled } from '@mui/material/styles';
-import { useRouter } from 'next/router';
-import React, { useCallback, useState } from 'react';
-import MenuItem from './item';
-import MobilPanel from './mobileView';
-import NavPanel from './panel';
-
-const NavMenuComponent = styled('div')(() => ({
- display: 'flex',
- gap: '40px',
-}));
-
-const menu: NavMenuProps[] = [
- { title: '最新活动', link: '/' },
- { title: '产品', expand: true },
-];
-
-const NavMenu: React.FC<{ apps: ApplicationInfo[] }> = ({ apps }) => {
- const isMobile = useMobileView();
- const router = useRouter();
- const [panelContent, setPanelContent] = useState();
- const [openMobile, setOpenMobile] = useState(false);
- const [openPanel, setOpenPanel] = useState(false);
-
- const handleOpen = useCallback(
- (open: boolean) => () => {
- setOpenMobile(open);
- },
- []
- );
-
- const handleClickMenu = useCallback(
- (link?: string) => () => {
- if (link) {
- router.push(link);
- }
- },
- [router]
- );
-
- const handleShowPanel = useCallback(
- (menuContent: NavMenuProps) => () => {
- if (menuContent?.expand) setOpenPanel(true);
- },
- []
- );
-
- const handleLeavePanel = useCallback(() => {
- setOpenPanel(false);
- }, []);
-
- return (
- <>
- {isMobile ? (
-
- ) : (
-
- {menu?.map((menuitem, index) => (
-
- ))}
-
- )}
-
- {isMobile && (
-
- )}
- >
- );
-};
-
-export default NavMenu;
diff --git a/src/layouts/Navbar/items/menu/item.tsx b/src/layouts/Navbar/items/menu/item.tsx
deleted file mode 100644
index 92a9b27..0000000
--- a/src/layouts/Navbar/items/menu/item.tsx
+++ /dev/null
@@ -1,96 +0,0 @@
-import { ArrowDown } from '@/icon';
-import { defaultText, primary, secondaryText } from '@/styles/colors';
-import { styled, SxProps } from '@mui/material/styles';
-import React from 'react';
-
-export interface MenuItemProps {
- title: string | React.ReactElement;
- subTitle?: string;
- highlight?: string | boolean;
- hoverview?: string | boolean;
- expand?: string | boolean;
- sx?: SxProps;
- icon?: React.ReactElement;
- onClick?: () => void;
- onHover?: () => void;
- onLeave?: () => void;
-}
-
-const MenuItemComponent = styled('div', {
- shouldForwardProp: (prop) => prop !== 'hightlight' && prop !== 'expand',
-})>(
- ({ highlight, hoverview }) => ({
- fontSize: 16,
- fontWeight: 'bold',
- color: highlight === 'true' ? primary : defaultText,
- lineHeight: '22px',
- ...(hoverview === 'true' && {
- transition: 'color 0.1s linear',
- }),
- transition: 'color 0.1s linear',
- display: 'flex',
- alignItems: 'center',
-
- '& > svg': {
- display: 'inline-block',
- marginLeft: '8px',
- transformOrigin: 'center',
- transition: 'transform 0.1s linear',
- },
- '&:hover': {
- ...(hoverview === 'true' && {
- color: primary,
- transition: 'color 0.1s linear',
- }),
- '& > svg': {
- transform: 'rotate(0.5turn)',
- transition: 'transform 0.1s linear',
- },
- },
- })
-);
-
-const MenuItemContent = styled('div')(() => ({
- fontSize: 'inherit',
- color: secondaryText,
-}));
-
-const MenuItemWrapper = styled('div')(() => ({
- display: 'flex',
- flexDirection: 'column',
- cursor: 'pointer',
-}));
-
-const MenuItem: React.FC = (props) => {
- const {
- title,
- subTitle,
- highlight,
- expand,
- sx,
- onClick,
- onHover,
- onLeave,
- hoverview,
- icon,
- } = props;
- return (
-
-
- {icon}
- {title}
- {expand && }
-
- {subTitle && {subTitle}}
-
- );
-};
-
-export default MenuItem;
diff --git a/src/layouts/Navbar/items/menu/mobileView.tsx b/src/layouts/Navbar/items/menu/mobileView.tsx
deleted file mode 100644
index a93400b..0000000
--- a/src/layouts/Navbar/items/menu/mobileView.tsx
+++ /dev/null
@@ -1,166 +0,0 @@
-import search_icon from '@/asset/img/search_icon.webp';
-import { useDebounce } from '@/hooks';
-import { Side_Margin, grayLight, primary } from '@/styles/colors';
-import { ApplicationInfo } from '@/types';
-import ClearIcon from '@mui/icons-material/Clear';
-import { Drawer, TextField } from '@mui/material';
-import { styled } from '@mui/material/styles';
-import Image, { StaticImageData } from 'next/image';
-import { useRouter } from 'next/router';
-import React, { useCallback, useEffect, useState } from 'react';
-import MenuItem from './item';
-import { NavPanelProps } from './panel';
-
-const PanelContent = styled('div')(() => ({
- display: 'flex',
- flexDirection: 'column',
- width: '100%',
- padding: `${parseInt(Side_Margin) / 2}% ${Side_Margin}`,
- justifyContent: 'flex-start',
- gap: 20,
-}));
-
-const Content = styled('div')(() => ({
- display: 'flex',
- gap: 40,
-}));
-
-const Header = styled('div')(() => ({
- display: 'flex',
- justifyContent: 'flex-end',
- alignItems: 'center',
-}));
-
-const ContentCol = styled('div')(() => ({
- display: 'flex',
- flexDirection: 'column',
- height: '100%',
- justifyContent: 'flex-start',
- alignItems: 'stretch',
- gap: 20,
-}));
-
-export const Icon = ({
- style,
- src,
-}: {
- style?: React.CSSProperties;
- src: string | StaticImageData;
-}) => {
- return (
-
- );
-};
-
-const ContentCard = styled('div')(() => ({
- padding: '12px 24px',
- transition: 'background-color 0.2s linear',
- '&:hover': {
- backgroundColor: grayLight,
- transition: 'background-color 0.2s linear',
- },
-}));
-
-const NavPanel: React.FC = (props) => {
- const { open, onClose, apps } = props;
- const [menuContent, setMenuContent] = useState([]);
- const [input, setInput] = useState('');
- const debounceInput = useDebounce(input, 500);
- const router = useRouter();
-
- const handleSearch = useCallback(
- (search: string) => {
- if (apps && search.length > 0) {
- const data = JSON.parse(JSON.stringify(apps)) as ApplicationInfo[];
- const searchResult = data?.filter((item) => item.name.includes(search));
- setMenuContent([...searchResult]);
- } else {
- setMenuContent(apps);
- }
- },
- [apps]
- );
-
- const toWorkbench = useCallback(
- (app: ApplicationInfo) => () => {
- if (app?.scope) {
- router.push(`/landing/${app?.scope}`);
- } else {
- router.push('/workbench');
- }
- onClose?.();
- },
- [onClose, router]
- );
-
- const handleSetInput = useCallback((event: React.ChangeEvent) => {
- const target = event.target as HTMLInputElement;
- const input = target?.value?.trim();
- setInput(input ?? '');
- }, []);
-
- useEffect(() => {
- handleSearch(debounceInput);
- }, [debounceInput, handleSearch]);
-
- return (
-
-
-
-
- ),
- }}
- />
-
-
- {menuContent?.map((contentItem, index) => (
-
-
-
- ))}
-
-
-
-
- );
-};
-
-export default NavPanel;
diff --git a/src/layouts/Navbar/items/menu/panel.tsx b/src/layouts/Navbar/items/menu/panel.tsx
deleted file mode 100644
index 3296f8c..0000000
--- a/src/layouts/Navbar/items/menu/panel.tsx
+++ /dev/null
@@ -1,152 +0,0 @@
-import search_icon from '@/asset/img/search_icon.webp';
-import { useDebounce } from '@/hooks';
-import { Side_Margin, grayLight } from '@/styles/colors';
-import { ApplicationInfo } from '@/types';
-import { Drawer, TextField } from '@mui/material';
-import { styled } from '@mui/material/styles';
-import Image, { StaticImageData } from 'next/image';
-import { useRouter } from 'next/router';
-import React, { useCallback, useEffect, useState } from 'react';
-import MenuItem from './item';
-
-export interface NavPanelProps {
- open: boolean;
- onClose?: () => void;
- apps: ApplicationInfo[];
-}
-
-const PanelContent = styled('div')(() => ({
- display: 'flex',
- flexDirection: 'column',
- width: '100%',
- padding: `${parseInt(Side_Margin) / 1.5}% ${Side_Margin}`,
- paddingTop: `calc(${parseInt(Side_Margin) / 4}% + 64px)`,
- justifyContent: 'flex-start',
- gap: 20,
-}));
-
-const Content = styled('div')(() => ({
- display: 'flex',
- gap: 40,
- flexWrap: 'wrap',
- alignItems: 'stretch',
-}));
-
-export const Icon = ({
- style,
- src,
-}: {
- style?: React.CSSProperties;
- src: string | StaticImageData;
-}) => {
- return (
-
- );
-};
-
-const ContentCard = styled('div')(() => ({
- flex: '0 0 220px',
- padding: '12px 24px',
- transition: 'background-color 0.2s linear',
- '&:hover': {
- backgroundColor: grayLight,
- transition: 'background-color 0.2s linear',
- },
-}));
-
-const NavPanel: React.FC = (props) => {
- const { open, onClose, apps } = props;
- const [menuContent, setMenuContent] = useState(apps ?? []);
- const [input, setInput] = useState('');
- const router = useRouter();
- const debounceInput = useDebounce(input, 500);
-
- const handleSearch = useCallback(
- (search: string) => {
- if (apps && search.length > 0) {
- const data = JSON.parse(JSON.stringify(apps)) as ApplicationInfo[];
- const searchResult = data?.filter((item) => item.name.includes(search));
- setMenuContent([...searchResult]);
- } else {
- setMenuContent(apps);
- }
- },
- [apps]
- );
-
- const handleSetInput = useCallback((event: React.ChangeEvent) => {
- const target = event.target as HTMLInputElement;
- const input = target?.value?.trim();
- setInput(input ?? '');
- }, []);
-
- const toWorkbench = useCallback(
- (app: ApplicationInfo) => () => {
- if (app?.scope) {
- router.push(`/landing/${app?.scope}`);
- } else {
- router.push('/workbench');
- }
- onClose?.();
- },
- [router, onClose]
- );
-
- useEffect(() => {
- handleSearch(debounceInput);
- }, [debounceInput, handleSearch]);
-
- return (
-
-
-
- ),
- }}
- />
-
- {menuContent?.map((item, index) => (
-
-
-
- ))}
-
-
-
- );
-};
-
-export default NavPanel;
diff --git a/src/layouts/SideBar/components.tsx b/src/layouts/SideBar/components.tsx
new file mode 100644
index 0000000..0ab79a7
--- /dev/null
+++ b/src/layouts/SideBar/components.tsx
@@ -0,0 +1,20 @@
+import { defaultText, grayBg, grayBorder, grayText } from '@/constant';
+import { Box, Stack } from '@mui/material';
+import { styled } from '@mui/material/styles';
+
+export const IssueIconWrap = styled(Stack)(() => ({
+ background: 'linear-gradient(180deg, rgba(255, 182, 85, 0.2) 0%, rgba(255, 58, 116, 0.2) 100%)',
+ filter: 'blur(1px)',
+ width: '14px',
+ height: '14px',
+ borderRadius: '50%',
+ justifyContent: 'center',
+ alignItems: 'center',
+ marginLeft: 'auto',
+}));
+export const IssueIcon = styled(Box)(() => ({
+ width: '8px',
+ height: '8px',
+ borderRadius: '50%',
+ background: 'linear-gradient(141deg, #FFB655 0%, #FF3A74 100%)',
+}));
diff --git a/src/layouts/SideBar/index.tsx b/src/layouts/SideBar/index.tsx
new file mode 100644
index 0000000..5dc185d
--- /dev/null
+++ b/src/layouts/SideBar/index.tsx
@@ -0,0 +1,47 @@
+import { grayText } from '@/constant/color';
+import { AnchorContext } from '@/hooks/useAnchor';
+import { allTags } from '@/utils/tags';
+import {
+ Box,
+ Button,
+ Link,
+ Paper,
+ Stack,
+ Typography
+} from '@mui/material';
+import Image from 'next/image';
+import React, { useContext, useEffect, useState } from 'react';
+
+const SideBar: React.FC<{}> = () => {
+ const { anchor } = useContext(AnchorContext)
+ const [checkAnchor, setChectAnchor] = useState('')
+ useEffect(() => {
+ setChectAnchor(anchor)
+ }, [anchor])
+ return (
+
+
+ {allTags.map(item =>
+ setChectAnchor(item.name)} href={'/tools#' + item.name} sx={{ alignSelf: 'stretch' }} className='custom-link'>
+
+
+ )}
+
+
+ );
+};
+
+export default SideBar;
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index d6e40c1..320eec4 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -7,11 +7,19 @@ import '@/styles/static/swiper.css';
import theme from '@/styles/theme';
import createEmotionCache from '@/utils/emotionCache';
import { CacheProvider } from '@emotion/react';
-import { ThemeProvider } from '@mui/material';
+import { Box, Stack, ThemeProvider } from '@mui/material';
import CssBaseline from '@mui/material/CssBaseline';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import PropTypes from 'prop-types';
+import Header from '@/layouts/Header';
+import SideBar from '@/layouts/SideBar';
+import { LikeContextProvider } from '@/hooks/useLikeList';
+import { AnchorContextProvider } from '@/hooks/useAnchor';
+import { usePath } from '@/hooks';
+import { useMemo } from 'react';
+import { allTools } from '@/utils/tools';
+import Head from 'next/head';
const clientSideEmotionCache = createEmotionCache();
@@ -19,24 +27,45 @@ const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false, refetchOnWindowFocus: false } },
});
+
export default function App({
Component,
emotionCache = clientSideEmotionCache,
}: any) {
+ const { path } = usePath()
+
+ const currentItem = useMemo(() => {
+ return allTools.find(item => item.path === path)
+ }, [path])
return (
<>
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
>
);
}
diff --git a/src/pages/aes.tsx b/src/pages/aes.tsx
index 02f3284..fc40a3a 100644
--- a/src/pages/aes.tsx
+++ b/src/pages/aes.tsx
@@ -101,7 +101,7 @@ const AES: React.FC = () => {
gap: '18px',
maxWidth: '1020px',
fontFamily: 'Mono',
- width: '838px',
+
mx: 'auto',
}}
>
diff --git a/src/pages/ascii.tsx b/src/pages/ascii.tsx
index b1f107e..f5f0bea 100644
--- a/src/pages/ascii.tsx
+++ b/src/pages/ascii.tsx
@@ -112,7 +112,7 @@ const Hash: React.FC = () => {
gap: '18px',
maxWidth: '1020px',
fontFamily: 'Mono',
- width: '838px',
+
mx: 'auto',
}}
>
diff --git a/src/pages/base64.tsx b/src/pages/base64.tsx
index c46dbdb..124bce2 100644
--- a/src/pages/base64.tsx
+++ b/src/pages/base64.tsx
@@ -66,9 +66,9 @@ const Base64: React.FC = () => {
sx={{
mt: '24px',
gap: '18px',
- maxWidth: '1020px',
+ // maxWidth: '1020px',
fontFamily: 'Mono',
- width: '838px',
+
mx: 'auto',
}}
>
diff --git a/src/pages/case_convert.tsx b/src/pages/case_convert.tsx
index 1c7f6cf..ed66d6c 100644
--- a/src/pages/case_convert.tsx
+++ b/src/pages/case_convert.tsx
@@ -16,7 +16,7 @@ const CaseConvert: React.FC = () => {
gap: '18px',
maxWidth: '1020px',
fontFamily: 'Mono',
- width: '838px',
+
mx: 'auto',
}}
>
diff --git a/src/pages/hash.tsx b/src/pages/hash.tsx
index 7ba6a68..4265836 100644
--- a/src/pages/hash.tsx
+++ b/src/pages/hash.tsx
@@ -85,7 +85,7 @@ const Hash: React.FC = () => {
gap: '18px',
maxWidth: '1020px',
fontFamily: 'Mono',
- width: '838px',
+
mx: 'auto',
}}
>
diff --git a/src/pages/img2base64.tsx b/src/pages/img2base64.tsx
index f8ed443..5796440 100644
--- a/src/pages/img2base64.tsx
+++ b/src/pages/img2base64.tsx
@@ -90,7 +90,7 @@ const ImgBase64: React.FC = () => {
gap: '18px',
maxWidth: '1020px',
fontFamily: 'Mono',
- width: '838px',
+
mx: 'auto',
}}
>
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 35e8521..844f1fe 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -1,3 +1,99 @@
-import Home from '@/components/Tools/home';
+import {
+ Avatar,
+ Box,
+ Card,
+ CardHeader,
+ Paper,
+ Stack,
+ Typography
+} from '@mui/material';
-export default Home;
+import LikeIcon from '@/components/LikeIcon';
+import { grayText2 } from '@/constant';
+import { LikeContext } from '@/hooks/useLikeList';
+import { Tag, Tags, allTags } from '@/utils/tags';
+import { Tool, allTools } from '@/utils/tools';
+import Image from 'next/image';
+import Link from 'next/link';
+import { useContext, useEffect, useMemo, useRef } from 'react';
+
+import NoLike from '@/asset/tag/no_like.png';
+import { AnchorContext } from '@/hooks/useAnchor';
+import { ToolCard } from '@/components/ToolCard';
+
+export default function App() {
+ const { updateAnchor } = useContext(AnchorContext)
+ const { likeList } = useContext(LikeContext)
+ const mainPageRef = useRef(null)
+
+ useEffect(() => {
+ const handleScroll = () => {
+ if (!mainPageRef.current?.children) return
+ const scrollPosition = mainPageRef?.current.scrollTop;
+ for (let liElement of mainPageRef?.current.children) {
+ const liTop = liElement.offsetTop;
+ const liBottom = liTop + liElement.offsetHeight;
+
+ if (scrollPosition >= liTop - 100 && scrollPosition < liBottom - 100) {
+ const liId = liElement.getAttribute('id');
+ updateAnchor(liId)
+ break;
+ }
+ }
+ };
+ mainPageRef.current?.addEventListener('scroll', handleScroll);
+ return () => {
+ mainPageRef.current?.removeEventListener('scroll', handleScroll);
+ updateAnchor('')
+ };
+ }, []);
+
+ const tagAndTools = useMemo(() => {
+ const addLikeTagForTools = allTools.map(item => {
+ if (likeList?.includes(item.path)) return ({ ...item, tags: [...item.tags, Tags.LIKE] })
+ return item
+ })
+ return allTags.map(tag => {
+ (tag as any).tools = addLikeTagForTools.filter(tool => tool.tags.includes(tag.name))
+ return tag
+ })
+ }, [likeList])
+
+ return (
+
+ {
+ tagAndTools.map(tag => (
+
+ {tag.label}
+
+ {
+ ((tag as any).tools.length ?
+ (tag as any).tools.map((tool: any) => (
+
+
+
+
+
+ )) :
+
+ )
+ }
+
+
+ )
+ )
+ }
+
+ );
+}
diff --git a/src/pages/jsontocsv.tsx b/src/pages/jsontocsv.tsx
index a07398b..5da4fde 100644
--- a/src/pages/jsontocsv.tsx
+++ b/src/pages/jsontocsv.tsx
@@ -136,7 +136,7 @@ const JSONToCSV = () => {
gap: '18px',
maxWidth: '1020px',
fontFamily: 'Mono',
- width: '838px',
+
mx: 'auto',
'.rc-table': {
border: '1px solid #eee',
diff --git a/src/pages/radix_convert.tsx b/src/pages/radix_convert.tsx
index fb93db6..7ba05d0 100644
--- a/src/pages/radix_convert.tsx
+++ b/src/pages/radix_convert.tsx
@@ -146,7 +146,7 @@ const RadixConvert: React.FC = () => {
gap: '18px',
maxWidth: '1020px',
fontFamily: 'Mono',
- width: '838px',
+
mx: 'auto',
}}
>
diff --git a/src/pages/random.tsx b/src/pages/random.tsx
index 92683e2..eb3fb8f 100644
--- a/src/pages/random.tsx
+++ b/src/pages/random.tsx
@@ -107,8 +107,8 @@ const Random: React.FC = () => {
return (
-
-
+
+