diff --git a/package-lock.json b/package-lock.json
index 5832645..f61e44f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,11 +1,11 @@
{
- "name": "frontend",
+ "name": "frontend_nyla_new",
"version": "0.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
- "name": "frontend",
+ "name": "frontend_nyla_new",
"version": "0.0.0",
"dependencies": {
"@azure/msal-browser": "^4.12.0",
@@ -25,20 +25,21 @@
"react-dom": "^19.1.0",
"react-dropzone": "^14.3.8",
"react-icons": "^5.5.0",
- "react-markdown": "^10.1.0",
- "react-router-dom": "^7.5.0",
- "xstate": "^5.18.0"
+ "react-router-dom": "^7.7.1",
+ "xstate": "^5.20.1"
},
"devDependencies": {
- "@eslint/js": "^9.21.0",
- "@types/react": "^19.1.6",
- "@types/react-dom": "^19.1.5",
- "@vitejs/plugin-react": "^4.3.4",
- "eslint": "^9.21.0",
- "eslint-plugin-react-hooks": "^5.1.0",
- "eslint-plugin-react-refresh": "^0.4.19",
- "globals": "^15.15.0",
- "vite": "^6.2.0"
+ "@eslint/js": "^9.30.1",
+ "@types/react": "^19.1.8",
+ "@types/react-dom": "^19.1.6",
+ "@vitejs/plugin-react": "^4.6.0",
+ "eslint": "^9.30.1",
+ "eslint-plugin-react-hooks": "^5.2.0",
+ "eslint-plugin-react-refresh": "^0.4.20",
+ "globals": "^16.3.0",
+ "typescript": "~5.8.3",
+ "typescript-eslint": "^8.35.1",
+ "vite": "^5.4.10"
}
},
"node_modules/@ampproject/remapping": {
@@ -46,6 +47,7 @@
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
"integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.24"
@@ -55,33 +57,36 @@
}
},
"node_modules/@azure/msal-browser": {
- "version": "4.13.2",
- "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.13.2.tgz",
- "integrity": "sha512-lS75bF6FYZRwsacKLXc8UYu/jb+gOB7dtZq5938chCvV/zKTFDnzuXxCXhsSUh0p8s/P8ztgbfdueD9lFARQlQ==",
+ "version": "4.16.0",
+ "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.16.0.tgz",
+ "integrity": "sha512-yF8gqyq7tVnYftnrWaNaxWpqhGQXoXpDfwBtL7UCGlIbDMQ1PUJF/T2xCL6NyDNHoO70qp1xU8GjjYTyNIefkw==",
+ "license": "MIT",
"dependencies": {
- "@azure/msal-common": "15.7.1"
+ "@azure/msal-common": "15.9.0"
},
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/@azure/msal-common": {
- "version": "15.7.1",
- "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.7.1.tgz",
- "integrity": "sha512-a0eowoYfRfKZEjbiCoA5bPT3IlWRAdGSvi63OU23Hv+X6EI8gbvXCoeqokUceFMoT9NfRUWTJSx5FiuzruqT8g==",
+ "version": "15.9.0",
+ "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.9.0.tgz",
+ "integrity": "sha512-lbz/D+C9ixUG3hiZzBLjU79a0+5ZXCorjel3mwXluisKNH0/rOS/ajm8yi4yI9RP5Uc70CAcs9Ipd0051Oh/kA==",
+ "license": "MIT",
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/@azure/msal-react": {
- "version": "3.0.13",
- "resolved": "https://registry.npmjs.org/@azure/msal-react/-/msal-react-3.0.13.tgz",
- "integrity": "sha512-g0jk1CXCWVyshSqdaFW0ES8qTXGHiQZlgfnkS+Oxa0eDgw3phdm8I2EChtFiK67OmoQr+HmYPRrg+s8NpvdeRQ==",
+ "version": "3.0.16",
+ "resolved": "https://registry.npmjs.org/@azure/msal-react/-/msal-react-3.0.16.tgz",
+ "integrity": "sha512-fIFc3z9UrHoOCG4rApNWMRr83DnQlo+CHfLSPNBQa4rndIkr+XYBpdYDqlzqtmikRf3A+CYNVOQ+lQX6jM0zdw==",
+ "license": "MIT",
"engines": {
"node": ">=10"
},
"peerDependencies": {
- "@azure/msal-browser": "^4.13.2",
+ "@azure/msal-browser": "^4.16.0",
"react": "^16.8.0 || ^17 || ^18 || ^19"
}
},
@@ -90,6 +95,7 @@
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
"integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-validator-identifier": "^7.27.1",
"js-tokens": "^4.0.0",
@@ -100,30 +106,32 @@
}
},
"node_modules/@babel/compat-data": {
- "version": "7.27.7",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.7.tgz",
- "integrity": "sha512-xgu/ySj2mTiUFmdE9yCMfBxLp4DHd5DwmbbD05YAuICfodYT3VvRxbrh81LGQ/8UpSdtMdfKMn3KouYDX59DGQ==",
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz",
+ "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/core": {
- "version": "7.27.7",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.7.tgz",
- "integrity": "sha512-BU2f9tlKQ5CAthiMIgpzAh4eDTLWo1mqi9jqE2OxMG0E/OM199VJt2q8BztTxpnSW0i1ymdwLXRJnYzvDM5r2w==",
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz",
+ "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.27.1",
- "@babel/generator": "^7.27.5",
+ "@babel/generator": "^7.28.0",
"@babel/helper-compilation-targets": "^7.27.2",
"@babel/helper-module-transforms": "^7.27.3",
"@babel/helpers": "^7.27.6",
- "@babel/parser": "^7.27.7",
+ "@babel/parser": "^7.28.0",
"@babel/template": "^7.27.2",
- "@babel/traverse": "^7.27.7",
- "@babel/types": "^7.27.7",
+ "@babel/traverse": "^7.28.0",
+ "@babel/types": "^7.28.0",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -139,15 +147,16 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.27.5",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz",
- "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==",
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz",
+ "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/parser": "^7.27.5",
- "@babel/types": "^7.27.3",
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.25",
+ "@babel/parser": "^7.28.0",
+ "@babel/types": "^7.28.0",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
"jsesc": "^3.0.2"
},
"engines": {
@@ -159,6 +168,7 @@
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
"integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/compat-data": "^7.27.2",
"@babel/helper-validator-option": "^7.27.1",
@@ -170,11 +180,22 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/helper-globals": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
+ "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/helper-module-imports": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
"integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/traverse": "^7.27.1",
"@babel/types": "^7.27.1"
@@ -188,6 +209,7 @@
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz",
"integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-module-imports": "^7.27.1",
"@babel/helper-validator-identifier": "^7.27.1",
@@ -205,6 +227,7 @@
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz",
"integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
@@ -214,6 +237,7 @@
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
@@ -223,6 +247,7 @@
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
@@ -232,30 +257,33 @@
"resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
"integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helpers": {
- "version": "7.27.6",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz",
- "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==",
+ "version": "7.28.2",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.2.tgz",
+ "integrity": "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/template": "^7.27.2",
- "@babel/types": "^7.27.6"
+ "@babel/types": "^7.28.2"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
- "version": "7.27.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.7.tgz",
- "integrity": "sha512-qnzXzDXdr/po3bOTbTIQZ7+TxNKxpkN5IifVLXS+r7qwynkZfPyjZfE7hCXbo7IoO9TNcSyibgONsf2HauUd3Q==",
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz",
+ "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/types": "^7.27.7"
+ "@babel/types": "^7.28.0"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -269,6 +297,7 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
"integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -284,6 +313,7 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
"integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -299,6 +329,7 @@
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
"integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/parser": "^7.27.2",
@@ -309,37 +340,30 @@
}
},
"node_modules/@babel/traverse": {
- "version": "7.27.7",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.7.tgz",
- "integrity": "sha512-X6ZlfR/O/s5EQ/SnUSLzr+6kGnkg8HXGMzpgsMsrJVcfDtH1vIp6ctCN4eZ1LS5c0+te5Cb6Y514fASjMRJ1nw==",
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz",
+ "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.27.1",
- "@babel/generator": "^7.27.5",
- "@babel/parser": "^7.27.7",
+ "@babel/generator": "^7.28.0",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/parser": "^7.28.0",
"@babel/template": "^7.27.2",
- "@babel/types": "^7.27.7",
- "debug": "^4.3.1",
- "globals": "^11.1.0"
+ "@babel/types": "^7.28.0",
+ "debug": "^4.3.1"
},
"engines": {
"node": ">=6.9.0"
}
},
- "node_modules/@babel/traverse/node_modules/globals": {
- "version": "11.12.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
- "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/@babel/types": {
- "version": "7.27.7",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.7.tgz",
- "integrity": "sha512-8OLQgDScAOHXnAz2cV+RfzzNMipuLVBz2biuAJFMV9bfkNf393je3VM8CLkjQodW5+iWsSJdSgSWT6rsZoXHPw==",
+ "version": "7.28.2",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz",
+ "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.27.1",
"@babel/helper-validator-identifier": "^7.27.1"
@@ -349,403 +373,394 @@
}
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz",
- "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
"cpu": [
"ppc64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"aix"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz",
- "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
"cpu": [
"arm"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz",
- "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
"cpu": [
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz",
- "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
"cpu": [
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz",
- "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
"cpu": [
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz",
- "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
"cpu": [
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz",
- "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
"cpu": [
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz",
- "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
"cpu": [
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz",
- "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
"cpu": [
"arm"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz",
- "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
"cpu": [
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz",
- "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
"cpu": [
"ia32"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz",
- "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
"cpu": [
"loong64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz",
- "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
"cpu": [
"mips64el"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz",
- "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
"cpu": [
"ppc64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz",
- "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
"cpu": [
"riscv64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz",
- "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
"cpu": [
"s390x"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz",
- "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
"cpu": [
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-arm64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz",
- "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz",
- "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
"cpu": [
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-arm64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz",
- "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz",
- "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
"cpu": [
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz",
- "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
"cpu": [
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"sunos"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz",
- "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
"cpu": [
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz",
- "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
"cpu": [
"ia32"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz",
- "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
"cpu": [
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@eslint-community/eslint-utils": {
@@ -753,6 +768,7 @@
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz",
"integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"eslint-visitor-keys": "^3.4.3"
},
@@ -771,6 +787,7 @@
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
@@ -783,15 +800,17 @@
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
"integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
}
},
"node_modules/@eslint/config-array": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.1.tgz",
- "integrity": "sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==",
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz",
+ "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"@eslint/object-schema": "^2.1.6",
"debug": "^4.3.1",
@@ -802,19 +821,21 @@
}
},
"node_modules/@eslint/config-helpers": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.3.tgz",
- "integrity": "sha512-u180qk2Um1le4yf0ruXH3PYFeEZeYC3p/4wCTKrr2U1CmGdzGi3KtY0nuPDH48UJxlKCC5RDzbcbh4X0XlqgHg==",
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz",
+ "integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@eslint/core": {
- "version": "0.14.0",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz",
- "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==",
+ "version": "0.15.1",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz",
+ "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"@types/json-schema": "^7.0.15"
},
@@ -827,6 +848,7 @@
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
"integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
@@ -850,6 +872,7 @@
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=18"
},
@@ -858,10 +881,11 @@
}
},
"node_modules/@eslint/js": {
- "version": "9.29.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.29.0.tgz",
- "integrity": "sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==",
+ "version": "9.31.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.31.0.tgz",
+ "integrity": "sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
@@ -874,15 +898,17 @@
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
"integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@eslint/plugin-kit": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.3.tgz",
- "integrity": "sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==",
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.4.tgz",
+ "integrity": "sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"@eslint/core": "^0.15.1",
"levn": "^0.4.1"
@@ -891,23 +917,12 @@
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
- "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": {
- "version": "0.15.1",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz",
- "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==",
- "dev": true,
- "dependencies": {
- "@types/json-schema": "^7.0.15"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
"node_modules/@humanfs/core": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
"integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": ">=18.18.0"
}
@@ -917,6 +932,7 @@
"resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz",
"integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"@humanfs/core": "^0.19.1",
"@humanwhocodes/retry": "^0.3.0"
@@ -930,6 +946,7 @@
"resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz",
"integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": ">=18.18"
},
@@ -943,6 +960,7 @@
"resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
"integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": ">=12.22"
},
@@ -956,6 +974,7 @@
"resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
"integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": ">=18.18"
},
@@ -965,17 +984,14 @@
}
},
"node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.8",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
- "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
+ "version": "0.3.12",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz",
+ "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jridgewell/set-array": "^1.2.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/sourcemap-codec": "^1.5.0",
"@jridgewell/trace-mapping": "^0.3.24"
- },
- "engines": {
- "node": ">=6.0.0"
}
},
"node_modules/@jridgewell/resolve-uri": {
@@ -983,296 +999,349 @@
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"dev": true,
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/set-array": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
- "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
- "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
- "dev": true
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz",
+ "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.25",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
- "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+ "version": "0.3.29",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz",
+ "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/@rolldown/pluginutils": {
- "version": "1.0.0-beta.19",
- "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.19.tgz",
- "integrity": "sha512-3FL3mnMbPu0muGOCaKAhhFEYmqv9eTfPSJRJmANrCwtgK8VuxpsZDGK+m0LYAGoyO8+0j5uRe4PeyPDK1yA/hA==",
- "dev": true
+ "version": "1.0.0-beta.27",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz",
+ "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.1.tgz",
- "integrity": "sha512-JAcBr1+fgqx20m7Fwe1DxPUl/hPkee6jA6Pl7n1v2EFiktAHenTaXl5aIFjUIEsfn9w3HE4gK1lEgNGMzBDs1w==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.45.1.tgz",
+ "integrity": "sha512-NEySIFvMY0ZQO+utJkgoMiCAjMrGvnbDLHvcmlA33UXJpYBCvlBEbMMtV837uCkS+plG2umfhn0T5mMAxGrlRA==",
"cpu": [
"arm"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"android"
]
},
"node_modules/@rollup/rollup-android-arm64": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.1.tgz",
- "integrity": "sha512-RurZetXqTu4p+G0ChbnkwBuAtwAbIwJkycw1n6GvlGlBuS4u5qlr5opix8cBAYFJgaY05TWtM+LaoFggUmbZEQ==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.45.1.tgz",
+ "integrity": "sha512-ujQ+sMXJkg4LRJaYreaVx7Z/VMgBBd89wGS4qMrdtfUFZ+TSY5Rs9asgjitLwzeIbhwdEhyj29zhst3L1lKsRQ==",
"cpu": [
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"android"
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.1.tgz",
- "integrity": "sha512-fM/xPesi7g2M7chk37LOnmnSTHLG/v2ggWqKj3CCA1rMA4mm5KVBT1fNoswbo1JhPuNNZrVwpTvlCVggv8A2zg==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.45.1.tgz",
+ "integrity": "sha512-FSncqHvqTm3lC6Y13xncsdOYfxGSLnP+73k815EfNmpewPs+EyM49haPS105Rh4aF5mJKywk9X0ogzLXZzN9lA==",
"cpu": [
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.1.tgz",
- "integrity": "sha512-gDnWk57urJrkrHQ2WVx9TSVTH7lSlU7E3AFqiko+bgjlh78aJ88/3nycMax52VIVjIm3ObXnDL2H00e/xzoipw==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.45.1.tgz",
+ "integrity": "sha512-2/vVn/husP5XI7Fsf/RlhDaQJ7x9zjvC81anIVbr4b/f0xtSmXQTFcGIQ/B1cXIYM6h2nAhJkdMHTnD7OtQ9Og==",
"cpu": [
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.1.tgz",
- "integrity": "sha512-wnFQmJ/zPThM5zEGcnDcCJeYJgtSLjh1d//WuHzhf6zT3Md1BvvhJnWoy+HECKu2bMxaIcfWiu3bJgx6z4g2XA==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.45.1.tgz",
+ "integrity": "sha512-4g1kaDxQItZsrkVTdYQ0bxu4ZIQ32cotoQbmsAnW1jAE4XCMbcBPDirX5fyUzdhVCKgPcrwWuucI8yrVRBw2+g==",
"cpu": [
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"freebsd"
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.1.tgz",
- "integrity": "sha512-uBmIxoJ4493YATvU2c0upGz87f99e3wop7TJgOA/bXMFd2SvKCI7xkxY/5k50bv7J6dw1SXT4MQBQSLn8Bb/Uw==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.45.1.tgz",
+ "integrity": "sha512-L/6JsfiL74i3uK1Ti2ZFSNsp5NMiM4/kbbGEcOCps99aZx3g8SJMO1/9Y0n/qKlWZfn6sScf98lEOUe2mBvW9A==",
"cpu": [
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"freebsd"
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.1.tgz",
- "integrity": "sha512-n0edDmSHlXFhrlmTK7XBuwKlG5MbS7yleS1cQ9nn4kIeW+dJH+ExqNgQ0RrFRew8Y+0V/x6C5IjsHrJmiHtkxQ==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.45.1.tgz",
+ "integrity": "sha512-RkdOTu2jK7brlu+ZwjMIZfdV2sSYHK2qR08FUWcIoqJC2eywHbXr0L8T/pONFwkGukQqERDheaGTeedG+rra6Q==",
"cpu": [
"arm"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.1.tgz",
- "integrity": "sha512-8WVUPy3FtAsKSpyk21kV52HCxB+me6YkbkFHATzC2Yd3yuqHwy2lbFL4alJOLXKljoRw08Zk8/xEj89cLQ/4Nw==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.45.1.tgz",
+ "integrity": "sha512-3kJ8pgfBt6CIIr1o+HQA7OZ9mp/zDk3ctekGl9qn/pRBgrRgfwiffaUmqioUGN9hv0OHv2gxmvdKOkARCtRb8Q==",
"cpu": [
"arm"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.1.tgz",
- "integrity": "sha512-yuktAOaeOgorWDeFJggjuCkMGeITfqvPgkIXhDqsfKX8J3jGyxdDZgBV/2kj/2DyPaLiX6bPdjJDTu9RB8lUPQ==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.45.1.tgz",
+ "integrity": "sha512-k3dOKCfIVixWjG7OXTCOmDfJj3vbdhN0QYEqB+OuGArOChek22hn7Uy5A/gTDNAcCy5v2YcXRJ/Qcnm4/ma1xw==",
"cpu": [
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.1.tgz",
- "integrity": "sha512-W+GBM4ifET1Plw8pdVaecwUgxmiH23CfAUj32u8knq0JPFyK4weRy6H7ooxYFD19YxBulL0Ktsflg5XS7+7u9g==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.45.1.tgz",
+ "integrity": "sha512-PmI1vxQetnM58ZmDFl9/Uk2lpBBby6B6rF4muJc65uZbxCs0EA7hhKCk2PKlmZKuyVSHAyIw3+/SiuMLxKxWog==",
"cpu": [
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.1.tgz",
- "integrity": "sha512-1zqnUEMWp9WrGVuVak6jWTl4fEtrVKfZY7CvcBmUUpxAJ7WcSowPSAWIKa/0o5mBL/Ij50SIf9tuirGx63Ovew==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.45.1.tgz",
+ "integrity": "sha512-9UmI0VzGmNJ28ibHW2GpE2nF0PBQqsyiS4kcJ5vK+wuwGnV5RlqdczVocDSUfGX/Na7/XINRVoUgJyFIgipoRg==",
"cpu": [
"loong64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.1.tgz",
- "integrity": "sha512-Rl3JKaRu0LHIx7ExBAAnf0JcOQetQffaw34T8vLlg9b1IhzcBgaIdnvEbbsZq9uZp3uAH+JkHd20Nwn0h9zPjA==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.45.1.tgz",
+ "integrity": "sha512-7nR2KY8oEOUTD3pBAxIBBbZr0U7U+R9HDTPNy+5nVVHDXI4ikYniH1oxQz9VoB5PbBU1CZuDGHkLJkd3zLMWsg==",
"cpu": [
"ppc64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.1.tgz",
- "integrity": "sha512-j5akelU3snyL6K3N/iX7otLBIl347fGwmd95U5gS/7z6T4ftK288jKq3A5lcFKcx7wwzb5rgNvAg3ZbV4BqUSw==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.45.1.tgz",
+ "integrity": "sha512-nlcl3jgUultKROfZijKjRQLUu9Ma0PeNv/VFHkZiKbXTBQXhpytS8CIj5/NfBeECZtY2FJQubm6ltIxm/ftxpw==",
"cpu": [
"riscv64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.1.tgz",
- "integrity": "sha512-ppn5llVGgrZw7yxbIm8TTvtj1EoPgYUAbfw0uDjIOzzoqlZlZrLJ/KuiE7uf5EpTpCTrNt1EdtzF0naMm0wGYg==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.45.1.tgz",
+ "integrity": "sha512-HJV65KLS51rW0VY6rvZkiieiBnurSzpzore1bMKAhunQiECPuxsROvyeaot/tcK3A3aGnI+qTHqisrpSgQrpgA==",
"cpu": [
"riscv64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.1.tgz",
- "integrity": "sha512-Hu6hEdix0oxtUma99jSP7xbvjkUM/ycke/AQQ4EC5g7jNRLLIwjcNwaUy95ZKBJJwg1ZowsclNnjYqzN4zwkAw==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.45.1.tgz",
+ "integrity": "sha512-NITBOCv3Qqc6hhwFt7jLV78VEO/il4YcBzoMGGNxznLgRQf43VQDae0aAzKiBeEPIxnDrACiMgbqjuihx08OOw==",
"cpu": [
"s390x"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.1.tgz",
- "integrity": "sha512-EtnsrmZGomz9WxK1bR5079zee3+7a+AdFlghyd6VbAjgRJDbTANJ9dcPIPAi76uG05micpEL+gPGmAKYTschQw==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.45.1.tgz",
+ "integrity": "sha512-+E/lYl6qu1zqgPEnTrs4WysQtvc/Sh4fC2nByfFExqgYrqkKWp1tWIbe+ELhixnenSpBbLXNi6vbEEJ8M7fiHw==",
"cpu": [
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.1.tgz",
- "integrity": "sha512-iAS4p+J1az6Usn0f8xhgL4PaU878KEtutP4hqw52I4IO6AGoyOkHCxcc4bqufv1tQLdDWFx8lR9YlwxKuv3/3g==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.45.1.tgz",
+ "integrity": "sha512-a6WIAp89p3kpNoYStITT9RbTbTnqarU7D8N8F2CV+4Cl9fwCOZraLVuVFvlpsW0SbIiYtEnhCZBPLoNdRkjQFw==",
"cpu": [
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.1.tgz",
- "integrity": "sha512-NtSJVKcXwcqozOl+FwI41OH3OApDyLk3kqTJgx8+gp6On9ZEt5mYhIsKNPGuaZr3p9T6NWPKGU/03Vw4CNU9qg==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.45.1.tgz",
+ "integrity": "sha512-T5Bi/NS3fQiJeYdGvRpTAP5P02kqSOpqiopwhj0uaXB6nzs5JVi2XMJb18JUSKhCOX8+UE1UKQufyD6Or48dJg==",
"cpu": [
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.1.tgz",
- "integrity": "sha512-JYA3qvCOLXSsnTR3oiyGws1Dm0YTuxAAeaYGVlGpUsHqloPcFjPg+X0Fj2qODGLNwQOAcCiQmHub/V007kiH5A==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.45.1.tgz",
+ "integrity": "sha512-lxV2Pako3ujjuUe9jiU3/s7KSrDfH6IgTSQOnDWr9aJ92YsFd7EurmClK0ly/t8dzMkDtd04g60WX6yl0sGfdw==",
"cpu": [
"ia32"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.1.tgz",
- "integrity": "sha512-J8o22LuF0kTe7m+8PvW9wk3/bRq5+mRo5Dqo6+vXb7otCm3TPhYOJqOaQtGU9YMWQSL3krMnoOxMr0+9E6F3Ug==",
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.45.1.tgz",
+ "integrity": "sha512-M/fKi4sasCdM8i0aWJjCSFm2qEnYRR8AMLG2kxp6wD13+tMGA4Z1tVAuHkNRjud5SW2EM3naLuK35w9twvf6aA==",
"cpu": [
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"win32"
@@ -1283,6 +1352,7 @@
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
"integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/parser": "^7.20.7",
"@babel/types": "^7.20.7",
@@ -1296,6 +1366,7 @@
"resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
"integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/types": "^7.0.0"
}
@@ -1305,6 +1376,7 @@
"resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
"integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/parser": "^7.1.0",
"@babel/types": "^7.0.0"
@@ -1315,62 +1387,31 @@
"resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz",
"integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/types": "^7.20.7"
}
},
- "node_modules/@types/debug": {
- "version": "4.1.12",
- "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
- "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
- "dependencies": {
- "@types/ms": "*"
- }
- },
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
- "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="
- },
- "node_modules/@types/estree-jsx": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz",
- "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==",
- "dependencies": {
- "@types/estree": "*"
- }
- },
- "node_modules/@types/hast": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
- "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
- "dependencies": {
- "@types/unist": "*"
- }
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
- "dev": true
- },
- "node_modules/@types/mdast": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
- "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==",
- "dependencies": {
- "@types/unist": "*"
- }
- },
- "node_modules/@types/ms": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
- "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/react": {
"version": "19.1.8",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz",
"integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
"csstype": "^3.0.2"
}
@@ -1380,30 +1421,293 @@
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.6.tgz",
"integrity": "sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==",
"dev": true,
+ "license": "MIT",
"peerDependencies": {
"@types/react": "^19.0.0"
}
},
- "node_modules/@types/unist": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
- "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.38.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.38.0.tgz",
+ "integrity": "sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "8.38.0",
+ "@typescript-eslint/type-utils": "8.38.0",
+ "@typescript-eslint/utils": "8.38.0",
+ "@typescript-eslint/visitor-keys": "8.38.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^7.0.0",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.38.0",
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
},
- "node_modules/@ungap/structured-clone": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
- "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.38.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.38.0.tgz",
+ "integrity": "sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.38.0",
+ "@typescript-eslint/types": "8.38.0",
+ "@typescript-eslint/typescript-estree": "8.38.0",
+ "@typescript-eslint/visitor-keys": "8.38.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/project-service": {
+ "version": "8.38.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.38.0.tgz",
+ "integrity": "sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/tsconfig-utils": "^8.38.0",
+ "@typescript-eslint/types": "^8.38.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.38.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.38.0.tgz",
+ "integrity": "sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.38.0",
+ "@typescript-eslint/visitor-keys": "8.38.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/tsconfig-utils": {
+ "version": "8.38.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.38.0.tgz",
+ "integrity": "sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.38.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.38.0.tgz",
+ "integrity": "sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.38.0",
+ "@typescript-eslint/typescript-estree": "8.38.0",
+ "@typescript-eslint/utils": "8.38.0",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.38.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.38.0.tgz",
+ "integrity": "sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "8.38.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.38.0.tgz",
+ "integrity": "sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/project-service": "8.38.0",
+ "@typescript-eslint/tsconfig-utils": "8.38.0",
+ "@typescript-eslint/types": "8.38.0",
+ "@typescript-eslint/visitor-keys": "8.38.0",
+ "debug": "^4.3.4",
+ "fast-glob": "^3.3.2",
+ "is-glob": "^4.0.3",
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.38.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.38.0.tgz",
+ "integrity": "sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.7.0",
+ "@typescript-eslint/scope-manager": "8.38.0",
+ "@typescript-eslint/types": "8.38.0",
+ "@typescript-eslint/typescript-estree": "8.38.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.38.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.38.0.tgz",
+ "integrity": "sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.38.0",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
},
"node_modules/@vitejs/plugin-react": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.6.0.tgz",
- "integrity": "sha512-5Kgff+m8e2PB+9j51eGHEpn5kUzRKH2Ry0qGoe8ItJg7pqnkPrYPkDQZGgGmTa0EGarHrkjLvOdU3b1fzI8otQ==",
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz",
+ "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/core": "^7.27.4",
+ "@babel/core": "^7.28.0",
"@babel/plugin-transform-react-jsx-self": "^7.27.1",
"@babel/plugin-transform-react-jsx-source": "^7.27.1",
- "@rolldown/pluginutils": "1.0.0-beta.19",
+ "@rolldown/pluginutils": "1.0.0-beta.27",
"@types/babel__core": "^7.20.5",
"react-refresh": "^0.17.0"
},
@@ -1411,13 +1715,14 @@
"node": "^14.18.0 || >=16.0.0"
},
"peerDependencies": {
- "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0"
+ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
}
},
"node_modules/@xstate/react": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/@xstate/react/-/react-5.0.5.tgz",
"integrity": "sha512-MfF/cPHa3lNKJmGFpUycMbNP25qBXyZXrxc8VYNroAu0Nnk0DV5WzAkTcQXma0xEC4dSwsoA+YQuKbZATtqvgg==",
+ "license": "MIT",
"dependencies": {
"use-isomorphic-layout-effect": "^1.1.2",
"use-sync-external-store": "^1.2.0"
@@ -1436,6 +1741,7 @@
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "license": "MIT",
"dependencies": {
"mime-types": "~2.1.34",
"negotiator": "0.6.3"
@@ -1449,6 +1755,7 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
+ "license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
@@ -1461,6 +1768,7 @@
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true,
+ "license": "MIT",
"peerDependencies": {
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
@@ -1470,6 +1778,7 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -1486,6 +1795,7 @@
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
},
@@ -1500,55 +1810,53 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
+ "dev": true,
+ "license": "Python-2.0"
},
"node_modules/array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
- "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
+ "license": "MIT"
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "license": "MIT"
},
"node_modules/attr-accept": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.5.tgz",
"integrity": "sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==",
+ "license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/axios": {
- "version": "1.10.0",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz",
- "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==",
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz",
+ "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==",
+ "license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
- "form-data": "^4.0.0",
+ "form-data": "^4.0.4",
"proxy-from-env": "^1.1.0"
}
},
- "node_modules/bail": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
- "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/body-parser": {
"version": "1.20.3",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
"integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
+ "license": "MIT",
"dependencies": {
"bytes": "3.1.2",
"content-type": "~1.0.5",
@@ -1572,6 +1880,7 @@
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
@@ -1579,18 +1888,33 @@
"node_modules/body-parser/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
},
"node_modules/brace-expansion": {
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/browserslist": {
"version": "4.25.1",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz",
@@ -1610,6 +1934,7 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
"caniuse-lite": "^1.0.30001726",
"electron-to-chromium": "^1.5.173",
@@ -1626,12 +1951,14 @@
"node_modules/buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
- "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
+ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
+ "license": "BSD-3-Clause"
},
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
@@ -1640,6 +1967,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
@@ -1652,6 +1980,7 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"get-intrinsic": "^1.3.0"
@@ -1668,14 +1997,15 @@
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001726",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz",
- "integrity": "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==",
+ "version": "1.0.30001727",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz",
+ "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==",
"dev": true,
"funding": [
{
@@ -1690,22 +2020,15 @@
"type": "github",
"url": "https://github.com/sponsors/ai"
}
- ]
- },
- "node_modules/ccount": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
- "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
+ ],
+ "license": "CC-BY-4.0"
},
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
@@ -1717,47 +2040,12 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
- "node_modules/character-entities": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
- "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/character-entities-html4": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz",
- "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/character-entities-legacy": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
- "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/character-reference-invalid": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz",
- "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
@@ -1769,12 +2057,14 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
@@ -1782,25 +2072,18 @@
"node": ">= 0.8"
}
},
- "node_modules/comma-separated-tokens": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
- "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/content-disposition": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "license": "MIT",
"dependencies": {
"safe-buffer": "5.2.1"
},
@@ -1812,6 +2095,7 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -1820,12 +2104,14 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/cookie": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
"integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -1833,13 +2119,15 @@
"node_modules/cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
- "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
+ "license": "MIT"
},
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
@@ -1852,12 +2140,16 @@
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
- "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/debug": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
@@ -1870,28 +2162,18 @@
}
}
},
- "node_modules/decode-named-character-reference": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz",
- "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==",
- "dependencies": {
- "character-entities": "^2.0.0"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "license": "MIT",
"engines": {
"node": ">=0.4.0"
}
@@ -1900,43 +2182,26 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
- "node_modules/dequal": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
- "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/destroy": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "license": "MIT",
"engines": {
"node": ">= 0.8",
"npm": "1.2.8000 || >= 1.4.16"
}
},
- "node_modules/devlop": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
- "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
- "dependencies": {
- "dequal": "^2.0.0"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/dotenv": {
- "version": "16.6.0",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.0.tgz",
- "integrity": "sha512-Omf1L8paOy2VJhILjyhrhqwLIdstqm1BvcDPKg4NGAlkwEu9ODyrFbvk8UymUOMCT+HXo31jg1lArIrVAAhuGA==",
+ "version": "16.6.1",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
+ "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=12"
},
@@ -1948,6 +2213,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
@@ -1961,6 +2227,7 @@
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+ "license": "Apache-2.0",
"dependencies": {
"safe-buffer": "^5.0.1"
}
@@ -1968,18 +2235,21 @@
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "license": "MIT"
},
"node_modules/electron-to-chromium": {
- "version": "1.5.177",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.177.tgz",
- "integrity": "sha512-7EH2G59nLsEMj97fpDuvVcYi6lwTcM1xuWw3PssD8xzboAW7zj7iB3COEEEATUfjLHrs5uKBLQT03V/8URx06g==",
- "dev": true
+ "version": "1.5.191",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.191.tgz",
+ "integrity": "sha512-xcwe9ELcuxYLUFqZZxL19Z6HVKcvNkIwhbHUz7L3us6u12yR+7uY89dSl570f/IqNthx8dAw3tojG7i4Ni4tDA==",
+ "dev": true,
+ "license": "ISC"
},
"node_modules/encodeurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
@@ -1988,6 +2258,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
}
@@ -1996,6 +2267,7 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
}
@@ -2004,6 +2276,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
@@ -2015,6 +2288,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
@@ -2026,43 +2300,42 @@
}
},
"node_modules/esbuild": {
- "version": "0.25.5",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz",
- "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
"dev": true,
"hasInstallScript": true,
+ "license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
- "node": ">=18"
+ "node": ">=12"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.25.5",
- "@esbuild/android-arm": "0.25.5",
- "@esbuild/android-arm64": "0.25.5",
- "@esbuild/android-x64": "0.25.5",
- "@esbuild/darwin-arm64": "0.25.5",
- "@esbuild/darwin-x64": "0.25.5",
- "@esbuild/freebsd-arm64": "0.25.5",
- "@esbuild/freebsd-x64": "0.25.5",
- "@esbuild/linux-arm": "0.25.5",
- "@esbuild/linux-arm64": "0.25.5",
- "@esbuild/linux-ia32": "0.25.5",
- "@esbuild/linux-loong64": "0.25.5",
- "@esbuild/linux-mips64el": "0.25.5",
- "@esbuild/linux-ppc64": "0.25.5",
- "@esbuild/linux-riscv64": "0.25.5",
- "@esbuild/linux-s390x": "0.25.5",
- "@esbuild/linux-x64": "0.25.5",
- "@esbuild/netbsd-arm64": "0.25.5",
- "@esbuild/netbsd-x64": "0.25.5",
- "@esbuild/openbsd-arm64": "0.25.5",
- "@esbuild/openbsd-x64": "0.25.5",
- "@esbuild/sunos-x64": "0.25.5",
- "@esbuild/win32-arm64": "0.25.5",
- "@esbuild/win32-ia32": "0.25.5",
- "@esbuild/win32-x64": "0.25.5"
+ "@esbuild/aix-ppc64": "0.21.5",
+ "@esbuild/android-arm": "0.21.5",
+ "@esbuild/android-arm64": "0.21.5",
+ "@esbuild/android-x64": "0.21.5",
+ "@esbuild/darwin-arm64": "0.21.5",
+ "@esbuild/darwin-x64": "0.21.5",
+ "@esbuild/freebsd-arm64": "0.21.5",
+ "@esbuild/freebsd-x64": "0.21.5",
+ "@esbuild/linux-arm": "0.21.5",
+ "@esbuild/linux-arm64": "0.21.5",
+ "@esbuild/linux-ia32": "0.21.5",
+ "@esbuild/linux-loong64": "0.21.5",
+ "@esbuild/linux-mips64el": "0.21.5",
+ "@esbuild/linux-ppc64": "0.21.5",
+ "@esbuild/linux-riscv64": "0.21.5",
+ "@esbuild/linux-s390x": "0.21.5",
+ "@esbuild/linux-x64": "0.21.5",
+ "@esbuild/netbsd-x64": "0.21.5",
+ "@esbuild/openbsd-x64": "0.21.5",
+ "@esbuild/sunos-x64": "0.21.5",
+ "@esbuild/win32-arm64": "0.21.5",
+ "@esbuild/win32-ia32": "0.21.5",
+ "@esbuild/win32-x64": "0.21.5"
}
},
"node_modules/escalade": {
@@ -2070,6 +2343,7 @@
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -2077,13 +2351,15 @@
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "license": "MIT"
},
"node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10"
},
@@ -2092,18 +2368,19 @@
}
},
"node_modules/eslint": {
- "version": "9.29.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.29.0.tgz",
- "integrity": "sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==",
+ "version": "9.31.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.31.0.tgz",
+ "integrity": "sha512-QldCVh/ztyKJJZLr4jXNUByx3gR+TDYZCRXEktiZoUR3PGy4qCmSbkxcIle8GEwGpb5JBZazlaJ/CxLidXdEbQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.12.1",
- "@eslint/config-array": "^0.20.1",
- "@eslint/config-helpers": "^0.2.1",
- "@eslint/core": "^0.14.0",
+ "@eslint/config-array": "^0.21.0",
+ "@eslint/config-helpers": "^0.3.0",
+ "@eslint/core": "^0.15.0",
"@eslint/eslintrc": "^3.3.1",
- "@eslint/js": "9.29.0",
+ "@eslint/js": "9.31.0",
"@eslint/plugin-kit": "^0.3.1",
"@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1",
@@ -2156,6 +2433,7 @@
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz",
"integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10"
},
@@ -2168,6 +2446,7 @@
"resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.20.tgz",
"integrity": "sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==",
"dev": true,
+ "license": "MIT",
"peerDependencies": {
"eslint": ">=8.40"
}
@@ -2177,6 +2456,7 @@
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
"integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"esrecurse": "^4.3.0",
"estraverse": "^5.2.0"
@@ -2193,6 +2473,7 @@
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
@@ -2205,6 +2486,7 @@
"resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
"integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"acorn": "^8.15.0",
"acorn-jsx": "^5.3.2",
@@ -2222,6 +2504,7 @@
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
"integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"estraverse": "^5.1.0"
},
@@ -2234,6 +2517,7 @@
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"estraverse": "^5.2.0"
},
@@ -2246,24 +2530,17 @@
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
}
},
- "node_modules/estree-util-is-identifier-name": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz",
- "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
"node_modules/esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true,
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=0.10.0"
}
@@ -2272,6 +2549,7 @@
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -2280,6 +2558,7 @@
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
"integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
+ "license": "MIT",
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
@@ -2325,6 +2604,7 @@
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
@@ -2332,43 +2612,68 @@
"node_modules/express/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
- },
- "node_modules/extend": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
- "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "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",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
},
"node_modules/fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
- "dev": true
- },
- "node_modules/fdir": {
- "version": "6.4.6",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
- "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==",
"dev": true,
- "peerDependencies": {
- "picomatch": "^3 || ^4"
- },
- "peerDependenciesMeta": {
- "picomatch": {
- "optional": true
- }
+ "license": "MIT"
+ },
+ "node_modules/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
}
},
"node_modules/file-entry-cache": {
@@ -2376,6 +2681,7 @@
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
"integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"flat-cache": "^4.0.0"
},
@@ -2387,6 +2693,7 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/file-selector/-/file-selector-2.1.2.tgz",
"integrity": "sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==",
+ "license": "MIT",
"dependencies": {
"tslib": "^2.7.0"
},
@@ -2394,10 +2701,24 @@
"node": ">= 12"
}
},
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/finalhandler": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
"integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
+ "license": "MIT",
"dependencies": {
"debug": "2.6.9",
"encodeurl": "~2.0.0",
@@ -2415,6 +2736,7 @@
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
@@ -2422,13 +2744,15 @@
"node_modules/finalhandler/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
},
"node_modules/find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"locate-path": "^6.0.0",
"path-exists": "^4.0.0"
@@ -2445,6 +2769,7 @@
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
"integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"flatted": "^3.2.9",
"keyv": "^4.5.4"
@@ -2457,7 +2782,8 @@
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
"integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/follow-redirects": {
"version": "1.15.9",
@@ -2469,6 +2795,7 @@
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
+ "license": "MIT",
"engines": {
"node": ">=4.0"
},
@@ -2479,9 +2806,10 @@
}
},
"node_modules/form-data": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz",
- "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
+ "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
+ "license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
@@ -2497,17 +2825,19 @@
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/framer-motion": {
- "version": "12.19.2",
- "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.19.2.tgz",
- "integrity": "sha512-0cWMLkYr+i0emeXC4hkLF+5aYpzo32nRdQ0D/5DI460B3O7biQ3l2BpDzIGsAHYuZ0fpBP0DC8XBkVf6RPAlZw==",
+ "version": "12.23.9",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.9.tgz",
+ "integrity": "sha512-TqEHXj8LWfQSKqfdr5Y4mYltYLw96deu6/K9kGDd+ysqRJPNwF9nb5mZcrLmybHbU7gcJ+HQar41U3UTGanbbQ==",
+ "license": "MIT",
"dependencies": {
- "motion-dom": "^12.19.0",
- "motion-utils": "^12.19.0",
+ "motion-dom": "^12.23.9",
+ "motion-utils": "^12.23.6",
"tslib": "^2.4.0"
},
"peerDependencies": {
@@ -2531,6 +2861,7 @@
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -2538,7 +2869,8 @@
"node_modules/fs": {
"version": "0.0.1-security",
"resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz",
- "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w=="
+ "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==",
+ "license": "ISC"
},
"node_modules/fsevents": {
"version": "2.3.3",
@@ -2546,6 +2878,7 @@
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
"hasInstallScript": true,
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
@@ -2558,6 +2891,7 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -2567,6 +2901,7 @@
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
@@ -2575,6 +2910,7 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
@@ -2598,6 +2934,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
@@ -2611,6 +2948,7 @@
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"is-glob": "^4.0.3"
},
@@ -2619,10 +2957,11 @@
}
},
"node_modules/globals": {
- "version": "15.15.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz",
- "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==",
+ "version": "16.3.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-16.3.0.tgz",
+ "integrity": "sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=18"
},
@@ -2634,6 +2973,7 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -2641,11 +2981,19 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -2654,6 +3002,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -2665,6 +3014,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
@@ -2679,6 +3029,7 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
@@ -2686,57 +3037,11 @@
"node": ">= 0.4"
}
},
- "node_modules/hast-util-to-jsx-runtime": {
- "version": "2.3.6",
- "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz",
- "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==",
- "dependencies": {
- "@types/estree": "^1.0.0",
- "@types/hast": "^3.0.0",
- "@types/unist": "^3.0.0",
- "comma-separated-tokens": "^2.0.0",
- "devlop": "^1.0.0",
- "estree-util-is-identifier-name": "^3.0.0",
- "hast-util-whitespace": "^3.0.0",
- "mdast-util-mdx-expression": "^2.0.0",
- "mdast-util-mdx-jsx": "^3.0.0",
- "mdast-util-mdxjs-esm": "^2.0.0",
- "property-information": "^7.0.0",
- "space-separated-tokens": "^2.0.0",
- "style-to-js": "^1.0.0",
- "unist-util-position": "^5.0.0",
- "vfile-message": "^4.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/hast-util-whitespace": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz",
- "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==",
- "dependencies": {
- "@types/hast": "^3.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/html-url-attributes": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz",
- "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
"node_modules/http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "license": "MIT",
"dependencies": {
"depd": "2.0.0",
"inherits": "2.0.4",
@@ -2752,6 +3057,7 @@
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3"
},
@@ -2764,6 +3070,7 @@
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 4"
}
@@ -2773,6 +3080,7 @@
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
"integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
@@ -2789,6 +3097,7 @@
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.8.19"
}
@@ -2796,57 +3105,24 @@
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
- },
- "node_modules/inline-style-parser": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz",
- "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q=="
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
},
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "license": "MIT",
"engines": {
"node": ">= 0.10"
}
},
- "node_modules/is-alphabetical": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
- "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/is-alphanumerical": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
- "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
- "dependencies": {
- "is-alphabetical": "^2.0.0",
- "is-decimal": "^2.0.0"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/is-decimal": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz",
- "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -2856,6 +3132,7 @@
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"is-extglob": "^2.1.1"
},
@@ -2863,36 +3140,28 @@
"node": ">=0.10.0"
}
},
- "node_modules/is-hexadecimal": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz",
- "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/is-plain-obj": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
- "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": ">=0.12.0"
}
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"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"
}
@@ -2900,13 +3169,15 @@
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "license": "MIT"
},
"node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
},
@@ -2919,6 +3190,7 @@
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
"integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
"dev": true,
+ "license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
},
@@ -2930,25 +3202,29 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/json-stable-stringify-without-jsonify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/json5": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true,
+ "license": "MIT",
"bin": {
"json5": "lib/cli.js"
},
@@ -2960,6 +3236,7 @@
"version": "9.0.2",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
"integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
+ "license": "MIT",
"dependencies": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
@@ -2981,6 +3258,7 @@
"version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
@@ -2992,6 +3270,7 @@
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz",
"integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==",
+ "license": "MIT",
"dependencies": {
"buffer-equal-constant-time": "^1.0.1",
"ecdsa-sig-formatter": "1.0.11",
@@ -3002,6 +3281,7 @@
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+ "license": "MIT",
"dependencies": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
@@ -3011,6 +3291,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz",
"integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==",
+ "license": "MIT",
"engines": {
"node": ">=18"
}
@@ -3020,6 +3301,7 @@
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"json-buffer": "3.0.1"
}
@@ -3029,6 +3311,7 @@
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"prelude-ls": "^1.2.1",
"type-check": "~0.4.0"
@@ -3042,6 +3325,7 @@
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"p-locate": "^5.0.0"
},
@@ -3055,57 +3339,57 @@
"node_modules/lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
- "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
+ "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
+ "license": "MIT"
},
"node_modules/lodash.isboolean": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
- "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
+ "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
+ "license": "MIT"
},
"node_modules/lodash.isinteger": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
- "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
+ "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
+ "license": "MIT"
},
"node_modules/lodash.isnumber": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
- "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
+ "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
+ "license": "MIT"
},
"node_modules/lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
- "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
+ "license": "MIT"
},
"node_modules/lodash.isstring": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
- "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
+ "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
+ "license": "MIT"
},
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
- "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
- },
- "node_modules/longest-streak": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
- "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
+ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
+ "license": "MIT"
},
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "license": "MIT",
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
},
@@ -3118,6 +3402,7 @@
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"yallist": "^3.0.2"
}
@@ -3126,159 +3411,16 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
- "node_modules/mdast-util-from-markdown": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz",
- "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==",
- "dependencies": {
- "@types/mdast": "^4.0.0",
- "@types/unist": "^3.0.0",
- "decode-named-character-reference": "^1.0.0",
- "devlop": "^1.0.0",
- "mdast-util-to-string": "^4.0.0",
- "micromark": "^4.0.0",
- "micromark-util-decode-numeric-character-reference": "^2.0.0",
- "micromark-util-decode-string": "^2.0.0",
- "micromark-util-normalize-identifier": "^2.0.0",
- "micromark-util-symbol": "^2.0.0",
- "micromark-util-types": "^2.0.0",
- "unist-util-stringify-position": "^4.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-mdx-expression": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz",
- "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==",
- "dependencies": {
- "@types/estree-jsx": "^1.0.0",
- "@types/hast": "^3.0.0",
- "@types/mdast": "^4.0.0",
- "devlop": "^1.0.0",
- "mdast-util-from-markdown": "^2.0.0",
- "mdast-util-to-markdown": "^2.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-mdx-jsx": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz",
- "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==",
- "dependencies": {
- "@types/estree-jsx": "^1.0.0",
- "@types/hast": "^3.0.0",
- "@types/mdast": "^4.0.0",
- "@types/unist": "^3.0.0",
- "ccount": "^2.0.0",
- "devlop": "^1.1.0",
- "mdast-util-from-markdown": "^2.0.0",
- "mdast-util-to-markdown": "^2.0.0",
- "parse-entities": "^4.0.0",
- "stringify-entities": "^4.0.0",
- "unist-util-stringify-position": "^4.0.0",
- "vfile-message": "^4.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-mdxjs-esm": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz",
- "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==",
- "dependencies": {
- "@types/estree-jsx": "^1.0.0",
- "@types/hast": "^3.0.0",
- "@types/mdast": "^4.0.0",
- "devlop": "^1.0.0",
- "mdast-util-from-markdown": "^2.0.0",
- "mdast-util-to-markdown": "^2.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-phrasing": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz",
- "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==",
- "dependencies": {
- "@types/mdast": "^4.0.0",
- "unist-util-is": "^6.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-to-hast": {
- "version": "13.2.0",
- "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz",
- "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==",
- "dependencies": {
- "@types/hast": "^3.0.0",
- "@types/mdast": "^4.0.0",
- "@ungap/structured-clone": "^1.0.0",
- "devlop": "^1.0.0",
- "micromark-util-sanitize-uri": "^2.0.0",
- "trim-lines": "^3.0.0",
- "unist-util-position": "^5.0.0",
- "unist-util-visit": "^5.0.0",
- "vfile": "^6.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-to-markdown": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz",
- "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==",
- "dependencies": {
- "@types/mdast": "^4.0.0",
- "@types/unist": "^3.0.0",
- "longest-streak": "^3.0.0",
- "mdast-util-phrasing": "^4.0.0",
- "mdast-util-to-string": "^4.0.0",
- "micromark-util-classify-character": "^2.0.0",
- "micromark-util-decode-string": "^2.0.0",
- "unist-util-visit": "^5.0.0",
- "zwitch": "^2.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-to-string": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz",
- "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==",
- "dependencies": {
- "@types/mdast": "^4.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -3287,443 +3429,49 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
"integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
+ "license": "MIT",
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
- "node_modules/micromark": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz",
- "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "@types/debug": "^4.0.0",
- "debug": "^4.0.0",
- "decode-named-character-reference": "^1.0.0",
- "devlop": "^1.0.0",
- "micromark-core-commonmark": "^2.0.0",
- "micromark-factory-space": "^2.0.0",
- "micromark-util-character": "^2.0.0",
- "micromark-util-chunked": "^2.0.0",
- "micromark-util-combine-extensions": "^2.0.0",
- "micromark-util-decode-numeric-character-reference": "^2.0.0",
- "micromark-util-encode": "^2.0.0",
- "micromark-util-normalize-identifier": "^2.0.0",
- "micromark-util-resolve-all": "^2.0.0",
- "micromark-util-sanitize-uri": "^2.0.0",
- "micromark-util-subtokenize": "^2.0.0",
- "micromark-util-symbol": "^2.0.0",
- "micromark-util-types": "^2.0.0"
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
}
},
- "node_modules/micromark-core-commonmark": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz",
- "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "decode-named-character-reference": "^1.0.0",
- "devlop": "^1.0.0",
- "micromark-factory-destination": "^2.0.0",
- "micromark-factory-label": "^2.0.0",
- "micromark-factory-space": "^2.0.0",
- "micromark-factory-title": "^2.0.0",
- "micromark-factory-whitespace": "^2.0.0",
- "micromark-util-character": "^2.0.0",
- "micromark-util-chunked": "^2.0.0",
- "micromark-util-classify-character": "^2.0.0",
- "micromark-util-html-tag-name": "^2.0.0",
- "micromark-util-normalize-identifier": "^2.0.0",
- "micromark-util-resolve-all": "^2.0.0",
- "micromark-util-subtokenize": "^2.0.0",
- "micromark-util-symbol": "^2.0.0",
- "micromark-util-types": "^2.0.0"
- }
- },
- "node_modules/micromark-factory-destination": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz",
- "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-character": "^2.0.0",
- "micromark-util-symbol": "^2.0.0",
- "micromark-util-types": "^2.0.0"
- }
- },
- "node_modules/micromark-factory-label": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz",
- "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "devlop": "^1.0.0",
- "micromark-util-character": "^2.0.0",
- "micromark-util-symbol": "^2.0.0",
- "micromark-util-types": "^2.0.0"
- }
- },
- "node_modules/micromark-factory-space": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
- "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-character": "^2.0.0",
- "micromark-util-types": "^2.0.0"
- }
- },
- "node_modules/micromark-factory-title": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz",
- "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-factory-space": "^2.0.0",
- "micromark-util-character": "^2.0.0",
- "micromark-util-symbol": "^2.0.0",
- "micromark-util-types": "^2.0.0"
- }
- },
- "node_modules/micromark-factory-whitespace": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz",
- "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-factory-space": "^2.0.0",
- "micromark-util-character": "^2.0.0",
- "micromark-util-symbol": "^2.0.0",
- "micromark-util-types": "^2.0.0"
- }
- },
- "node_modules/micromark-util-character": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
- "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-symbol": "^2.0.0",
- "micromark-util-types": "^2.0.0"
- }
- },
- "node_modules/micromark-util-chunked": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz",
- "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-symbol": "^2.0.0"
- }
- },
- "node_modules/micromark-util-classify-character": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz",
- "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-character": "^2.0.0",
- "micromark-util-symbol": "^2.0.0",
- "micromark-util-types": "^2.0.0"
- }
- },
- "node_modules/micromark-util-combine-extensions": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz",
- "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-chunked": "^2.0.0",
- "micromark-util-types": "^2.0.0"
- }
- },
- "node_modules/micromark-util-decode-numeric-character-reference": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz",
- "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-symbol": "^2.0.0"
- }
- },
- "node_modules/micromark-util-decode-string": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz",
- "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "decode-named-character-reference": "^1.0.0",
- "micromark-util-character": "^2.0.0",
- "micromark-util-decode-numeric-character-reference": "^2.0.0",
- "micromark-util-symbol": "^2.0.0"
- }
- },
- "node_modules/micromark-util-encode": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
- "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ]
- },
- "node_modules/micromark-util-html-tag-name": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz",
- "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ]
- },
- "node_modules/micromark-util-normalize-identifier": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz",
- "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-symbol": "^2.0.0"
- }
- },
- "node_modules/micromark-util-resolve-all": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz",
- "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-types": "^2.0.0"
- }
- },
- "node_modules/micromark-util-sanitize-uri": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
- "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-character": "^2.0.0",
- "micromark-util-encode": "^2.0.0",
- "micromark-util-symbol": "^2.0.0"
- }
- },
- "node_modules/micromark-util-subtokenize": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz",
- "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "devlop": "^1.0.0",
- "micromark-util-chunked": "^2.0.0",
- "micromark-util-symbol": "^2.0.0",
- "micromark-util-types": "^2.0.0"
- }
- },
- "node_modules/micromark-util-symbol": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
- "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ]
- },
- "node_modules/micromark-util-types": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz",
- "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ]
- },
"node_modules/mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "license": "MIT",
"bin": {
"mime": "cli.js"
},
@@ -3735,6 +3483,7 @@
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -3743,6 +3492,7 @@
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
@@ -3755,6 +3505,7 @@
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -3763,11 +3514,12 @@
}
},
"node_modules/motion": {
- "version": "12.19.2",
- "resolved": "https://registry.npmjs.org/motion/-/motion-12.19.2.tgz",
- "integrity": "sha512-Yb69HXE4ryhVd1xwpgWMMQAQgqEGMSGWG+NOumans2fvSCtT8gsj8JK7jhcGnc410CLT3BFPgquP67zmjbA5Jw==",
+ "version": "12.23.9",
+ "resolved": "https://registry.npmjs.org/motion/-/motion-12.23.9.tgz",
+ "integrity": "sha512-5PDgsbNtZ4cpfew3STYL0p06rIiy8vOveQuQBXUAa2+m1WMzjf65DXYn6eo88dM2s+XLxAQq3ZiOjcnKMACEtQ==",
+ "license": "MIT",
"dependencies": {
- "framer-motion": "^12.19.2",
+ "framer-motion": "^12.23.9",
"tslib": "^2.4.0"
},
"peerDependencies": {
@@ -3788,22 +3540,25 @@
}
},
"node_modules/motion-dom": {
- "version": "12.19.0",
- "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.19.0.tgz",
- "integrity": "sha512-m96uqq8VbwxFLU0mtmlsIVe8NGGSdpBvBSHbnnOJQxniPaabvVdGgxSamhuDwBsRhwX7xPxdICgVJlOpzn/5bw==",
+ "version": "12.23.9",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.9.tgz",
+ "integrity": "sha512-6Sv++iWS8XMFCgU1qwKj9l4xuC47Hp4+2jvPfyTXkqDg2tTzSgX6nWKD4kNFXk0k7llO59LZTPuJigza4A2K1A==",
+ "license": "MIT",
"dependencies": {
- "motion-utils": "^12.19.0"
+ "motion-utils": "^12.23.6"
}
},
"node_modules/motion-utils": {
- "version": "12.19.0",
- "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.19.0.tgz",
- "integrity": "sha512-BuFTHINYmV07pdWs6lj6aI63vr2N4dg0vR+td0rtrdpWOhBzIkEklZyLcvKBoEtwSqx8Jg06vUB5RS0xDiUybw=="
+ "version": "12.23.6",
+ "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.23.6.tgz",
+ "integrity": "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==",
+ "license": "MIT"
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
},
"node_modules/nanoid": {
"version": "3.3.11",
@@ -3816,6 +3571,7 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
@@ -3827,12 +3583,14 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -3841,12 +3599,14 @@
"version": "2.0.19",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
"integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -3855,6 +3615,7 @@
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -3866,6 +3627,7 @@
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "license": "MIT",
"dependencies": {
"ee-first": "1.1.1"
},
@@ -3878,6 +3640,7 @@
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
"integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"deep-is": "^0.1.3",
"fast-levenshtein": "^2.0.6",
@@ -3895,6 +3658,7 @@
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"yocto-queue": "^0.1.0"
},
@@ -3910,6 +3674,7 @@
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"p-limit": "^3.0.2"
},
@@ -3925,6 +3690,7 @@
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"callsites": "^3.0.0"
},
@@ -3932,33 +3698,11 @@
"node": ">=6"
}
},
- "node_modules/parse-entities": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz",
- "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==",
- "dependencies": {
- "@types/unist": "^2.0.0",
- "character-entities-legacy": "^3.0.0",
- "character-reference-invalid": "^2.0.0",
- "decode-named-character-reference": "^1.0.0",
- "is-alphanumerical": "^2.0.0",
- "is-decimal": "^2.0.0",
- "is-hexadecimal": "^2.0.0"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/parse-entities/node_modules/@types/unist": {
- "version": "2.0.11",
- "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
- "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="
- },
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
@@ -3968,6 +3712,7 @@
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -3977,6 +3722,7 @@
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -3984,16 +3730,18 @@
"node_modules/path-to-regexp": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
- "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="
+ "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
+ "license": "MIT"
},
"node_modules/pg": {
- "version": "8.16.2",
- "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.2.tgz",
- "integrity": "sha512-OtLWF0mKLmpxelOt9BqVq83QV6bTfsS0XLegIeAKqKjurRnRKie1Dc1iL89MugmSLhftxw6NNCyZhm1yQFLMEQ==",
+ "version": "8.16.3",
+ "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz",
+ "integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==",
+ "license": "MIT",
"dependencies": {
"pg-connection-string": "^2.9.1",
"pg-pool": "^3.10.1",
- "pg-protocol": "^1.10.2",
+ "pg-protocol": "^1.10.3",
"pg-types": "2.2.0",
"pgpass": "1.0.5"
},
@@ -4001,7 +3749,7 @@
"node": ">= 16.0.0"
},
"optionalDependencies": {
- "pg-cloudflare": "^1.2.6"
+ "pg-cloudflare": "^1.2.7"
},
"peerDependencies": {
"pg-native": ">=3.0.1"
@@ -4013,20 +3761,23 @@
}
},
"node_modules/pg-cloudflare": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.6.tgz",
- "integrity": "sha512-uxmJAnmIgmYgnSFzgOf2cqGQBzwnRYcrEgXuFjJNEkpedEIPBSEzxY7ph4uA9k1mI+l/GR0HjPNS6FKNZe8SBQ==",
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz",
+ "integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==",
+ "license": "MIT",
"optional": true
},
"node_modules/pg-connection-string": {
"version": "2.9.1",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz",
- "integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w=="
+ "integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==",
+ "license": "MIT"
},
"node_modules/pg-int8": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
+ "license": "ISC",
"engines": {
"node": ">=4.0.0"
}
@@ -4035,19 +3786,22 @@
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.1.tgz",
"integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==",
+ "license": "MIT",
"peerDependencies": {
"pg": ">=8.0"
}
},
"node_modules/pg-protocol": {
- "version": "1.10.2",
- "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.2.tgz",
- "integrity": "sha512-Ci7jy8PbaWxfsck2dwZdERcDG2A0MG8JoQILs+uZNjABFuBuItAZCWUNz8sXRDMoui24rJw7WlXqgpMdBSN/vQ=="
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz",
+ "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==",
+ "license": "MIT"
},
"node_modules/pg-types": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
+ "license": "MIT",
"dependencies": {
"pg-int8": "1.0.1",
"postgres-array": "~2.0.0",
@@ -4063,6 +3817,7 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
"integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
+ "license": "MIT",
"dependencies": {
"split2": "^4.1.0"
}
@@ -4071,15 +3826,17 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/picomatch": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
- "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=12"
+ "node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
@@ -4104,6 +3861,7 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -4117,6 +3875,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -4125,6 +3884,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
"integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -4133,6 +3893,7 @@
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -4141,6 +3902,7 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
+ "license": "MIT",
"dependencies": {
"xtend": "^4.0.0"
},
@@ -4153,6 +3915,7 @@
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.8.0"
}
@@ -4161,25 +3924,18 @@
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "license": "MIT",
"dependencies": {
"loose-envify": "^1.4.0",
"object-assign": "^4.1.1",
"react-is": "^16.13.1"
}
},
- "node_modules/property-information": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz",
- "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "license": "MIT",
"dependencies": {
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
@@ -4191,13 +3947,15 @@
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "license": "MIT"
},
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -4206,6 +3964,7 @@
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
+ "license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.0.6"
},
@@ -4216,10 +3975,32 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "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/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -4228,6 +4009,7 @@
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+ "license": "MIT",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
@@ -4242,6 +4024,7 @@
"version": "19.1.0",
"resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
"integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -4250,6 +4033,7 @@
"version": "19.1.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
"integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
+ "license": "MIT",
"dependencies": {
"scheduler": "^0.26.0"
},
@@ -4261,6 +4045,7 @@
"version": "14.3.8",
"resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.3.8.tgz",
"integrity": "sha512-sBgODnq+lcA4P296DY4wacOZz3JFpD99fp+hb//iBO2HHnyeZU3FwWyXJ6salNpqQdsZrgMrotuko/BdJMV8Ug==",
+ "license": "MIT",
"dependencies": {
"attr-accept": "^2.2.4",
"file-selector": "^2.1.0",
@@ -4277,6 +4062,7 @@
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
"integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==",
+ "license": "MIT",
"peerDependencies": {
"react": "*"
}
@@ -4284,47 +4070,24 @@
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
- },
- "node_modules/react-markdown": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz",
- "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==",
- "dependencies": {
- "@types/hast": "^3.0.0",
- "@types/mdast": "^4.0.0",
- "devlop": "^1.0.0",
- "hast-util-to-jsx-runtime": "^2.0.0",
- "html-url-attributes": "^3.0.0",
- "mdast-util-to-hast": "^13.0.0",
- "remark-parse": "^11.0.0",
- "remark-rehype": "^11.0.0",
- "unified": "^11.0.0",
- "unist-util-visit": "^5.0.0",
- "vfile": "^6.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- },
- "peerDependencies": {
- "@types/react": ">=18",
- "react": ">=18"
- }
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "license": "MIT"
},
"node_modules/react-refresh": {
"version": "0.17.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
"integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-router": {
- "version": "7.6.2",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.6.2.tgz",
- "integrity": "sha512-U7Nv3y+bMimgWjhlT5CRdzHPu2/KVmqPwKUCChW8en5P3znxUqwlYFlbmyj8Rgp1SF6zs5X4+77kBVknkg6a0w==",
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.7.1.tgz",
+ "integrity": "sha512-jVKHXoWRIsD/qS6lvGveckwb862EekvapdHJN/cGmzw40KnJH5gg53ujOJ4qX6EKIK9LSBfFed/xiQ5yeXNrUA==",
+ "license": "MIT",
"dependencies": {
"cookie": "^1.0.1",
"set-cookie-parser": "^2.6.0"
@@ -4343,11 +4106,12 @@
}
},
"node_modules/react-router-dom": {
- "version": "7.6.2",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.6.2.tgz",
- "integrity": "sha512-Q8zb6VlTbdYKK5JJBLQEN06oTUa/RAbG/oQS1auK1I0TbJOXktqm+QENEVJU6QvWynlXPRBXI3fiOQcSEA78rA==",
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.7.1.tgz",
+ "integrity": "sha512-bavdk2BA5r3MYalGKZ01u8PGuDBloQmzpBZVhDLrOOv1N943Wq6dcM9GhB3x8b7AbqPMEezauv4PeGkAJfy7FQ==",
+ "license": "MIT",
"dependencies": {
- "react-router": "7.6.2"
+ "react-router": "7.7.1"
},
"engines": {
"node": ">=20.0.0"
@@ -4361,55 +4125,38 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
"integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
+ "license": "MIT",
"engines": {
"node": ">=18"
}
},
- "node_modules/remark-parse": {
- "version": "11.0.0",
- "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz",
- "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==",
- "dependencies": {
- "@types/mdast": "^4.0.0",
- "mdast-util-from-markdown": "^2.0.0",
- "micromark-util-types": "^2.0.0",
- "unified": "^11.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/remark-rehype": {
- "version": "11.1.2",
- "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz",
- "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==",
- "dependencies": {
- "@types/hast": "^3.0.0",
- "@types/mdast": "^4.0.0",
- "mdast-util-to-hast": "^13.0.0",
- "unified": "^11.0.0",
- "vfile": "^6.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
"node_modules/resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
},
- "node_modules/rollup": {
- "version": "4.44.1",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.1.tgz",
- "integrity": "sha512-x8H8aPvD+xbl0Do8oez5f5o8eMS3trfCghc4HhLAnCkj7Vl0d1JWGs0UF/D886zLW2rOj2QymV/JcSSsw+XDNg==",
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
"dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.45.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.45.1.tgz",
+ "integrity": "sha512-4iya7Jb76fVpQyLoiVpzUrsjQ12r3dM7fIVz+4NwoYvZOShknRmiv+iu9CClZml5ZLGb0XMcYLutK6w9tgxHDw==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
"@types/estree": "1.0.8"
},
@@ -4421,29 +4168,53 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.44.1",
- "@rollup/rollup-android-arm64": "4.44.1",
- "@rollup/rollup-darwin-arm64": "4.44.1",
- "@rollup/rollup-darwin-x64": "4.44.1",
- "@rollup/rollup-freebsd-arm64": "4.44.1",
- "@rollup/rollup-freebsd-x64": "4.44.1",
- "@rollup/rollup-linux-arm-gnueabihf": "4.44.1",
- "@rollup/rollup-linux-arm-musleabihf": "4.44.1",
- "@rollup/rollup-linux-arm64-gnu": "4.44.1",
- "@rollup/rollup-linux-arm64-musl": "4.44.1",
- "@rollup/rollup-linux-loongarch64-gnu": "4.44.1",
- "@rollup/rollup-linux-powerpc64le-gnu": "4.44.1",
- "@rollup/rollup-linux-riscv64-gnu": "4.44.1",
- "@rollup/rollup-linux-riscv64-musl": "4.44.1",
- "@rollup/rollup-linux-s390x-gnu": "4.44.1",
- "@rollup/rollup-linux-x64-gnu": "4.44.1",
- "@rollup/rollup-linux-x64-musl": "4.44.1",
- "@rollup/rollup-win32-arm64-msvc": "4.44.1",
- "@rollup/rollup-win32-ia32-msvc": "4.44.1",
- "@rollup/rollup-win32-x64-msvc": "4.44.1",
+ "@rollup/rollup-android-arm-eabi": "4.45.1",
+ "@rollup/rollup-android-arm64": "4.45.1",
+ "@rollup/rollup-darwin-arm64": "4.45.1",
+ "@rollup/rollup-darwin-x64": "4.45.1",
+ "@rollup/rollup-freebsd-arm64": "4.45.1",
+ "@rollup/rollup-freebsd-x64": "4.45.1",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.45.1",
+ "@rollup/rollup-linux-arm-musleabihf": "4.45.1",
+ "@rollup/rollup-linux-arm64-gnu": "4.45.1",
+ "@rollup/rollup-linux-arm64-musl": "4.45.1",
+ "@rollup/rollup-linux-loongarch64-gnu": "4.45.1",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.45.1",
+ "@rollup/rollup-linux-riscv64-gnu": "4.45.1",
+ "@rollup/rollup-linux-riscv64-musl": "4.45.1",
+ "@rollup/rollup-linux-s390x-gnu": "4.45.1",
+ "@rollup/rollup-linux-x64-gnu": "4.45.1",
+ "@rollup/rollup-linux-x64-musl": "4.45.1",
+ "@rollup/rollup-win32-arm64-msvc": "4.45.1",
+ "@rollup/rollup-win32-ia32-msvc": "4.45.1",
+ "@rollup/rollup-win32-x64-msvc": "4.45.1",
"fsevents": "~2.3.2"
}
},
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "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",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -4461,23 +4232,27 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ]
+ ],
+ "license": "MIT"
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "license": "MIT"
},
"node_modules/scheduler": {
"version": "0.26.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
- "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="
+ "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
+ "license": "MIT"
},
"node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
}
@@ -4486,6 +4261,7 @@
"version": "0.19.0",
"resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
"integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
+ "license": "MIT",
"dependencies": {
"debug": "2.6.9",
"depd": "2.0.0",
@@ -4509,6 +4285,7 @@
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
@@ -4516,12 +4293,14 @@
"node_modules/send/node_modules/debug/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
},
"node_modules/send/node_modules/encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
@@ -4530,6 +4309,7 @@
"version": "1.16.2",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
"integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
+ "license": "MIT",
"dependencies": {
"encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
@@ -4543,18 +4323,21 @@
"node_modules/set-cookie-parser": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
- "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ=="
+ "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
+ "license": "MIT"
},
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "license": "ISC"
},
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
},
@@ -4567,6 +4350,7 @@
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -4575,6 +4359,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3",
@@ -4593,6 +4378,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3"
@@ -4608,6 +4394,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
@@ -4625,6 +4412,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
@@ -4644,23 +4432,16 @@
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true,
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
- "node_modules/space-separated-tokens": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
- "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/split2": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "license": "ISC",
"engines": {
"node": ">= 10.x"
}
@@ -4669,28 +4450,17 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
- "node_modules/stringify-entities": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz",
- "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==",
- "dependencies": {
- "character-entities-html4": "^2.0.0",
- "character-entities-legacy": "^3.0.0"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
},
@@ -4698,27 +4468,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/style-to-js": {
- "version": "1.1.17",
- "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.17.tgz",
- "integrity": "sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==",
- "dependencies": {
- "style-to-object": "1.0.9"
- }
- },
- "node_modules/style-to-object": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.9.tgz",
- "integrity": "sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==",
- "dependencies": {
- "inline-style-parser": "0.2.4"
- }
- },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -4726,58 +4481,53 @@
"node": ">=8"
}
},
- "node_modules/tinyglobby": {
- "version": "0.2.14",
- "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
- "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==",
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "fdir": "^6.4.4",
- "picomatch": "^4.0.2"
+ "is-number": "^7.0.0"
},
"engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/SuperchupuDev"
+ "node": ">=8.0"
}
},
"node_modules/toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "license": "MIT",
"engines": {
"node": ">=0.6"
}
},
- "node_modules/trim-lines": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
- "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/trough": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz",
- "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
+ "node_modules/ts-api-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
+ "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
}
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
- "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
},
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"prelude-ls": "^1.2.1"
},
@@ -4789,6 +4539,7 @@
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "license": "MIT",
"dependencies": {
"media-typer": "0.3.0",
"mime-types": "~2.1.24"
@@ -4797,91 +4548,49 @@
"node": ">= 0.6"
}
},
- "node_modules/unified": {
- "version": "11.0.5",
- "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz",
- "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==",
- "dependencies": {
- "@types/unist": "^3.0.0",
- "bail": "^2.0.0",
- "devlop": "^1.0.0",
- "extend": "^3.0.0",
- "is-plain-obj": "^4.0.0",
- "trough": "^2.0.0",
- "vfile": "^6.0.0"
+ "node_modules/typescript": {
+ "version": "5.8.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
+ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
+ "engines": {
+ "node": ">=14.17"
}
},
- "node_modules/unist-util-is": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz",
- "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==",
+ "node_modules/typescript-eslint": {
+ "version": "8.38.0",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.38.0.tgz",
+ "integrity": "sha512-FsZlrYK6bPDGoLeZRuvx2v6qrM03I0U0SnfCLPs/XCCPCFD80xU9Pg09H/K+XFa68uJuZo7l/Xhs+eDRg2l3hg==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "@types/unist": "^3.0.0"
+ "@typescript-eslint/eslint-plugin": "8.38.0",
+ "@typescript-eslint/parser": "8.38.0",
+ "@typescript-eslint/typescript-estree": "8.38.0",
+ "@typescript-eslint/utils": "8.38.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/unist-util-position": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz",
- "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==",
- "dependencies": {
- "@types/unist": "^3.0.0"
+ "url": "https://opencollective.com/typescript-eslint"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/unist-util-stringify-position": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz",
- "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==",
- "dependencies": {
- "@types/unist": "^3.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/unist-util-visit": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz",
- "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==",
- "dependencies": {
- "@types/unist": "^3.0.0",
- "unist-util-is": "^6.0.0",
- "unist-util-visit-parents": "^6.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/unist-util-visit-parents": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz",
- "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==",
- "dependencies": {
- "@types/unist": "^3.0.0",
- "unist-util-is": "^6.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
@@ -4905,6 +4614,7 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
"escalade": "^3.2.0",
"picocolors": "^1.1.1"
@@ -4921,6 +4631,7 @@
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"punycode": "^2.1.0"
}
@@ -4929,6 +4640,7 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.1.tgz",
"integrity": "sha512-tpZZ+EX0gaghDAiFR37hj5MgY6ZN55kLiPkJsKxBMZ6GZdOSPJXiOzPM984oPYZ5AnehYx5WQp1+ME8I/P/pRA==",
+ "license": "MIT",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
},
@@ -4942,6 +4654,7 @@
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
"integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
+ "license": "MIT",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
@@ -4950,6 +4663,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4.0"
}
@@ -4958,54 +4672,27 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
- "node_modules/vfile": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz",
- "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==",
- "dependencies": {
- "@types/unist": "^3.0.0",
- "vfile-message": "^4.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/vfile-message": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz",
- "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==",
- "dependencies": {
- "@types/unist": "^3.0.0",
- "unist-util-stringify-position": "^4.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
"node_modules/vite": {
- "version": "6.3.5",
- "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",
- "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==",
+ "version": "5.4.19",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz",
+ "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "esbuild": "^0.25.0",
- "fdir": "^6.4.4",
- "picomatch": "^4.0.2",
- "postcss": "^8.5.3",
- "rollup": "^4.34.9",
- "tinyglobby": "^0.2.13"
+ "esbuild": "^0.21.3",
+ "postcss": "^8.4.43",
+ "rollup": "^4.20.0"
},
"bin": {
"vite": "bin/vite.js"
},
"engines": {
- "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ "node": "^18.0.0 || >=20.0.0"
},
"funding": {
"url": "https://github.com/vitejs/vite?sponsor=1"
@@ -5014,25 +4701,19 @@
"fsevents": "~2.3.3"
},
"peerDependencies": {
- "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
- "jiti": ">=1.21.0",
+ "@types/node": "^18.0.0 || >=20.0.0",
"less": "*",
"lightningcss": "^1.21.0",
"sass": "*",
"sass-embedded": "*",
"stylus": "*",
"sugarss": "*",
- "terser": "^5.16.0",
- "tsx": "^4.8.1",
- "yaml": "^2.4.2"
+ "terser": "^5.4.0"
},
"peerDependenciesMeta": {
"@types/node": {
"optional": true
},
- "jiti": {
- "optional": true
- },
"less": {
"optional": true
},
@@ -5053,12 +4734,6 @@
},
"terser": {
"optional": true
- },
- "tsx": {
- "optional": true
- },
- "yaml": {
- "optional": true
}
}
},
@@ -5067,6 +4742,7 @@
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
},
@@ -5082,14 +4758,16 @@
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
"integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/xstate": {
- "version": "5.20.0",
- "resolved": "https://registry.npmjs.org/xstate/-/xstate-5.20.0.tgz",
- "integrity": "sha512-lFQ0fLwVa0OMZnjNP8zUkt2fwIS85ZBNPvxE41APVYhYj0++aTssgmsnTAiBHdKYbgnd6+L8DRTZ9jPZAFPuyw==",
+ "version": "5.20.1",
+ "resolved": "https://registry.npmjs.org/xstate/-/xstate-5.20.1.tgz",
+ "integrity": "sha512-i9ZpNnm/XhCOMUxae1suT8PjYNTStZWbhmuKt4xeTPaYG5TS0Fz0i+Ka5yxoNPpaHW3VW6JIowrwFgSTZONxig==",
+ "license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/xstate"
@@ -5099,6 +4777,7 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "license": "MIT",
"engines": {
"node": ">=0.4"
}
@@ -5107,28 +4786,21 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
- },
- "node_modules/zwitch": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
- "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
}
}
}
diff --git a/package.json b/package.json
index e894238..2a9f14d 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,6 @@
"preview": "vite preview"
},
"dependencies": {
-<<<<<<< Updated upstream
"@azure/msal-browser": "^4.12.0",
"@azure/msal-react": "^3.0.12",
"@xstate/react": "^5.0.0",
@@ -24,10 +23,12 @@
"jwt-decode": "^4.0.0",
"motion": "^12.7.3",
"pg": "^8.8.0",
-=======
->>>>>>> Stashed changes
"react": "^19.1.0",
- "react-dom": "^19.1.0"
+ "react-dom": "^19.1.0",
+ "react-dropzone": "^14.3.8",
+ "react-icons": "^5.5.0",
+ "react-router-dom": "^7.7.1",
+ "xstate": "^5.20.1"
},
"devDependencies": {
"@eslint/js": "^9.30.1",
diff --git a/src/App.tsx b/src/App.tsx
index 20c89fd..59e8583 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -10,13 +10,16 @@ import Register from './pages/Register';
import { AuthProvider } from './auth/authProvider';
import { ProtectedRoute } from './auth/ProtectedRoute';
import { LanguageProvider } from './contexts/LanguageContext';
-import Home from './pages/Home';
-import Dateien from './pages/Dateien/Dateien';
-import TeamBereich from './pages/TeamBereich/TeamBereich';
-import Dashboard from './pages/Dashboard';
-import Einstellungen from './pages/Einstellungen/Einstellungen';
+import Home from './pages/Home/Home';
+import Dateien from './pages/Home/Dateien';
+import TeamBereich from './pages/Home/TeamBereich';
+import Dashboard from './pages/Home/Dashboard';
+import Einstellungen from './pages/Home/Einstellungen';
// Import the global light theme CSS variables as default
import './assets/styles/light.css';
+import Connections from './pages/Home/Connections';
+import Workflows from './pages/Home/Workflows';
+import TestSharepoint from './pages/Home/TestSharepoint';
function App() {
// Load saved theme preference on app mount
@@ -49,7 +52,10 @@ function App() {
} />
} />
} />
+ } />
+ } />
} />
+ } />
diff --git a/src/assets/styles/light.css b/src/assets/styles/light.css
index 861531f..a1ff93f 100644
--- a/src/assets/styles/light.css
+++ b/src/assets/styles/light.css
@@ -11,9 +11,9 @@
--color-secondary-hover: #FF6A55;
--color-secondary-disabled: #F5B0A4;
- --color-red: #D85B65;
- --color-red-hover: #E77A81;
- --color-red-disabled: #F3C0C4;
+ --color-red: #dc3545;
+ --color-red-hover: #f5c6cb;
+ --color-red-disabled: #f8d7da;
--color-secondary-red: #B94A55;
--color-secondary-red-hover: #D46872;
@@ -40,9 +40,9 @@
--color-secondary-hover: #FF715C;
--color-secondary-disabled: #6E3E36;
- --color-red: #FF6F7A;
- --color-red-hover: #FF8B94;
- --color-red-disabled: #80383E;
+ --color-red: #dc3545;
+ --color-red-hover: #f5c6cb;
+ --color-red-disabled: #f8d7da;
--color-secondary-red: #D65D6A;
--color-secondary-red-hover: #E17683;
diff --git a/src/components/Connections/ConnectionEditModal.module.css b/src/components/Connections/ConnectionEditModal.module.css
new file mode 100644
index 0000000..bef2cd8
--- /dev/null
+++ b/src/components/Connections/ConnectionEditModal.module.css
@@ -0,0 +1,61 @@
+.editModal {
+ /* Custom styling for the edit modal */
+}
+
+.editForm {
+ /* Form-specific styling within the modal */
+ min-width: 400px;
+}
+
+/* Ensure proper spacing for form elements */
+.editForm :global(.fieldGroup) {
+ margin-bottom: 18px;
+}
+
+.editForm :global(.floatingLabelInput) {
+ margin-bottom: 18px;
+}
+
+/* Style the readonly fields to blend better with the modal */
+.editForm :global(.readonlyField) {
+ background-color: var(--color-bg);
+ opacity: 0.8;
+ font-style: italic;
+}
+
+/* Enhance button styling within the modal */
+.editForm :global(.buttonGroup) {
+ margin-top: 32px;
+ padding-top: 20px;
+ border-top: 1px solid var(--color-primary);
+}
+
+.editForm :global(.saveButton) {
+ background-color: var(--color-secondary);
+ min-width: 120px;
+}
+
+.editForm :global(.saveButton:hover) {
+ background-color: var(--color-secondary-hover);
+}
+
+.editForm :global(.cancelButton) {
+ min-width: 100px;
+}
+
+/* Responsive design */
+@media (max-width: 640px) {
+ .editForm {
+ min-width: 300px;
+ }
+
+ .editForm :global(.buttonGroup) {
+ gap: 8px;
+ }
+
+ .editForm :global(.saveButton),
+ .editForm :global(.cancelButton) {
+ flex: 1;
+ min-width: unset;
+ }
+}
\ No newline at end of file
diff --git a/src/components/Connections/ConnectionEditModal.tsx b/src/components/Connections/ConnectionEditModal.tsx
new file mode 100644
index 0000000..8c1b529
--- /dev/null
+++ b/src/components/Connections/ConnectionEditModal.tsx
@@ -0,0 +1,50 @@
+import React from 'react';
+import { Popup, EditForm } from '../Popup';
+import styles from './ConnectionEditModal.module.css';
+import { ConnectionEditModalProps } from './interfaces';
+import { useLanguage } from '../../contexts/LanguageContext';
+
+export function ConnectionEditModal({
+ isOpen,
+ connection,
+ fields,
+ onSave,
+ onCancel
+}: ConnectionEditModalProps) {
+ const { t, isLoading } = useLanguage();
+
+ if (!connection) {
+ return null;
+ }
+
+ const authorityName = connection.authority?.charAt(0).toUpperCase() + connection.authority?.slice(1);
+
+ // Simplified approach for the title
+ const baseTitle = t('connections.edit_connection_title', `Edit {authority} Connection`);
+ const modalTitle = baseTitle.includes('{authority}')
+ ? baseTitle.replace('{authority}', authorityName || '')
+ : `Edit ${authorityName} Connection`;
+
+ return (
+
+
+
+ );
+}
+
+export default ConnectionEditModal;
\ No newline at end of file
diff --git a/src/components/Connections/ConnectionsErrorDisplay.module.css b/src/components/Connections/ConnectionsErrorDisplay.module.css
new file mode 100644
index 0000000..0c0a15e
--- /dev/null
+++ b/src/components/Connections/ConnectionsErrorDisplay.module.css
@@ -0,0 +1,47 @@
+.errorContainer {
+ margin-bottom: 20px;
+}
+
+.errorMessage {
+ color: var(--color-red, #ef4444);
+ padding: 12px 16px;
+ background-color: var(--color-red-hover, rgba(239, 68, 68, 0.1));
+ border: 1px solid var(--color-red, #ef4444);
+ border-radius: 25px;
+ margin-bottom: 12px;
+ font-size: 14px;
+ line-height: 1.4;
+}
+
+.errorMessage:last-child {
+ margin-bottom: 0;
+}
+
+.errorMessage strong {
+ font-weight: 600;
+ margin-right: 4px;
+}
+
+/* Animation for error appearance */
+.errorMessage {
+ animation: slideIn 0.3s ease-out;
+}
+
+@keyframes slideIn {
+ from {
+ opacity: 0;
+ transform: translateY(-10px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+/* Responsive design */
+@media (max-width: 480px) {
+ .errorMessage {
+ padding: 10px 14px;
+ font-size: 13px;
+ }
+}
\ No newline at end of file
diff --git a/src/components/Connections/ConnectionsErrorDisplay.tsx b/src/components/Connections/ConnectionsErrorDisplay.tsx
new file mode 100644
index 0000000..16ebed0
--- /dev/null
+++ b/src/components/Connections/ConnectionsErrorDisplay.tsx
@@ -0,0 +1,41 @@
+import React from 'react';
+import styles from './ConnectionsErrorDisplay.module.css';
+import { ConnectionsErrorDisplayProps } from './interfaces';
+import { useLanguage } from '../../contexts/LanguageContext';
+
+export function ConnectionsErrorDisplay({
+ error,
+ connectError,
+ disconnectError
+}: ConnectionsErrorDisplayProps) {
+ const { t } = useLanguage();
+
+ // Don't render anything if no errors
+ if (!error && !connectError && !disconnectError) {
+ return null;
+ }
+
+ return (
+
+ {error && (
+
+ {t('connections.error', 'Error')}: {error}
+
+ )}
+
+ {connectError && (
+
+ {t('connections.connection_error', 'Connection Error')}: {connectError}
+
+ )}
+
+ {disconnectError && (
+
+ {t('connections.disconnect_error', 'Disconnect Error')}: {disconnectError}
+
+ )}
+
+ );
+}
+
+export default ConnectionsErrorDisplay;
\ No newline at end of file
diff --git a/src/components/Connections/ConnectionsTable.module.css b/src/components/Connections/ConnectionsTable.module.css
new file mode 100644
index 0000000..f2a3931
--- /dev/null
+++ b/src/components/Connections/ConnectionsTable.module.css
@@ -0,0 +1,50 @@
+.tableContainer {
+ width: 100%;
+ background: var(--color-bg);
+ border-radius: 8px;
+ overflow: hidden;
+}
+
+.connectionsTable {
+ width: 100%;
+ border-radius: 8px;
+}
+
+/* Override FormGenerator styles for connections-specific styling */
+.connectionsTable :global(.table) {
+ background-color: var(--color-bg);
+ color: var(--color-text);
+}
+
+.connectionsTable :global(.th) {
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ border-bottom: 2px solid var(--color-primary);
+}
+
+.connectionsTable :global(.td) {
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ border-bottom: 1px solid var(--color-primary);
+}
+
+.connectionsTable :global(.tr:hover) {
+ background-color: var(--color-primary-hover);
+}
+
+/* Responsive design */
+@media (max-width: 768px) {
+ .tableContainer {
+ border-radius: 4px;
+ margin: 0 -8px;
+ }
+}
+
+@media (max-width: 480px) {
+ .tableContainer {
+ margin: 0 -16px;
+ border-radius: 0;
+ border-left: none;
+ border-right: none;
+ }
+}
\ No newline at end of file
diff --git a/src/components/Connections/ConnectionsTable.tsx b/src/components/Connections/ConnectionsTable.tsx
new file mode 100644
index 0000000..599967d
--- /dev/null
+++ b/src/components/Connections/ConnectionsTable.tsx
@@ -0,0 +1,42 @@
+import React from 'react';
+import { FormGenerator } from '../FormGenerator';
+import styles from './ConnectionsTable.module.css';
+import { ConnectionsTableProps } from './interfaces';
+import { useLanguage } from '../../contexts/LanguageContext';
+
+export function ConnectionsTable({
+ connections,
+ columns,
+ actions,
+ isLoading = false,
+ isConnecting = false,
+ isDisconnecting = false,
+ onRowSelect
+}: ConnectionsTableProps) {
+ const { t } = useLanguage();
+
+ const loading = isLoading || isConnecting || isDisconnecting;
+
+ return (
+
+
+
+ );
+}
+
+export default ConnectionsTable;
\ No newline at end of file
diff --git a/src/components/Connections/index.ts b/src/components/Connections/index.ts
new file mode 100644
index 0000000..272a124
--- /dev/null
+++ b/src/components/Connections/index.ts
@@ -0,0 +1,10 @@
+// Export all components
+export { ConnectionsTable } from './ConnectionsTable';
+export { ConnectionEditModal } from './ConnectionEditModal';
+export { ConnectionsErrorDisplay } from './ConnectionsErrorDisplay';
+
+// Export logic hook
+export { useConnectionsLogic } from './logic';
+
+// Export all interfaces and types
+export * from './interfaces';
\ No newline at end of file
diff --git a/src/components/Connections/interfaces.ts b/src/components/Connections/interfaces.ts
new file mode 100644
index 0000000..6003b51
--- /dev/null
+++ b/src/components/Connections/interfaces.ts
@@ -0,0 +1,72 @@
+import { ColumnConfig } from '../FormGenerator';
+import { EditFieldConfig } from '../Popup';
+
+// Re-export connection-related interfaces from hooks
+export type { Connection, CreateConnectionData } from '../../hooks/useConnections';
+
+// Import React for component types
+import React from 'react';
+
+// Component Props Interfaces
+export interface ConnectionsTableProps {
+ connections: Connection[];
+ columns: ColumnConfig[];
+ actions: TableAction[];
+ isLoading?: boolean;
+ isConnecting?: boolean;
+ isDisconnecting?: boolean;
+ onRowSelect?: (selectedRows: Connection[]) => void;
+}
+
+export interface ConnectionEditModalProps {
+ isOpen: boolean;
+ connection: Connection | null;
+ fields: EditFieldConfig[];
+ onSave: (updatedConnection: Connection) => Promise;
+ onCancel: () => void;
+}
+
+export interface ConnectionsErrorDisplayProps {
+ error?: string | null;
+ connectError?: string | null;
+ disconnectError?: string | null;
+}
+
+// Table Action Interface
+export interface TableAction {
+ label: string;
+ onClick: (connection: Connection) => Promise | void;
+ icon: React.ReactNode | ((connection: Connection) => React.ReactNode);
+}
+
+// Connection Status Types
+export type ConnectionStatus = 'active' | 'pending' | 'expired' | 'revoked';
+export type ConnectionAuthority = 'local' | 'google' | 'msft';
+
+// Handler Function Types
+export interface ConnectionHandlers {
+ handleCreateConnection: (type: 'msft' | 'google') => Promise;
+ handleConnect: (connection: Connection) => Promise;
+ handleDisconnect: (connection: Connection) => Promise;
+ handleDelete: (connection: Connection) => Promise;
+ handleConnectOrDisconnect: (connection: Connection) => Promise;
+ handleEditConnection: (connection: Connection) => Promise;
+ handleSaveConnection: (updatedConnection: Connection) => Promise;
+ handleCancelEdit: () => void;
+}
+
+// Hook Return Types
+export interface ConnectionsLogicReturn extends ConnectionHandlers {
+ connections: Connection[];
+ isLoading: boolean;
+ isConnecting: boolean;
+ isDisconnecting: boolean;
+ error: string | null;
+ connectError: string | null;
+ disconnectError: string | null;
+ editPopupOpen: boolean;
+ editingConnection: Connection | null;
+ connectionColumns: ColumnConfig[];
+ connectionEditFields: EditFieldConfig[];
+ tableActions: TableAction[];
+}
\ No newline at end of file
diff --git a/src/components/Connections/logic.tsx b/src/components/Connections/logic.tsx
new file mode 100644
index 0000000..5118ec7
--- /dev/null
+++ b/src/components/Connections/logic.tsx
@@ -0,0 +1,339 @@
+import { useEffect, useState } from 'react';
+import { IoIosLink, IoIosTrash } from 'react-icons/io';
+import { MdModeEdit } from 'react-icons/md';
+import { GoUnlink } from 'react-icons/go';
+import React from 'react';
+
+import { useConnections, useOAuthConnect, useDisconnect } from '../../hooks/useConnections';
+import { useLanguage } from '../../contexts/LanguageContext';
+import { ColumnConfig } from '../FormGenerator';
+import { EditFieldConfig } from '../Popup';
+import {
+ Connection,
+ CreateConnectionData,
+ ConnectionsLogicReturn,
+ TableAction
+} from './interfaces';
+
+export function useConnectionsLogic(): ConnectionsLogicReturn {
+ const { t } = useLanguage();
+
+ // Hooks
+ const {
+ connections,
+ fetchConnections,
+ createConnection,
+ updateConnection,
+ connectService,
+ disconnectService,
+ deleteConnection,
+ isLoading,
+ error
+ } = useConnections();
+
+ const {
+ connectWithPopup,
+ isConnecting,
+ error: connectError
+ } = useOAuthConnect();
+
+ const {
+ disconnect,
+ isDisconnecting,
+ error: disconnectError
+ } = useDisconnect();
+
+ // Local state
+ const [editPopupOpen, setEditPopupOpen] = useState(false);
+ const [editingConnection, setEditingConnection] = useState(null);
+
+ // Define field configuration for editing connections
+ const connectionEditFields: EditFieldConfig[] = [
+ {
+ key: 'authority',
+ label: t('connections.field.service', 'Service'),
+ type: 'readonly',
+ editable: false,
+ formatter: (value: string) => {
+ if (!value) return t('connections.unknown', 'Unknown');
+ const labels = {
+ 'google': t('connections.service.google', 'Google'),
+ 'msft': t('connections.service.microsoft', 'Microsoft'),
+ 'local': t('connections.service.local', 'Local')
+ };
+ return labels[value as keyof typeof labels] || value;
+ }
+ },
+ {
+ key: 'status',
+ label: t('connections.field.status', 'Status'),
+ type: 'readonly',
+ editable: false,
+ formatter: (value: string) => value ? value.charAt(0).toUpperCase() + value.slice(1) : t('connections.unknown', 'Unknown')
+ },
+ {
+ key: 'externalUsername',
+ label: t('connections.field.external_username', 'External Username'),
+ type: 'string',
+ editable: true,
+ required: false,
+ placeholder: t('connections.placeholder.external_username', 'Enter external username')
+ },
+ {
+ key: 'externalEmail',
+ label: t('connections.field.external_email', 'External Email'),
+ type: 'email',
+ editable: true,
+ required: false,
+ placeholder: t('connections.placeholder.external_email', 'Enter external email address')
+ },
+ {
+ key: 'connectedAt',
+ label: t('connections.field.connected_at', 'Connected At'),
+ type: 'readonly',
+ editable: false,
+ formatter: (value: string) => {
+ if (!value) return t('connections.not_available', 'N/A');
+ try {
+ return new Date(value).toLocaleString();
+ } catch {
+ return t('connections.invalid_date', 'Invalid Date');
+ }
+ }
+ },
+ {
+ key: 'lastChecked',
+ label: t('connections.field.last_checked', 'Last Checked'),
+ type: 'readonly',
+ editable: false,
+ formatter: (value: string) => {
+ if (!value) return t('connections.not_available', 'N/A');
+ try {
+ return new Date(value).toLocaleString();
+ } catch {
+ return t('connections.invalid_date', 'Invalid Date');
+ }
+ }
+ }
+ ];
+
+ // Define custom columns for the connections table
+ const connectionColumns: ColumnConfig[] = [
+ {
+ key: 'authority',
+ label: t('connections.field.service', 'Service'),
+ type: 'enum',
+ filterOptions: ['google', 'msft', 'local'],
+ formatter: (value: string) => {
+ if (!value) return t('connections.unknown', 'Unknown');
+ const labels = {
+ 'google': t('connections.service.google', 'Google'),
+ 'msft': t('connections.service.microsoft', 'Microsoft'),
+ 'local': t('connections.service.local', 'Local')
+ };
+ return labels[value as keyof typeof labels] || value;
+ },
+ width: 150,
+ sortable: true,
+ filterable: true
+ },
+ {
+ key: 'status',
+ label: t('connections.field.status', 'Status'),
+ type: 'enum',
+ filterOptions: ['active', 'pending', 'expired', 'revoked'],
+ formatter: (value: string) => {
+ return value?.charAt(0).toUpperCase() + value?.slice(1) || t('connections.unknown', 'Unknown');
+ },
+ width: 120,
+ sortable: true,
+ filterable: true
+ },
+ {
+ key: 'externalUsername',
+ label: t('connections.field.external_username', 'External Username'),
+ type: 'string',
+ width: 200,
+ sortable: true,
+ filterable: false,
+ searchable: true
+ },
+ {
+ key: 'externalEmail',
+ label: t('connections.field.external_email', 'External Email'),
+ type: 'string',
+ width: 250,
+ sortable: true,
+ filterable: false,
+ searchable: true
+ },
+ {
+ key: 'connectedAt',
+ label: t('connections.field.connected_at', 'Connected At'),
+ type: 'date',
+ width: 150,
+ sortable: true,
+ filterable: false,
+ searchable: true
+ },
+ {
+ key: 'lastChecked',
+ label: t('connections.field.last_checked', 'Last Checked'),
+ type: 'date',
+ width: 150,
+ sortable: true,
+ filterable: true,
+ searchable: true
+ },
+ {
+ key: 'expiresAt',
+ label: t('connections.field.expires_at', 'Expires At'),
+ type: 'date',
+ width: 150,
+ sortable: true,
+ filterable: true
+ }
+ ];
+
+ // Fetch connections on mount
+ useEffect(() => {
+ fetchConnections();
+ }, []);
+
+ // Handler functions
+ const handleCreateConnection = async (type: 'msft' | 'google') => {
+ console.log('Creating connection for type:', type);
+ try {
+ const connectionData: CreateConnectionData = {
+ type: type,
+ status: 'pending',
+ connectedAt: new Date().toISOString(),
+ lastChecked: new Date().toISOString()
+ };
+
+ console.log('Sending connection data to backend:', connectionData);
+ const newConnection = await createConnection(connectionData);
+ console.log('Connection created successfully:', newConnection);
+ await fetchConnections();
+ } catch (error) {
+ console.error('Error creating connection:', error);
+ }
+ };
+
+ const handleConnect = async (connection: Connection) => {
+ console.log('Connecting to service:', connection);
+ try {
+ await connectWithPopup(connection.id);
+ await fetchConnections();
+ } catch (error) {
+ console.error('Error connecting to service:', error);
+ }
+ };
+
+ const handleDisconnect = async (connection: Connection) => {
+ console.log('Disconnecting from service:', connection);
+ try {
+ await disconnect(connection.id);
+ await fetchConnections();
+ } catch (error) {
+ console.error('Error disconnecting from service:', error);
+ }
+ };
+
+ const handleDelete = async (connection: Connection) => {
+ const serviceName = connection.authority?.charAt(0).toUpperCase() + connection.authority?.slice(1) || t('connections.unknown', 'Unknown');
+ const confirmMessage = t('connections.confirm_delete', 'Are you sure you want to delete the {service} connection?').replace('{service}', serviceName);
+
+ if (window.confirm(confirmMessage)) {
+ try {
+ await deleteConnection(connection.id);
+ await fetchConnections();
+ } catch (error) {
+ console.error('Error deleting connection:', error);
+ }
+ }
+ };
+
+ const handleConnectOrDisconnect = async (connection: Connection) => {
+ if (connection.status === 'active') {
+ await handleDisconnect(connection);
+ } else {
+ await handleConnect(connection);
+ }
+ };
+
+ const handleEditConnection = async (connection: Connection) => {
+ console.log('Editing connection:', connection);
+ setEditingConnection(connection);
+ setEditPopupOpen(true);
+ };
+
+ const handleSaveConnection = async (updatedConnection: Connection) => {
+ if (!editingConnection) return;
+
+ try {
+ const updateData = {
+ externalUsername: updatedConnection.externalUsername,
+ externalEmail: updatedConnection.externalEmail
+ };
+
+ await updateConnection(editingConnection.id, updateData);
+ console.log('Connection updated successfully');
+ await fetchConnections();
+ setEditPopupOpen(false);
+ setEditingConnection(null);
+ } catch (error) {
+ console.error('Error updating connection:', error);
+ }
+ };
+
+ const handleCancelEdit = () => {
+ setEditPopupOpen(false);
+ setEditingConnection(null);
+ };
+
+ // Table actions
+ const tableActions: TableAction[] = [
+ {
+ label: t('connections.action.edit', 'Edit'),
+ onClick: handleEditConnection,
+ icon:
+ },
+ {
+ label: t('connections.action.toggle_connection', 'Toggle Connection'),
+ onClick: handleConnectOrDisconnect,
+ icon: (connection: Connection) => connection.status === 'active' ? :
+ },
+ {
+ label: t('connections.action.delete', 'Delete'),
+ onClick: handleDelete,
+ icon:
+ }
+ ];
+
+ return {
+ // Data
+ connections,
+ isLoading,
+ isConnecting,
+ isDisconnecting,
+ error,
+ connectError,
+ disconnectError,
+ editPopupOpen,
+ editingConnection,
+ connectionColumns,
+ connectionEditFields,
+ tableActions,
+
+ // Handlers
+ handleCreateConnection,
+ handleConnect,
+ handleDisconnect,
+ handleDelete,
+ handleConnectOrDisconnect,
+ handleEditConnection,
+ handleSaveConnection,
+ handleCancelEdit
+ };
+}
\ No newline at end of file
diff --git a/src/components/Dashboard/DashboardChat/DashboardChat.tsx b/src/components/Dashboard/DashboardChat/DashboardChat.tsx
index 79d79b7..2f60cb7 100644
--- a/src/components/Dashboard/DashboardChat/DashboardChat.tsx
+++ b/src/components/Dashboard/DashboardChat/DashboardChat.tsx
@@ -1,13 +1,10 @@
import React, { useState } from "react";
-import { BsArrowsAngleExpand, BsArrowsAngleContract } from "react-icons/bs";
-import { motion, AnimatePresence } from "framer-motion";
import { Prompt } from "../../../hooks/usePrompts";
import { useLanguage } from '../../../contexts/LanguageContext';
-import DashboardChatArea from './DashboardChatArea/DashboardChatArea';
-import DashboardChatHistory from './DashboardChatHistory/DashboardChatHistory';
+import DashboardChatArea from './DashboardChatArea';
-import styles from './DashboardChat.module.css';
+import styles from './DashboardChatAreaStyles/DashboardChat.module.css';
interface DashboardChatProps {
isExpanded: boolean;
@@ -20,8 +17,6 @@ interface DashboardChatProps {
}
const DashboardChat: React.FC = ({
- isExpanded,
- onToggleExpand,
selectedPrompt,
onPromptUsed,
onWorkflowIdChange,
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatArea.tsx b/src/components/Dashboard/DashboardChat/DashboardChatArea.tsx
similarity index 93%
rename from src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatArea.tsx
rename to src/components/Dashboard/DashboardChat/DashboardChatArea.tsx
index 3245212..ffb103d 100644
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatArea.tsx
+++ b/src/components/Dashboard/DashboardChat/DashboardChatArea.tsx
@@ -25,13 +25,20 @@ const DashboardChatArea: React.FC = ({
// Workflow state
const [currentWorkflowId, setCurrentWorkflowId] = useState(resumeWorkflowId || null);
+ // Update current workflow ID when resumeWorkflowId changes
+ React.useEffect(() => {
+ if (resumeWorkflowId !== currentWorkflowId) {
+ setCurrentWorkflowId(resumeWorkflowId);
+ }
+ }, [resumeWorkflowId, currentWorkflowId]);
+
// Handle workflow ID changes
- const handleWorkflowIdChange = (workflowId: string | null) => {
+ const handleWorkflowIdChange = React.useCallback((workflowId: string | null) => {
setCurrentWorkflowId(workflowId);
if (onWorkflowIdChange) {
onWorkflowIdChange(workflowId);
}
- };
+ }, [onWorkflowIdChange]);
// Handle resizing
const handleMouseDown = (direction: 'horizontal' | 'vertical') => (e: React.MouseEvent) => {
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/DashbaordChatAreaStatusDisplayold.tsx b/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/DashbaordChatAreaStatusDisplayold.tsx
deleted file mode 100644
index cbd7bba..0000000
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/DashbaordChatAreaStatusDisplayold.tsx
+++ /dev/null
@@ -1,127 +0,0 @@
-import React from "react";
-import { motion, AnimatePresence } from "framer-motion";
-import { WorkflowStatusDisplayProps } from "./dashboardChatAreaTypes";
-import { useLanguage } from "../../../../contexts/LanguageContext";
-import styles from './DashboardChatArea.module.css';
-
-const WorkflowStatusDisplay: React.FC = ({
- currentWorkflowId,
- workflowStatus,
- workflowCompleted,
- onStartNewWorkflow,
- handleRetry,
- shouldShowRetryButton
-}) => {
- const { t } = useLanguage();
- return (
-
- {currentWorkflowId && shouldShowRetryButton() && (
-
-
-
- {t('chat.workflow_failed')}
-
-
- {t('chat.retry_workflow')}
-
-
-
- )}
- {currentWorkflowId && !workflowCompleted && !shouldShowRetryButton() && (
-
-
-
- •
-
-
- •
-
-
- •
-
-
-
- )}
-
- );
-};
-
-export default WorkflowStatusDisplay;
\ No newline at end of file
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/DashboardChatArea.module.css b/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/DashboardChatArea.module.css
deleted file mode 100644
index b4cf4f9..0000000
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/DashboardChatArea.module.css
+++ /dev/null
@@ -1,536 +0,0 @@
-.chat_area {
- display: flex;
- flex-direction: column;
- flex: 1;
- min-height: 0;
- overflow: hidden;
- font-family: var(--font-family);
-}
-
-.chat_messages {
- flex: 1;
- padding: 15px;
- border-radius: 15px;
- margin-bottom: 15px;
- min-height: 0;
- overflow-y: auto;
- overflow-x: hidden;
- scroll-behavior: smooth;
-}
-
-.chat_messages::-webkit-scrollbar {
- width: 6px;
-}
-
-.chat_messages::-webkit-scrollbar-track {
- background: transparent;
-}
-
-.chat_messages::-webkit-scrollbar-thumb {
- background: var(--color-gray-disabled);
- border-radius: 3px;
-}
-
-.chat_messages::-webkit-scrollbar-thumb:hover {
- background: var(--color-gray);
-}
-
-.messages_container {
- min-height: 100%;
- display: flex;
- flex-direction: column;
- justify-content: flex-start;
-
-}
-
-.messages_spacer {
- flex: 1;
- min-height: 20px;
-}
-
-.chat_input {
- display: flex;
- gap: 10px;
- align-items: flex-end;
- flex-shrink: 0;
- flex-direction: column;
- transition: all 0.2s ease;
-}
-
-.chat_input.drag_over {
- background-color: var(--color-secondary-disabled);
- border: 2px dashed var(--color-secondary);
- border-radius: 12px;
- padding: 8px;
-}
-
-.input_row {
- display: flex;
- gap: 10px;
- align-items: flex-end;
- width: 100%;
-}
-
-.message_input {
- flex: 1;
- padding: 12px 16px;
- border: 1px solid var(--color-gray-disabled);
- border-radius: 12px;
- outline: none;
- font-size: 14px;
- font-family: var(--font-family);
- background-color: var(--color-bg);
- color: var(--color-text);
-}
-
-.message_input:focus {
- border-color: var(--color-secondary);
-}
-
-.message_input:disabled {
- background-color: var(--color-surface);
- cursor: not-allowed;
- opacity: 0.6;
-}
-
-.attachment_button {
- height: 48px;
- width: 48px;
- background-color: var(--color-secondary-disabled);
- color: var(--color-secondary);
- border: none;
- border-radius: 12px;
- cursor: pointer;
- font-size: 14px;
- font-weight: 500;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: background-color 0.2s ease, border-color 0.2s ease;
- font-family: var(--font-family);
-}
-
-.attachment_button:hover {
- background-color: var(--color-secondary-hover);
- color: var(--color-bg);
-}
-
-.attachment_button:disabled {
- background-color: var(--color-surface);
- cursor: not-allowed;
- opacity: 0.6;
-}
-
-.attached_files {
- display: flex;
- flex-wrap: wrap;
- gap: 8px;
- width: 100%;
- margin-bottom: 5px;
-}
-
-.attached_file {
- display: flex;
- align-items: center;
- gap: 6px;
- padding: 6px 8px;
- background-color: var(--color-secondary-disabled);
- border: 1px solid var(--color-secondary);
- border-radius: 8px;
- font-size: 12px;
- color: var(--color-secondary);
- font-family: var(--font-family);
-}
-
-.attached_file_icon {
- font-size: 16px;
-}
-
-.attached_file_name {
- max-width: 150px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.attached_file_remove {
- background: none;
- border: none;
- color: var(--color-gray);
- cursor: pointer;
- padding: 0;
- margin-left: 4px;
- display: flex;
- align-items: center;
- justify-content: center;
- width: 16px;
- height: 16px;
- border-radius: 50%;
- transition: background-color 0.2s ease, color 0.2s ease;
-}
-
-.attached_file_remove:hover {
- background-color: var(--color-gray-disabled);
- color: var(--color-text);
-}
-
-.send_button {
- height: 48px;
- width: 48px;
- background-color: var(--color-secondary);
- color: var(--color-bg);
- border: 1px solid var(--color-secondary);
- border-radius: 12px;
- cursor: pointer;
- font-size: 14px;
- font-weight: 500;
- display: flex;
- align-items: center;
- justify-content: center;
- font-family: var(--font-family);
-}
-
-.send_button:hover {
- background-color: var(--color-secondary-hover);
-}
-
-.send_button_icon {
- height: 60%;
- width: 60%;
- margin: none;
- padding: none;
-}
-
-.send_button:disabled {
- background-color: var(--color-gray-disabled);
- cursor: not-allowed;
- opacity: 0.6;
- border: 1px solid var(--color-gray-disabled);
-}
-
-.stop_button {
- padding: 12px 12px;
- height: 48px;
- width: 48px;
- background-color: var(--color-red);
- color: var(--color-bg);
- border: none;
- border-radius: 12px;
- cursor: pointer;
- font-size: 14px;
- font-weight: 500;
- display: flex;
- align-items: center;
- justify-content: center;
- font-family: var(--font-family);
-}
-
-.stop_button:hover {
- background-color: var(--color-red-hover);
-}
-
-.stop_button:disabled {
- background-color: var(--color-gray-disabled);
- cursor: not-allowed;
- opacity: 0.6;
-}
-
-.loading_message {
- padding: 10px;
- background-color: var(--color-secondary-disabled);
- border-left: 4px solid var(--color-secondary);
- border-radius: 4px;
- margin-bottom: 10px;
-}
-
-.loading_message p {
- margin: 0;
- color: var(--color-secondary);
- font-size: 14px;
- font-family: var(--font-family);
-}
-
-.error_message {
- padding: 10px;
- background-color: var(--color-red-disabled);
- border-left: 4px solid var(--color-red);
- border-radius: 4px;
- margin-bottom: 10px;
-}
-
-.error_message p {
- margin: 0;
- color: var(--color-red);
- font-size: 14px;
- font-family: var(--font-family);
-}
-
-.message {
- margin-bottom: 15px;
- padding: 12px;
- border-radius: 12px;
- max-width: 80%;
- font-family: var(--font-family);
-}
-
-.message_user {
- background-color: var(--color-secondary);
- color: var(--color-bg);
- margin-left: auto;
- margin-right: 0;
-}
-
-.message_assistant {
- background-color: var(--color-surface);
- color: var(--color-text);
- margin-left: 0;
- margin-right: auto;
-}
-
-.message_system {
- background-color: var(--color-primary-disabled);
- color: var(--color-primary);
- margin-left: auto;
- margin-right: auto;
- text-align: center;
-}
-
-.message_role {
- font-size: 12px;
- font-weight: 600;
- margin-bottom: 4px;
- opacity: 0.8;
- font-family: var(--font-family);
-}
-
-.message_content {
- font-size: 14px;
- line-height: 1.4;
- white-space: pre-wrap;
- word-wrap: break-word;
- font-family: var(--font-family);
-}
-
-.message_timestamp {
- font-size: 11px;
- margin-top: 4px;
- opacity: 0.6;
- font-family: var(--font-family);
-}
-
-.placeholder_text {
- text-align: center;
- color: var(--color-gray);
- font-style: italic;
- margin: 20px 0;
- font-family: var(--font-family);
-}
-
-.workflow_status {
- display: flex;
- justify-content: center;
- align-items: center;
- padding: 10px;
- margin: 5px 0;
-}
-
-.workflow_status p {
- margin: 0;
- font-size: 14px;
- color: var(--color-gray);
- font-family: var(--font-family);
-}
-
-.retry_container {
- display: flex;
- align-items: center;
- gap: 12px;
- padding: 12px 16px;
- background-color: var(--color-red-disabled);
- border: 1px solid var(--color-red);
- border-radius: 12px;
-}
-
-.failed_message {
- font-size: 14px;
- color: var(--color-red);
- font-family: var(--font-family);
- font-weight: 500;
-}
-
-.retry_button {
- background-color: var(--color-primary);
- color: var(--color-bg);
- border: none;
- border-radius: 8px;
- padding: 8px 16px;
- font-size: 12px;
- font-weight: 500;
- cursor: pointer;
- font-family: var(--font-family);
- transition: background-color 0.2s ease, transform 0.2s ease;
- white-space: nowrap;
-}
-
-.retry_button:hover {
- background-color: var(--color-primary-hover);
- transform: translateY(-1px);
-}
-
-.retry_button:disabled {
- background-color: var(--color-gray-disabled);
- cursor: not-allowed;
- transform: none;
- opacity: 0.6;
-}
-
-.completion_message {
- padding: 10px 12px;
- background-color: var(--color-secondary-disabled);
- border-left: 4px solid var(--color-secondary);
- border-radius: 4px;
- margin-bottom: 10px;
- text-align: center;
-}
-
-.completion_message p {
- margin: 0 0 10px 0;
- color: var(--color-secondary);
- font-size: 14px;
- font-weight: 600;
- font-family: var(--font-family);
-}
-
-.new_workflow_button {
- background-color: var(--color-secondary);
- color: var(--color-bg);
- border: none;
- border-radius: 8px;
- padding: 8px 16px;
- font-size: 12px;
- font-weight: 500;
- cursor: pointer;
- transition: background-color 0.2s ease;
- font-family: var(--font-family);
-}
-
-.new_workflow_button:hover {
- background-color: var(--color-secondary-hover);
-}
-
-.message_documents {
- margin-top: 8px;
- display: flex;
- flex-direction: column;
- gap: 6px;
-}
-
-.document_item {
- display: flex;
- align-items: center;
- gap: 8px;
- padding: 8px 10px;
- background-color: var(--color-bg);
- border: 1px solid var(--color-gray-disabled);
- border-radius: 6px;
- cursor: pointer;
- transition: all 0.2s ease;
- font-size: 13px;
-}
-
-.document_item:hover {
- border-color: var(--color-primary);
- background-color: var(--color-surface);
-}
-
-.message_assistant .document_item {
- background-color: var(--color-bg);
- border-color: var(--color-gray-disabled);
-}
-
-.message_assistant .document_item:hover {
- border-color: var(--color-primary);
- background-color: var(--color-surface);
-}
-
-.document_icon {
- font-size: 16px;
- color: var(--color-secondary);
- flex-shrink: 0;
-
-
-}
-
-.document_info {
- flex: 1;
- min-width: 0;
- display: flex;
- flex-direction: column;
- gap: 2px;
-}
-
-.document_name {
- font-weight: 500;
- color: var(--color-text);
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- font-family: var(--font-family);
-}
-
-.document_meta {
- display: flex;
- gap: 8px;
- font-size: 11px;
- color: var(--color-gray);
- font-family: var(--font-family);
-}
-
-.document_size {
- font-size: 11px;
- color: var(--color-gray);
-}
-
-.document_type {
- font-size: 11px;
- color: var(--color-gray);
-}
-
-.document_actions {
- display: flex;
- gap: 4px;
- opacity: 1;
- transition: opacity 0.2s ease;
-}
-
-.document_item:hover .document_actions {
- opacity: 1;
-}
-
-.document_action_button {
- background: none;
- border: none;
- color: var(--color-gray);
- cursor: pointer;
- padding: 4px;
- border-radius: 4px;
- font-size: 14px;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: all 0.2s ease;
-}
-
-.document_action_button:hover {
- background-color: var(--color-surface);
- color: var(--color-text);
-}
-
-.message_assistant .document_action_button {
- color: var(--color-gray);
-}
-
-.message_assistant .document_action_button:hover {
- background-color: var(--color-surface);
- color: var(--color-text);
-}
\ No newline at end of file
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/DashboardChatArea.tsx b/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/DashboardChatArea.tsx
deleted file mode 100644
index e842786..0000000
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/DashboardChatArea.tsx
+++ /dev/null
@@ -1,104 +0,0 @@
-import React, { useEffect } from "react";
-import { DashboardChatAreaProps } from "./dashboardChatAreaTypes";
-import { useChatLogic } from "./dashboardChatAreaLogic";
-import { useLanguage } from "../../../../contexts/LanguageContext";
-import MessageList from "./DashboardChatAreaMessageList";
-import ChatInput from "./DashboardChatAreaInput";
-import styles from './DashboardChatArea.module.css';
-
-const DashboardChatArea: React.FC = ({
- selectedPrompt,
- onPromptUsed,
- onWorkflowIdChange,
- onWorkflowCompletedChange,
- resumeWorkflowId
-}) => {
- const {
- // State
- inputValue,
- setInputValue,
- currentWorkflowId,
- workflowCompleted,
- attachedFiles,
-
- // Refs
- inputRef,
- messagesEndRef,
-
- // Data from hooks
- messages,
- messagesLoading,
- messagesError,
- startingWorkflow,
- startError,
- workflowStatus,
-
- // Handlers
- handleSend,
- handleKeyPress,
- startNewWorkflow,
- handleStopWorkflow,
- handleFileAttach,
- handleFileRemove,
- handleFilesSelect,
- handleRetry,
-
- // Workflow state
- isWorkflowRunning,
- isStoppingWorkflow,
- shouldShowRetryButton
- } = useChatLogic({
- selectedPrompt,
- onPromptUsed,
- onWorkflowIdChange,
- resumeWorkflowId
- });
-
- const { t } = useLanguage();
-
- // Notify parent component when workflow completion status changes
- useEffect(() => {
- if (onWorkflowCompletedChange) {
- onWorkflowCompletedChange(workflowCompleted);
- }
- }, [workflowCompleted, onWorkflowCompletedChange]);
-
- const placeholder = workflowCompleted ? t('chat.continue_conversation') : t('chat.enter_message');
-
- return (
-
-
-
-
- );
-};
-
-export default DashboardChatArea;
\ No newline at end of file
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/DashboardChatAreaInput.tsx b/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/DashboardChatAreaInput.tsx
deleted file mode 100644
index f0cfc40..0000000
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/DashboardChatAreaInput.tsx
+++ /dev/null
@@ -1,239 +0,0 @@
-import React, { useState, useEffect } from "react";
-import { motion } from "framer-motion";
-import { LuSendHorizontal } from "react-icons/lu";
-import { FaStop } from "react-icons/fa";
-import { IoAttach, IoClose } from "react-icons/io5";
-import { ChatInputProps } from "./dashboardChatAreaTypes";
-import { FileInfo } from "../../../../hooks/useFiles";
-import { useLanguage } from "../../../../contexts/LanguageContext";
-import DateienSelector from "../../../Dateien/DateienHinzufügen/DateienSelector";
-import styles from './DashboardChatArea.module.css';
-
-// Helper function to get file icon based on type
-const getFileIcon = (mimeType?: string): string => {
- if (!mimeType) return '📄';
-
- const type = mimeType.toLowerCase();
-
- if (type.includes('image')) return '🖼️';
- if (type.includes('video')) return '🎥';
- if (type.includes('audio')) return '🎵';
- if (type.includes('pdf')) return '📕';
- if (type.includes('word') || type.includes('document')) return '📘';
- if (type.includes('excel') || type.includes('spreadsheet')) return '📊';
- if (type.includes('powerpoint') || type.includes('presentation')) return '📋';
- if (type.includes('text')) return '📝';
- if (type.includes('zip') || type.includes('archive')) return '📦';
- if (type.includes('javascript') || type.includes('json') || type.includes('html') || type.includes('css')) return '💻';
-
- return '📄';
-};
-
-const ChatInput: React.FC = ({
- inputValue,
- setInputValue,
- onSend,
- onKeyPress,
- isDisabled,
- placeholder,
- inputRef,
- isWorkflowRunning,
- onStopWorkflow,
- isStoppingWorkflow,
- attachedFiles,
- onFileAttach,
- onFileRemove,
- onFilesSelect
-}) => {
- const { t } = useLanguage();
- const [isUploadModalOpen, setIsUploadModalOpen] = useState(false);
- const [isDragOver, setIsDragOver] = useState(false);
-
- // Auto-resize textarea functionality
- useEffect(() => {
- if (inputRef?.current) {
- const textarea = inputRef.current;
- textarea.style.height = 'auto';
-
- // Calculate line height - approximately 1.5em per line
- const lineHeight = 24; // Adjust this value based on your CSS line-height
- const maxHeight = lineHeight * 8; // 8 lines maximum
-
- const newHeight = Math.min(textarea.scrollHeight, maxHeight);
- textarea.style.height = `${newHeight}px`;
-
- // Enable/disable scroll based on content height
- if (textarea.scrollHeight > maxHeight) {
- textarea.style.overflowY = 'auto';
- } else {
- textarea.style.overflowY = 'hidden';
- }
- }
- }, [inputValue, inputRef]);
-
- const handleAttachmentClick = () => {
- setIsUploadModalOpen(true);
- };
-
- const handleFilesSelected = (files: FileInfo[]) => {
- onFilesSelect(files);
- setIsUploadModalOpen(false);
- };
-
- const handleFileRemove = (fileId: number) => {
- onFileRemove(fileId);
- };
-
- // Handle Enter key press for sending message (without Shift)
- const handleKeyDown = (e: React.KeyboardEvent) => {
- if (e.key === 'Enter' && !e.shiftKey) {
- e.preventDefault();
- if (!isDisabled && (inputValue.trim() || attachedFiles.length > 0)) {
- onSend();
- }
- }
- // Call original onKeyPress if it exists (for backward compatibility)
- if (onKeyPress && e.key !== 'Enter') {
- onKeyPress(e as any);
- }
- };
-
- // Drag and drop handlers
- const handleDragEnter = (e: React.DragEvent) => {
- e.preventDefault();
- e.stopPropagation();
- if (!isDisabled && !isWorkflowRunning) {
- setIsDragOver(true);
- }
- };
-
- const handleDragOver = (e: React.DragEvent) => {
- e.preventDefault();
- e.stopPropagation();
- };
-
- const handleDragLeave = (e: React.DragEvent) => {
- e.preventDefault();
- e.stopPropagation();
- // Only set drag over to false if we're leaving the entire input area
- if (!e.currentTarget.contains(e.relatedTarget as Node)) {
- setIsDragOver(false);
- }
- };
-
- const handleDrop = (e: React.DragEvent) => {
- e.preventDefault();
- e.stopPropagation();
- setIsDragOver(false);
-
- if (isDisabled || isWorkflowRunning) {
- return;
- }
-
- const files = Array.from(e.dataTransfer.files);
- if (files.length > 0) {
- // Convert File objects to FileInfo objects
- const fileInfos: FileInfo[] = files.map((file, index) => ({
- id: Date.now() + index, // Generate unique IDs
- name: file.name,
- mimeType: file.type,
- size: file.size,
- creationDate: new Date().toISOString(),
- source: 'user_uploaded'
- }));
-
- onFilesSelect(fileInfos);
- }
- };
-
- return (
-
- {/* Show attached files if any */}
- {attachedFiles.length > 0 && (
-
- {attachedFiles.map((file) => (
-
-
- {getFileIcon(file.mimeType)}
-
-
- {file.name}
-
- handleFileRemove(file.id)}
- title={t('chat.remove_file')}
- >
-
-
-
- ))}
-
- )}
-
- {/* Input row with text input, attachment button, and send button */}
-
-
-
- {/* Upload Modal */}
- setIsUploadModalOpen(false)}
- onFilesSelected={handleFilesSelected}
- />
-
- );
-};
-
-export default ChatInput;
\ No newline at end of file
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/DashboardChatAreaMessageItem.tsx b/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/DashboardChatAreaMessageItem.tsx
deleted file mode 100644
index ab99021..0000000
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/DashboardChatAreaMessageItem.tsx
+++ /dev/null
@@ -1,193 +0,0 @@
-import React, { useState } from "react";
-import { FaDownload } from "react-icons/fa";
-import { MdOutlineRemoveRedEye } from "react-icons/md";
-import { Message, Document } from "./dashboardChatAreaTypes";
-import FilePreviewPopup from "./FilePreviewPopup";
-import { useFileDownload } from "../../../../hooks/useWorkflows";
-import { useLanguage } from "../../../../contexts/LanguageContext";
-import styles from './DashboardChatArea.module.css';
-
-interface MessageItemProps {
- message: Message;
- index: number;
-}
-
-// Helper function to format file size
-const formatFileSize = (bytes?: number): string => {
- if (!bytes) return '';
- const sizes = ['B', 'KB', 'MB', 'GB'];
- const i = Math.floor(Math.log(bytes) / Math.log(1024));
- return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
-};
-
-// Helper function to get file icon based on type or extension
-const getFileIcon = (type?: string, ext?: string): string => {
- // Use extension first if available, then fall back to MIME type
- const extension = ext?.toLowerCase();
- const mimeType = type?.toLowerCase();
-
- // Check extension first
- if (extension) {
- // Images
- if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'].includes(extension)) return '🖼️';
- // Videos
- if (['mp4', 'avi', 'mov', 'wmv', 'flv', 'webm', 'mkv'].includes(extension)) return '🎥';
- // Audio
- if (['mp3', 'wav', 'aac', 'flac', 'ogg', 'wma'].includes(extension)) return '🎵';
- // Documents
- if (extension === 'pdf') return '📕';
- if (['doc', 'docx'].includes(extension)) return '📘';
- if (['xls', 'xlsx'].includes(extension)) return '📊';
- if (['ppt', 'pptx'].includes(extension)) return '📋';
- if (['txt', 'md', 'rtf'].includes(extension)) return '📝';
- // Archives
- if (['zip', 'rar', '7z', 'tar', 'gz'].includes(extension)) return '📦';
- // Code files
- if (['js', 'ts', 'jsx', 'tsx', 'html', 'css', 'py', 'java', 'cpp', 'c', 'php'].includes(extension)) return '💻';
- }
-
- // Fall back to MIME type if extension didn't match
- if (mimeType) {
- if (mimeType.includes('image')) return '🖼️';
- if (mimeType.includes('video')) return '🎥';
- if (mimeType.includes('audio')) return '🎵';
- if (mimeType.includes('pdf')) return '📕';
- if (mimeType.includes('text')) return '📝';
- if (mimeType.includes('word') || mimeType.includes('document')) return '📘';
- if (mimeType.includes('excel') || mimeType.includes('spreadsheet')) return '📊';
- if (mimeType.includes('powerpoint') || mimeType.includes('presentation')) return '📋';
- if (mimeType.includes('zip') || mimeType.includes('archive')) return '📦';
- }
-
- return '📄';
-};
-
-const MessageItem: React.FC = ({ message, index }) => {
- const { t } = useLanguage();
- const [previewDocument, setPreviewDocument] = useState(null);
- const [isPreviewOpen, setIsPreviewOpen] = useState(false);
- const { downloadFile, isDownloading, error: downloadError } = useFileDownload();
-
-
-
- const handleDocumentClick = (document: Document) => {
- // If there's a downloadUrl, use it; otherwise try the url
- const downloadLink = document.downloadUrl || document.url;
-
- if (downloadLink) {
- // Open the document in a new tab
- window.open(downloadLink, '_blank');
- }
- };
-
- const handlePreview = (document: Document, e: React.MouseEvent) => {
- e.stopPropagation();
-
- // Use fileId if available, otherwise try to use id as fallback
- const fileId = document.fileId || document.id;
-
- if (!fileId) {
- return;
- }
-
- setPreviewDocument(document);
- setIsPreviewOpen(true);
- };
-
- const handleClosePreview = () => {
- setIsPreviewOpen(false);
- setPreviewDocument(null);
- };
-
- const handleDownload = async (document: Document, e: React.MouseEvent) => {
- e.stopPropagation();
-
- // Use fileId if available, otherwise try to use id as fallback
- const fileId = document.fileId || document.id;
-
- if (!fileId) {
- return;
- }
-
- // Construct filename with extension if available
- const fileName = document.ext ? `${document.name}.${document.ext}` : document.name;
-
- await downloadFile(fileId, fileName);
- };
-
- return (
-
-
- {message.role === 'user' ? t('chat.you') : message.agentName}
-
-
- {message.content}
-
-
- {message.documents && message.documents.length > 0 && (
-
- {message.documents.map((document, docIndex) => (
-
handleDocumentClick(document)}
- title={`${t('chat.click_to_open')} ${document.name}`}
- >
-
- {getFileIcon(document.type, document.ext)}
-
-
-
- {document.ext ? `${document.name}.${document.ext}` : document.name}
-
-
- {document.size && (
-
- {formatFileSize(document.size)}
-
- )}
-
-
-
- handlePreview(document, e)}
- title={t('chat.preview_document')}
- >
-
-
- handleDownload(document, e)}
- title={t('chat.download_document')}
- >
-
-
-
-
- ))}
-
- )}
-
- {message.timestamp && (
-
- {new Date(message.timestamp).toLocaleTimeString()}
-
- )}
-
- {/* File Preview Popup */}
- {previewDocument && (
-
- )}
-
- );
-};
-
-export default MessageItem;
\ No newline at end of file
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/DashboardChatAreaMessageList.tsx b/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/DashboardChatAreaMessageList.tsx
deleted file mode 100644
index d1224a0..0000000
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/DashboardChatAreaMessageList.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-import React from "react";
-import { motion } from "framer-motion";
-import { MessageListProps } from "./dashboardChatAreaTypes";
-import MessageItem from "./DashboardChatAreaMessageItem";
-import WorkflowStatusDisplay from "./DashbaordChatAreaStatusDisplayold";
-import { useLanguage } from "../../../../contexts/LanguageContext";
-import styles from './DashboardChatArea.module.css';
-
-const MessageList: React.FC = ({
- messages,
- currentWorkflowId,
- workflowStatus,
- workflowCompleted,
- startingWorkflow,
- startError,
- messagesError,
- messagesLoading,
- onStartNewWorkflow,
- messagesEndRef,
- handleRetry,
- shouldShowRetryButton
-}) => {
- const { t } = useLanguage();
-
- return (
-
-
- {startingWorkflow && (
-
-
{workflowCompleted && currentWorkflowId ? t('chat.sending_followup', 'Sending follow-up message...') : t('chat.sending_message', 'Sending message...')}
-
- )}
- {startError && (
-
-
{t('chat.error_prefix', 'Error:')} {startError}
-
- )}
- {messagesError && (
-
-
{t('chat.error_loading_messages', 'Error loading messages:')} {messagesError}
-
- )}
- {currentWorkflowId && messagesLoading && messages.length === 0 && (
-
-
{t('chat.loading_workflow_messages', 'Loading workflow messages...')}
-
- )}
- {messages.length > 0 ? (
- messages.map((message, index) => (
-
- ))
- ) : !currentWorkflowId ? (
-
{t('chat.start_conversation', 'Start a conversation by entering a message, selecting a template, or continuing a previous workflow...')}
- ) : null}
-
- {/* Spacer to push workflow status to bottom when there are fewer messages */}
- {messages.length < 3 &&
}
-
-
-
-
-
-
- );
-};
-
-export default MessageList;
\ No newline at end of file
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/FilePreviewPopup.module.css b/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/FilePreviewPopup.module.css
deleted file mode 100644
index 1aece67..0000000
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/FilePreviewPopup.module.css
+++ /dev/null
@@ -1,455 +0,0 @@
-.overlay {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background-color: var(--color-bg);
- display: flex;
- align-items: center;
- justify-content: center;
- z-index: 9999;
- padding: 20px;
-}
-
-.popup {
- background: var(--color-bg);
- border-radius: 12px;
- box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
- max-width: 90vw;
- height: 90vh;
- width: 80vw;
- display: flex;
- flex-direction: column;
- overflow: hidden;
- font-family: var(--font-family);
-}
-
-.header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 16px 20px;
- border-bottom: 1px solid var(--color-gray-disabled);
- background-color: var(--color-surface);
- flex-shrink: 0;
-}
-
-.title {
- margin: 0;
- font-size: 18px;
- font-weight: 600;
- color: var(--color-text);
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- flex: 1;
- margin-right: 16px;
- font-family: var(--font-family);
-}
-
-.close_button {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 32px;
- height: 32px;
- border: none;
- border-radius: 8px;
- background-color: transparent;
- color: var(--color-gray);
- cursor: pointer;
- transition: all 0.2s ease;
- font-size: 18px;
- flex-shrink: 0;
-}
-
-.close_button:hover {
- background-color: var(--color-gray-disabled);
- color: var(--color-text);
-}
-
-.content {
- flex: 1;
- display: flex;
- align-items: flex-start;
- justify-content: center;
- padding: 20px;
- overflow: hidden;
- height: 0;
-}
-
-.loading {
- display: flex;
- align-items: center;
- justify-content: center;
- color: var(--color-gray);
- font-size: 16px;
- width: 100%;
- height: 100%;
- font-family: var(--font-family);
-}
-
-.error {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- color: var(--color-red);
- font-size: 16px;
- text-align: center;
- width: 100%;
- height: 100%;
- font-family: var(--font-family);
-}
-
-.no_preview {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- color: var(--color-gray);
- font-size: 16px;
- font-style: italic;
- width: 100%;
- height: 100%;
- font-family: var(--font-family);
-}
-
-.image_preview {
- max-width: 100%;
- max-height: 100%;
- object-fit: contain;
- border-radius: 8px;
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
-}
-
-.pdf_preview {
- width: 100%;
- height: 100%;
- border: none;
- border-radius: 8px;
-}
-
-.text_preview {
- width: 100%;
- height: 100%;
- background-color: var(--color-bg);
- border: 1px solid var(--color-gray-disabled);
- border-radius: 8px;
- padding: 16px;
- font-family: 'Courier New', monospace;
- font-size: 14px;
- line-height: 1.5;
- color: var(--color-text);
- overflow: auto;
- white-space: pre-wrap;
- word-wrap: break-word;
- box-sizing: border-box;
-}
-
-.enhanced_text_preview {
- width: 100%;
- height: 100%;
- background-color: var(--color-bg);
- border: 1px solid var(--color-gray-disabled);
- border-radius: 8px;
- padding: 32px;
- overflow: auto;
- font-family: var(--font-family);
- box-sizing: border-box;
- line-height: 1.7;
- color: var(--color-text);
-}
-
-.text_line {
- margin-bottom: 4px;
- word-wrap: break-word;
- white-space: pre-wrap;
-}
-
-.text_line_break {
- height: 16px;
-}
-
-.text_header {
- font-weight: 600;
- font-size: 1.1em;
- color: var(--color-text);
- margin: 16px 0 8px 0;
- padding-bottom: 4px;
- border-bottom: 1px solid var(--color-gray-disabled);
- font-family: var(--font-family);
-}
-
-.text_numbered {
- margin: 8px 0;
- padding-left: 8px;
- color: var(--color-text);
- font-family: var(--font-family);
-}
-
-.text_bullet {
- margin: 4px 0;
- padding-left: 8px;
- color: var(--color-text);
- font-family: var(--font-family);
-}
-
-.text_indented {
- background-color: var(--color-surface);
- padding: 8px 12px;
- margin: 4px 0;
- border-left: 3px solid var(--color-gray-disabled);
- border-radius: 4px;
- font-family: 'Courier New', monospace;
- font-size: 0.9em;
- color: var(--color-text);
-}
-
-.code_preview {
- width: 100%;
- height: 100%;
- background-color: var(--color-surface);
- border: 1px solid var(--color-gray-disabled);
- border-radius: 8px;
- overflow: auto;
- font-family: 'Courier New', monospace;
- font-size: 14px;
- line-height: 1.4;
- color: var(--color-text);
- box-sizing: border-box;
- display: flex;
- flex-direction: column;
-}
-
-.python_code_preview {
- width: 100%;
- height: 100%;
- background-color: var(--color-surface);
- border: 1px solid var(--color-gray-disabled);
- border-radius: 8px;
- overflow: auto;
- box-sizing: border-box;
- display: flex;
- flex-direction: column;
-}
-
-.code_header {
- background-color: var(--color-gray-disabled);
- padding: 8px 16px;
- border-bottom: 1px solid var(--color-gray-disabled);
- display: flex;
- justify-content: space-between;
- align-items: center;
- flex-shrink: 0;
-}
-
-.code_language {
- font-size: 12px;
- font-weight: 600;
- color: var(--color-text);
- text-transform: uppercase;
- letter-spacing: 0.5px;
- font-family: var(--font-family);
-}
-
-.code_filename {
- font-size: 12px;
- color: var(--color-gray);
- font-family: var(--font-family);
-}
-
-.python_code_content {
- padding: 16px;
- overflow: auto;
- flex: 1;
- background-color: var(--color-bg);
- font-family: 'Courier New', monospace;
- font-size: 14px;
- line-height: 1.4;
- color: var(--color-text);
- white-space: pre;
- word-wrap: break-word;
-}
-
-.python_code_content code {
- font-family: 'Courier New', monospace;
- font-size: 14px;
- line-height: 1.4;
- color: var(--color-text);
- background: none;
- padding: 0;
-}
-
-.markdown_preview {
- width: 100%;
- height: 100%;
- background-color: var(--color-bg);
- border: 1px solid var(--color-gray-disabled);
- border-radius: 8px;
- padding: 32px;
- overflow: auto;
- font-family: var(--font-family);
- box-sizing: border-box;
- line-height: 1.6;
- color: var(--color-text);
-}
-
-.markdown_preview h1 {
- font-size: 2em;
- font-weight: 700;
- margin: 0 0 16px 0;
- color: var(--color-text);
- border-bottom: 2px solid var(--color-gray-disabled);
- padding-bottom: 8px;
-}
-
-.markdown_preview h2 {
- font-size: 1.5em;
- font-weight: 600;
- margin: 24px 0 12px 0;
- color: var(--color-text);
-}
-
-.markdown_preview h3 {
- font-size: 1.25em;
- font-weight: 600;
- margin: 20px 0 10px 0;
- color: var(--color-text);
-}
-
-.markdown_preview h4,
-.markdown_preview h5,
-.markdown_preview h6 {
- font-size: 1.1em;
- font-weight: 600;
- margin: 16px 0 8px 0;
- color: var(--color-text);
-}
-
-.markdown_preview p {
- margin: 0 0 16px 0;
- line-height: 1.7;
-}
-
-.markdown_preview ul,
-.markdown_preview ol {
- margin: 0 0 16px 20px;
- line-height: 1.7;
-}
-
-.markdown_preview li {
- margin: 4px 0;
- line-height: 1.6;
-}
-
-.markdown_preview blockquote {
- margin: 16px 0;
- padding: 12px 16px;
- border-left: 4px solid var(--color-primary);
- background-color: var(--color-surface);
- font-style: italic;
- color: var(--color-gray);
-}
-
-.markdown_preview code {
- background-color: var(--color-surface);
- padding: 2px 6px;
- border-radius: 4px;
- font-family: 'Courier New', monospace;
- font-size: 0.9em;
- color: var(--color-secondary);
-}
-
-.markdown_preview pre {
- background-color: var(--color-surface);
- border: 1px solid var(--color-gray-disabled);
- border-radius: 8px;
- padding: 16px;
- margin: 16px 0;
- overflow-x: auto;
- font-family: 'Courier New', monospace;
- font-size: 14px;
- line-height: 1.4;
-}
-
-.markdown_preview pre code {
- background: none;
- padding: 0;
- border-radius: 0;
- color: var(--color-text);
-}
-
-.markdown_preview table {
- border-collapse: collapse;
- width: 100%;
- margin: 16px 0;
- border: 1px solid var(--color-gray-disabled);
-}
-
-.markdown_preview th,
-.markdown_preview td {
- border: 1px solid var(--color-gray-disabled);
- padding: 8px 12px;
- text-align: left;
-}
-
-.markdown_preview th {
- background-color: var(--color-surface);
- font-weight: 600;
-}
-
-.markdown_preview td {
- background-color: var(--color-bg);
-}
-
-.markdown_preview a {
- color: var(--color-secondary);
- text-decoration: underline;
-}
-
-.markdown_preview a:hover {
- color: var(--color-secondary-hover);
-}
-
-.markdown_preview hr {
- border: none;
- height: 1px;
- background-color: var(--color-gray-disabled);
- margin: 24px 0;
-}
-
-.markdown_preview strong {
- font-weight: 700;
- color: var(--color-text);
-}
-
-.markdown_preview em {
- font-style: italic;
- color: var(--color-gray);
-}
-
-/* Responsive design */
-@media (max-width: 768px) {
- .popup {
- width: 95vw;
- height: 85vh;
- }
-
- .header {
- padding: 12px 16px;
- }
-
- .title {
- font-size: 16px;
- }
-
- .content {
- padding: 16px;
- }
-
- .pdf_preview {
- height: calc(100% - 60px);
- }
-}
\ No newline at end of file
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/FilePreviewPopup.tsx b/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/FilePreviewPopup.tsx
deleted file mode 100644
index 8685c4a..0000000
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/FilePreviewPopup.tsx
+++ /dev/null
@@ -1,247 +0,0 @@
-import React, { useEffect } from "react";
-import ReactMarkdown from 'react-markdown';
-import { MdClose } from "react-icons/md";
-import { Document } from "./dashboardChatAreaTypes";
-import { useFilePreview } from "../../../../hooks/useWorkflows";
-import { useLanguage } from "../../../../contexts/LanguageContext";
-import styles from './FilePreviewPopup.module.css';
-
-interface FilePreviewPopupProps {
- document: Document;
- isOpen: boolean;
- onClose: () => void;
-}
-
-const FilePreviewPopup: React.FC = ({ document, isOpen, onClose }) => {
- const { t } = useLanguage();
- const { previewContent, fileMetadata, isLoading, error, fetchPreview, clearPreview } = useFilePreview();
-
- useEffect(() => {
- if (isOpen && document) {
- // Use fileId if available, otherwise try to use id as fallback
- const fileId = document.fileId || document.id;
-
- if (fileId) {
- console.log('FilePreviewPopup: calling fetchPreview with fileId:', fileId);
- fetchPreview(String(fileId));
- } else {
- console.error('FilePreviewPopup: No fileId or id available on document:', document);
- }
- } else if (!isOpen) {
- clearPreview();
- }
- }, [isOpen, document.fileId, document.id]);
-
- const handleBackdropClick = (e: React.MouseEvent) => {
- if (e.target === e.currentTarget) {
- onClose();
- }
- };
-
- const getPreviewComponent = () => {
- if (isLoading) {
- return {t('file_preview.loading')}
;
- }
-
- if (error) {
- return (
-
-
{t('file_preview.error')}: {error}
- {fileMetadata && (
-
- Debug: {JSON.stringify(fileMetadata, null, 2)}
-
- )}
-
- );
- }
-
- if (!previewContent) {
- return (
-
-
{t('file_preview.no_preview')}
- {fileMetadata && (
-
- Available metadata: {Object.keys(fileMetadata).join(', ')}
-
- Preview field: {fileMetadata.preview ? 'has data' : 'empty/null'}
-
- Base64Encoded: {String(fileMetadata.base64Encoded)}
-
- MimeType: {fileMetadata.mimeType}
-
- )}
-
- );
- }
-
- // Use metadata from backend response, but prioritize file extension over potentially incorrect MIME type
- const mimeType = fileMetadata?.mimeType;
- const isBase64Encoded = fileMetadata?.base64Encoded;
- const fileExtension = document.ext?.toLowerCase();
-
- // Check if this is a markdown file by extension first (more reliable than backend MIME type)
- const isMarkdownByType = fileExtension === 'md' ||
- fileExtension === 'markdown' ||
- mimeType === 'text/markdown' ||
- mimeType === 'text/x-markdown';
-
- // Content-based markdown detection for .txt files with markdown content
- // BUT NOT for specific code file types
- const isCodeFile = fileExtension === 'py' ||
- fileExtension === 'js' ||
- fileExtension === 'ts' ||
- fileExtension === 'jsx' ||
- fileExtension === 'tsx' ||
- fileExtension === 'java' ||
- fileExtension === 'cpp' ||
- fileExtension === 'c' ||
- fileExtension === 'php' ||
- fileExtension === 'html' ||
- fileExtension === 'css';
-
- const hasMarkdownContent = !isCodeFile && previewContent && (
- previewContent.includes('# ') || // Headers
- previewContent.includes('## ') || // Headers
- previewContent.includes('**') || // Bold
- previewContent.includes('__') || // Bold
- previewContent.includes('- ') || // Lists
- previewContent.includes('* ') || // Lists
- previewContent.includes('1. ') || // Numbered lists
- previewContent.includes('```') || // Code blocks
- previewContent.includes('[') && previewContent.includes('](') // Links
- );
-
- // For .txt files or text MIME types, check for markdown content
- const isTxtWithMarkdown = (fileExtension === 'txt' || mimeType?.startsWith('text/')) && hasMarkdownContent;
- const isMarkdown = isMarkdownByType || isTxtWithMarkdown;
-
- // Debug logging
- console.log('FilePreviewPopup preview detection:', {
- fileExtension,
- mimeType,
- isMarkdownByType,
- hasMarkdownContent,
- isTxtWithMarkdown,
- isMarkdown,
- isCodeFile
- });
-
- if (mimeType?.startsWith('image/')) {
- // Image preview
- const imageSrc = isBase64Encoded
- ? `data:${mimeType};base64,${previewContent}`
- : previewContent;
-
- return (
-
- );
- } else if (fileExtension === 'pdf' || mimeType === 'application/pdf') {
- // PDF preview
- const pdfSrc = isBase64Encoded
- ? `data:application/pdf;base64,${previewContent}`
- : previewContent;
-
- return (
-
- );
- } else if (isMarkdown) {
- // Markdown preview
- console.log('Rendering markdown with ReactMarkdown:', previewContent?.substring(0, 200));
-
- return (
-
- {previewContent}
-
- );
- } else if (fileExtension === 'py') {
- // Python code preview
- return (
-
-
- {t('file_preview.python')}
-
- {document.ext ? `${document.name}.${document.ext}` : document.name}
-
-
-
- {previewContent}
-
-
- );
- } else if ((mimeType?.startsWith('text/') || fileExtension === 'txt') && !isMarkdown) {
- // Enhanced text preview for text files that are not markdown
- return (
-
- {previewContent?.split('\n').map((line, index) => {
- // Handle empty lines
- if (line.trim() === '') {
- return
;
- }
-
- // Check if line looks like a header (all caps, starts with numbers, etc.)
- const isHeader = line.match(/^[A-Z\s\d\.\-_]+:?\s*$/) && line.length < 80;
- const isNumberedItem = line.match(/^\s*\d+\.\s/);
- const isBulletItem = line.match(/^\s*[-*•]\s/);
- const isIndented = line.match(/^\s{4,}/);
-
- return (
-
- {line}
-
- );
- })}
-
- );
- } else {
- // Code/raw text preview for non-text files
- return (
-
- {previewContent}
-
- );
- }
- };
-
- if (!isOpen) return null;
-
- return (
-
-
-
-
- {document.ext ? `${document.name}.${document.ext}` : document.name}
-
-
-
-
-
-
- {getPreviewComponent()}
-
-
-
- );
-};
-
-export default FilePreviewPopup;
\ No newline at end of file
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/dashboardChatAreaLogic.ts b/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/dashboardChatAreaLogic.ts
deleted file mode 100644
index f567300..0000000
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/dashboardChatAreaLogic.ts
+++ /dev/null
@@ -1,316 +0,0 @@
-import { useState, useEffect, useRef } from "react";
-import { Prompt } from "../../../../hooks/usePrompts";
-import { FileInfo, useFileOperations } from "../../../../hooks/useFiles";
-import { useWorkflowOperations, useWorkflowMessages, useWorkflowStatus } from "../../../../hooks/useWorkflows";
-
-interface UseChatLogicProps {
- selectedPrompt?: Prompt | null;
- onPromptUsed?: () => void;
- onWorkflowIdChange?: (workflowId: string | null) => void;
- resumeWorkflowId?: string | null;
-}
-
-export const useChatLogic = ({
- selectedPrompt,
- onPromptUsed,
- onWorkflowIdChange,
- resumeWorkflowId
-}: UseChatLogicProps) => {
- const [inputValue, setInputValue] = useState("");
- const [currentWorkflowId, setCurrentWorkflowId] = useState(null);
- const [workflowCompleted, setWorkflowCompleted] = useState(false);
- const [attachedFiles, setAttachedFiles] = useState([]);
- const inputRef = useRef(null);
- const messagesEndRef = useRef(null);
-
- const { startWorkflow, startingWorkflow, startError, stopWorkflow, stoppingWorkflows } = useWorkflowOperations();
- const { messages, loading: messagesLoading, error: messagesError, refetch: refetchMessages } = useWorkflowMessages(currentWorkflowId);
- const { status: workflowStatus, refetch: refetchStatus } = useWorkflowStatus(currentWorkflowId);
- const { handleFileUpload } = useFileOperations();
-
- // Update input value when a prompt is selected
- useEffect(() => {
- if (selectedPrompt) {
- setInputValue(selectedPrompt.content);
- // Focus the input field
- if (inputRef.current) {
- inputRef.current.focus();
- }
- }
- }, [selectedPrompt]);
-
- // Auto-scroll to bottom when new messages arrive or workflow status changes
- useEffect(() => {
- if (messagesEndRef.current) {
- messagesEndRef.current.scrollIntoView({ behavior: 'smooth' });
- }
- }, [messages, workflowCompleted, workflowStatus]);
-
- // Polling logic for fetching messages and status
- useEffect(() => {
- if (!currentWorkflowId || workflowCompleted) return;
-
- const interval = setInterval(() => {
- refetchMessages();
- refetchStatus();
- }, 1000); // Poll every second
-
- return () => clearInterval(interval);
- }, [currentWorkflowId, workflowCompleted, refetchMessages, refetchStatus]);
-
- // Simple workflow completion detection
- useEffect(() => {
- const isCompleted = workflowStatus && (
- workflowStatus.status === 'completed' ||
- workflowStatus.status === 'finished' ||
- workflowStatus.status === 'done' ||
- workflowStatus.status === 'stopped' ||
- workflowStatus.status === 'error'
- );
-
- setWorkflowCompleted(!!isCompleted);
- }, [workflowStatus]);
-
- // Handle workflow ID changes
- useEffect(() => {
- if (currentWorkflowId && onWorkflowIdChange) {
- onWorkflowIdChange(currentWorkflowId);
- }
- }, [currentWorkflowId, onWorkflowIdChange]);
-
- // Handle workflow resumption
- useEffect(() => {
- if (resumeWorkflowId && resumeWorkflowId !== currentWorkflowId) {
- setCurrentWorkflowId(resumeWorkflowId);
- setWorkflowCompleted(false);
- setInputValue("");
- setAttachedFiles([]);
- }
- }, [resumeWorkflowId, currentWorkflowId]);
-
- const handleFileAttach = async (file: File) => {
- try {
- console.log('Uploading file:', file.name);
- const result = await handleFileUpload(file, currentWorkflowId || undefined);
-
- if (result.success && result.fileData) {
- // Add the uploaded file to the attached files list
- const fileInfo: FileInfo = {
- id: result.fileData.id,
- name: result.fileData.name || file.name,
- mimeType: result.fileData.mimeType || file.type,
- size: result.fileData.size || file.size,
- creationDate: result.fileData.creationDate || new Date().toISOString(),
- workflowId: currentWorkflowId || undefined
- };
-
- setAttachedFiles(prev => [...prev, fileInfo]);
- console.log('File uploaded successfully:', fileInfo);
- } else {
- console.error('Failed to upload file:', result.error);
- }
- } catch (error) {
- console.error('Error uploading file:', error);
- }
- };
-
- const handleFileRemove = (fileId: number) => {
- setAttachedFiles(prev => prev.filter(file => file.id !== fileId));
- };
-
- const handleFilesSelect = (selectedFiles: FileInfo[]) => {
- // Add selected files to the attached files list, avoiding duplicates
- setAttachedFiles(prev => {
- const existingIds = new Set(prev.map(f => f.id));
- const newFiles = selectedFiles.filter(f => !existingIds.has(f.id));
- return [...prev, ...newFiles];
- });
- };
-
- const handleSend = async () => {
- if (inputValue.trim() || attachedFiles.length > 0) {
- console.log('Sending message:', inputValue, 'with files:', attachedFiles.map(f => f.id));
-
- try {
- let result;
-
- // Prepare file IDs for the request
- const listFileId = attachedFiles.map(file => file.id);
-
- // If we have a completed workflow, send as follow-up using the existing workflow ID
- if (workflowCompleted && currentWorkflowId) {
- console.log('Sending follow-up message to workflow:', currentWorkflowId);
- result = await startWorkflow({
- prompt: inputValue || "Files attached", // Provide a default message if only files are sent
- listFileId: listFileId
- }, currentWorkflowId);
-
- if (result.success) {
- console.log('Follow-up message sent successfully');
- // Reset workflow completion state to resume polling for messages/status
- // but DON'T reset logPollingCompleted - logs should stay stopped
- setWorkflowCompleted(false);
- }
- } else {
- // Start a new workflow
- console.log('Starting new workflow');
- // Reset previous workflow state when starting a new one
- setCurrentWorkflowId(null);
- setWorkflowCompleted(false);
-
- result = await startWorkflow({
- prompt: inputValue || "Files attached", // Provide a default message if only files are sent
- listFileId: listFileId
- });
-
- if (result.success && result.data) {
- console.log('Workflow started successfully:', result.data);
- // Set the workflow ID to start polling for messages
- setCurrentWorkflowId(result.data.id);
- setWorkflowCompleted(false);
- }
- }
-
- if (result.success) {
- // Clear the input and attached files after successful send
- setInputValue("");
- setAttachedFiles([]);
- // Call onPromptUsed if a prompt was used
- if (selectedPrompt && onPromptUsed) {
- onPromptUsed();
- }
- } else {
- console.error('Failed to send message:', result.error);
- }
- } catch (error) {
- console.error('Error sending message:', error);
- }
- }
- };
-
- const handleKeyPress = (e: React.KeyboardEvent) => {
- if (e.key === 'Enter' && !e.shiftKey) {
- e.preventDefault();
- handleSend();
- }
- };
-
- const startNewWorkflow = () => {
- setCurrentWorkflowId(null);
- setWorkflowCompleted(false);
- setInputValue("");
- setAttachedFiles([]);
- if (onWorkflowIdChange) {
- onWorkflowIdChange(null);
- }
- };
-
- const handleStopWorkflow = async () => {
- if (currentWorkflowId) {
- console.log('Stopping workflow:', currentWorkflowId);
- const success = await stopWorkflow(currentWorkflowId);
- if (success) {
- console.log('Workflow stopped successfully');
- // Refresh status to get updated workflow state
- refetchStatus();
- } else {
- console.error('Failed to stop workflow');
- }
- }
- };
-
- // Determine if workflow is currently running
- const isWorkflowRunning = !!(currentWorkflowId && !workflowCompleted && workflowStatus &&
- workflowStatus.status !== 'completed' &&
- workflowStatus.status !== 'finished' &&
- workflowStatus.status !== 'done' &&
- workflowStatus.status !== 'stopped' &&
- workflowStatus.status !== 'error');
-
- const isStoppingWorkflow = currentWorkflowId ? stoppingWorkflows.has(currentWorkflowId) : false;
-
- const handleRetry = async () => {
- if (!currentWorkflowId || !messages.length) {
- console.error('No workflow ID or messages available for retry');
- return;
- }
-
- // Find the last user message to retry
- const userMessages = messages.filter(msg => msg.role === 'user');
- const lastUserMessage = userMessages[userMessages.length - 1];
-
- if (!lastUserMessage) {
- console.error('No user message found to retry');
- return;
- }
-
- console.log('Retrying workflow with last user message:', lastUserMessage.content);
-
- try {
- // Extract file IDs if available from the message
- const fileIds = lastUserMessage.fileIds || [];
-
- // Start the workflow again with the same prompt and files
- const result = await startWorkflow({
- prompt: lastUserMessage.content,
- listFileId: fileIds
- }, currentWorkflowId);
-
- if (result.success) {
- console.log('Workflow retry started successfully');
- // Reset workflow completion state to resume polling
- setWorkflowCompleted(false);
- } else {
- console.error('Failed to retry workflow:', result.error);
- }
- } catch (error) {
- console.error('Error retrying workflow:', error);
- }
- };
-
- const shouldShowRetryButton = () => {
- if (!workflowStatus) return false;
-
- const statusLower = workflowStatus.status.toLowerCase();
- return statusLower === 'error' ||
- statusLower === 'failed' ||
- statusLower === 'stopped' ||
- statusLower === 'cancelled';
- };
-
- return {
- // State
- inputValue,
- setInputValue,
- currentWorkflowId,
- workflowCompleted,
- attachedFiles,
-
- // Refs
- inputRef,
- messagesEndRef,
-
- // Data from hooks
- messages,
- messagesLoading,
- messagesError,
- startingWorkflow,
- startError,
- workflowStatus,
-
- // Handlers
- handleSend,
- handleKeyPress,
- startNewWorkflow,
- handleStopWorkflow,
- handleFileAttach,
- handleFileRemove,
- handleFilesSelect,
- handleRetry,
-
- // Workflow state
- isWorkflowRunning,
- isStoppingWorkflow,
- shouldShowRetryButton
- };
-};
\ No newline at end of file
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/dashboardChatAreaTypes.ts b/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/dashboardChatAreaTypes.ts
deleted file mode 100644
index 9f163da..0000000
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/dashboardChatAreaTypes.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-import { Prompt } from "../../../../hooks/usePrompts";
-import { FileInfo } from "../../../../hooks/useFiles";
-
-export interface DashboardChatAreaProps {
- selectedPrompt?: Prompt | null;
- onPromptUsed?: () => void;
- onWorkflowIdChange?: (workflowId: string | null) => void;
- onWorkflowCompletedChange?: (completed: boolean) => void;
- resumeWorkflowId?: string | null;
-}
-
-export interface Document {
- id?: string;
- fileId?: number;
- name: string;
- url?: string;
- type?: string;
- size?: number;
- downloadUrl?: string;
- ext?: string;
-}
-
-export interface Message {
- id?: string;
- role: 'user' | 'assistant' | 'system';
- agentName: string;
- content: string;
- timestamp?: string;
- documents?: Document[];
-}
-
-export interface WorkflowStatus {
- status: string;
- currentRound?: number;
-}
-
-export interface ChatInputProps {
- inputValue: string;
- setInputValue: (value: string) => void;
- onSend: () => void;
- onKeyPress: (e: React.KeyboardEvent) => void;
- isDisabled: boolean;
- placeholder: string;
- inputRef: React.RefObject;
- isWorkflowRunning: boolean;
- onStopWorkflow: () => void;
- isStoppingWorkflow: boolean;
- attachedFiles: FileInfo[];
- onFileAttach: (file: File) => void;
- onFileRemove: (fileId: number) => void;
- onFilesSelect: (files: FileInfo[]) => void;
-}
-
-export interface MessageListProps {
- messages: Message[];
- currentWorkflowId: string | null;
- workflowStatus: WorkflowStatus | null;
- workflowCompleted: boolean;
- startingWorkflow: boolean;
- startError: string | null;
- messagesError: string | null;
- messagesLoading: boolean;
- onStartNewWorkflow: () => void;
- messagesEndRef: React.RefObject;
- handleRetry: () => Promise;
- shouldShowRetryButton: () => boolean;
-}
-
-export interface WorkflowStatusDisplayProps {
- currentWorkflowId: string | null;
- workflowStatus: WorkflowStatus | null;
- workflowCompleted: boolean;
- onStartNewWorkflow: () => void;
- handleRetry: () => Promise;
- shouldShowRetryButton: () => boolean;
-}
\ No newline at end of file
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/README.md b/src/components/Dashboard/DashboardChat/DashboardChatArea/README.md
deleted file mode 100644
index 499aec7..0000000
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/README.md
+++ /dev/null
@@ -1,109 +0,0 @@
-# DashboardChatArea - Modular Structure
-
-This directory contains the refactored `DashboardChatArea` component, broken down into manageable modules for better maintainability and separation of concerns.
-
-## File Structure
-
-```
-DashboardChatArea/
-├── index.ts # Main export file
-├── types.ts # TypeScript interfaces and types
-├── DashboardChatArea.tsx # Main orchestrating component
-├── useChatLogic.ts # Custom hook with all business logic
-├── MessageList.tsx # Component for displaying messages
-├── MessageItem.tsx # Individual message component
-├── ChatInput.tsx # Input field and send button component
-├── WorkflowStatusDisplay.tsx # Workflow status and completion UI
-├── DashboardChatArea.module.css # Shared styles
-└── README.md # This documentation
-```
-
-## Component Responsibilities
-
-### `DashboardChatArea.tsx` (Main Component)
-- **Purpose**: Orchestrates all child components
-- **Responsibilities**:
- - Uses the `useChatLogic` hook
- - Renders `MessageList` and `ChatInput` components
- - Passes props between components
-- **Size**: ~73 lines (reduced from 278 lines)
-
-### `useChatLogic.ts` (Custom Hook)
-- **Purpose**: Contains all business logic and state management
-- **Responsibilities**:
- - State management (input value, workflow ID, completion status)
- - Effects for polling, auto-scroll, prompt handling
- - Workflow operations (send messages, start workflows)
- - Event handlers
-- **Size**: ~196 lines
-
-### `MessageList.tsx` (Message Display)
-- **Purpose**: Handles the display of all messages and status indicators
-- **Responsibilities**:
- - Renders loading and error states
- - Maps through messages using `MessageItem`
- - Includes `WorkflowStatusDisplay`
- - Handles auto-scroll reference
-- **Size**: ~73 lines
-
-### `MessageItem.tsx` (Individual Message)
-- **Purpose**: Renders a single message
-- **Responsibilities**:
- - Message content display
- - Role-based styling
- - Timestamp formatting
-- **Size**: ~32 lines
-
-### `ChatInput.tsx` (Input Interface)
-- **Purpose**: Handles user input and send functionality
-- **Responsibilities**:
- - Input field with ref handling
- - Send button with animations
- - Keyboard event handling
- - Disabled states
-- **Size**: ~46 lines
-
-### `WorkflowStatusDisplay.tsx` (Status UI)
-- **Purpose**: Shows workflow status and completion states
-- **Responsibilities**:
- - Running workflow status
- - Completion message
- - "Start New Workflow" button
-- **Size**: ~38 lines
-
-### `types.ts` (Type Definitions)
-- **Purpose**: Centralized TypeScript interfaces
-- **Responsibilities**:
- - Component prop interfaces
- - Data structure types
- - Shared type definitions
-- **Size**: ~50 lines
-
-## Benefits of This Structure
-
-1. **Separation of Concerns**: Each file has a single, clear responsibility
-2. **Reusability**: Components can be easily reused or tested independently
-3. **Maintainability**: Easier to locate and modify specific functionality
-4. **Readability**: Smaller files are easier to understand and navigate
-5. **Testing**: Individual components can be unit tested in isolation
-6. **Type Safety**: Centralized types ensure consistency across components
-
-## Usage
-
-Import the main component as before:
-
-```typescript
-import DashboardChatArea from './DashboardChatArea';
-// or
-import DashboardChatArea, { DashboardChatAreaProps } from './DashboardChatArea';
-```
-
-The API remains exactly the same - this refactoring is purely internal and doesn't affect how the component is used by parent components.
-
-## Development Guidelines
-
-- **Adding new features**: Consider which component/file is most appropriate
-- **State changes**: Most state logic should go in `useChatLogic.ts`
-- **UI changes**: Modify the relevant component file
-- **New types**: Add to `types.ts`
-- **Styling**: All styles remain in `DashboardChatArea.module.css`
\ No newline at end of file
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/index.ts b/src/components/Dashboard/DashboardChat/DashboardChatArea/index.ts
deleted file mode 100644
index 79a448b..0000000
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default } from './DashboardChatArea';
-export type { DashboardChatAreaProps } from './dashboardChatAreaTypes';
\ No newline at end of file
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaConnectedFiles.tsx b/src/components/Dashboard/DashboardChat/DashboardChatAreaConnectedFiles.tsx
similarity index 99%
rename from src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaConnectedFiles.tsx
rename to src/components/Dashboard/DashboardChat/DashboardChatAreaConnectedFiles.tsx
index 76b74c9..e659a77 100644
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaConnectedFiles.tsx
+++ b/src/components/Dashboard/DashboardChat/DashboardChatAreaConnectedFiles.tsx
@@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react';
-import { useFileDownload } from '../../../../hooks/useWorkflows';
+import { useFileDownload } from '../../../hooks/useWorkflows';
import { FileInfo } from './dashboardChatAreaTypes';
interface AttachedFile {
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaFilePreview.tsx b/src/components/Dashboard/DashboardChat/DashboardChatAreaFilePreview.tsx
similarity index 99%
rename from src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaFilePreview.tsx
rename to src/components/Dashboard/DashboardChat/DashboardChatAreaFilePreview.tsx
index f909faf..aafa126 100644
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaFilePreview.tsx
+++ b/src/components/Dashboard/DashboardChat/DashboardChatAreaFilePreview.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { useFilePreview } from '../../../../hooks/useWorkflows';
+import { useFilePreview } from '../../../hooks/useWorkflows';
import { FileInfo } from './dashboardChatAreaTypes';
interface AttachedFileWithData extends FileInfo {
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaInput.tsx b/src/components/Dashboard/DashboardChat/DashboardChatAreaInput.tsx
similarity index 98%
rename from src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaInput.tsx
rename to src/components/Dashboard/DashboardChat/DashboardChatAreaInput.tsx
index 106715d..6202509 100644
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaInput.tsx
+++ b/src/components/Dashboard/DashboardChat/DashboardChatAreaInput.tsx
@@ -1,6 +1,6 @@
import React, { useState, useEffect } from 'react';
-import { useWorkflowOperations } from '../../../../hooks/useWorkflows';
-import { Prompt } from '../../../../hooks/usePrompts';
+import { useWorkflowOperations } from '../../../hooks/useWorkflows';
+import { Prompt } from '../../../hooks/usePrompts';
import FileAttachmentPopup from './FileAttachmentPopup';
interface InputAreaProps {
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaMessageItem.tsx b/src/components/Dashboard/DashboardChat/DashboardChatAreaMessageItem.tsx
similarity index 98%
rename from src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaMessageItem.tsx
rename to src/components/Dashboard/DashboardChat/DashboardChatAreaMessageItem.tsx
index da481ca..9f3ee3b 100644
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaMessageItem.tsx
+++ b/src/components/Dashboard/DashboardChat/DashboardChatAreaMessageItem.tsx
@@ -1,8 +1,8 @@
import React, { useState } from "react";
import { FaDownload } from "react-icons/fa";
import { MdOutlineRemoveRedEye } from "react-icons/md";
-import { useFileDownload } from "../../../../hooks/useWorkflows";
-import { useLanguage } from "../../../../contexts/LanguageContext";
+import { useFileDownload } from "../../../hooks/useWorkflows";
+import { useLanguage } from "../../../contexts/LanguageContext";
import { Message, Document } from "./dashboardChatAreaTypes";
interface MessageItemProps {
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaMessageList.tsx b/src/components/Dashboard/DashboardChat/DashboardChatAreaMessageList.tsx
similarity index 98%
rename from src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaMessageList.tsx
rename to src/components/Dashboard/DashboardChat/DashboardChatAreaMessageList.tsx
index f3af60f..bac92ed 100644
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaMessageList.tsx
+++ b/src/components/Dashboard/DashboardChat/DashboardChatAreaMessageList.tsx
@@ -1,7 +1,7 @@
import React, { useEffect, useRef, useState, useCallback } from 'react';
-import { useWorkflowStatus } from '../../../../hooks/useWorkflows';
-import { Prompt } from '../../../../hooks/usePrompts';
-import { useApiRequest } from '../../../../hooks/useApi';
+import { useWorkflowStatus } from '../../../hooks/useWorkflows';
+import { Prompt } from '../../../hooks/usePrompts';
+import { useApiRequest } from '../../../hooks/useApi';
import MessageItem from './DashboardChatAreaMessageItem';
import { Message, Document, WorkflowMessage } from './dashboardChatAreaTypes';
diff --git a/src/components/Dashboard/DashboardChat/DashboardChat.module.css b/src/components/Dashboard/DashboardChat/DashboardChatAreaStyles/DashboardChat.module.css
similarity index 100%
rename from src/components/Dashboard/DashboardChat/DashboardChat.module.css
rename to src/components/Dashboard/DashboardChat/DashboardChatAreaStyles/DashboardChat.module.css
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaStyles/DashboardChatArea.module.css b/src/components/Dashboard/DashboardChat/DashboardChatAreaStyles/DashboardChatArea.module.css
similarity index 100%
rename from src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaStyles/DashboardChatArea.module.css
rename to src/components/Dashboard/DashboardChat/DashboardChatAreaStyles/DashboardChatArea.module.css
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaStyles/grid.css b/src/components/Dashboard/DashboardChat/DashboardChatAreaStyles/grid.css
similarity index 100%
rename from src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaStyles/grid.css
rename to src/components/Dashboard/DashboardChat/DashboardChatAreaStyles/grid.css
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistory.module.css b/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistory.module.css
deleted file mode 100644
index d98e673..0000000
--- a/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistory.module.css
+++ /dev/null
@@ -1,127 +0,0 @@
-.chat_history {
- height: 100%;
- display: flex;
- flex-direction: column;
- overflow: hidden;
- font-family: var(--font-family);
-}
-
-.container {
- height: 100%;
- display: flex;
- flex-direction: column;
- padding: 20px;
- overflow: hidden;
-}
-
-.header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
- flex-shrink: 0;
-}
-
-.history_title {
- font-size: 18px;
- font-weight: 600;
- color: var(--color-text);
- margin: 0;
- font-family: var(--font-family);
-}
-
-.workflowCount {
- font-size: 14px;
- color: var(--color-gray);
- background-color: var(--color-surface);
- padding: 4px 12px;
- border-radius: 12px;
- font-family: var(--font-family);
-}
-
-.scrollableContent {
- flex: 1;
- overflow-y: auto;
- min-height: 0;
-}
-
-.workflowsList {
- display: flex;
- flex-direction: column;
- gap: 0;
-}
-
-.emptyState {
- display: flex;
- align-items: center;
- justify-content: center;
- height: 200px;
- color: var(--color-gray);
- font-size: 16px;
- text-align: center;
- font-family: var(--font-family);
-}
-
-.loadingContainer {
- display: flex;
- align-items: center;
- justify-content: center;
- height: 200px;
-}
-
-.loadingText {
- color: var(--color-gray);
- font-size: 16px;
- font-family: var(--font-family);
-}
-
-.errorContainer {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- height: 200px;
- gap: 16px;
-}
-
-.errorText {
- color: var(--color-red);
- font-size: 16px;
- text-align: center;
- font-family: var(--font-family);
-}
-
-.retryButton {
- background-color: var(--color-secondary);
- color: var(--color-bg);
- border: none;
- padding: 8px 16px;
- border-radius: 8px;
- cursor: pointer;
- font-size: 14px;
- transition: background-color 0.2s ease;
- font-family: var(--font-family);
-}
-
-.retryButton:hover {
- background-color: var(--color-secondary-hover);
-}
-
-/* Scrollbar styling */
-.scrollableContent::-webkit-scrollbar {
- width: 6px;
-}
-
-.scrollableContent::-webkit-scrollbar-track {
- background: var(--color-surface);
- border-radius: 3px;
-}
-
-.scrollableContent::-webkit-scrollbar-thumb {
- background: var(--color-gray-disabled);
- border-radius: 3px;
-}
-
-.scrollableContent::-webkit-scrollbar-thumb:hover {
- background: var(--color-gray);
-}
\ No newline at end of file
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistory.tsx b/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistory.tsx
deleted file mode 100644
index bd00f11..0000000
--- a/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistory.tsx
+++ /dev/null
@@ -1,98 +0,0 @@
-import React from "react";
-import { motion } from "framer-motion";
-import { useWorkflows } from "../../../../hooks/useWorkflows";
-import { useLanguage } from "../../../../contexts/LanguageContext";
-import DashboardChatHistoryItem from "./DashboardChatHistoryItem";
-
-import styles from './DashboardChatHistory.module.css';
-
-interface DashboardChatHistoryProps {
- onWorkflowResume?: (workflowId: string) => void;
-}
-
-const DashboardChatHistory: React.FC = ({ onWorkflowResume }) => {
- const { workflows, loading, error, refetch } = useWorkflows();
- const { t } = useLanguage();
-
- const handleWorkflowResume = (workflowId: string) => {
- if (onWorkflowResume) {
- onWorkflowResume(workflowId);
- }
- console.log('Resuming workflow:', workflowId);
- };
-
- if (loading) {
- return (
-
-
-
{t('chat_history.loading', 'Loading workflows...')}
-
-
- );
- }
-
- if (error) {
- return (
-
-
-
{t('chat_history.error_loading', 'Error loading workflows:')} {error}
-
- {t('chat_history.try_again', 'Try Again')}
-
-
-
- );
- }
-
- return (
-
-
-
-
{t('chat_history.title', 'Workflow History')}
-
- {workflows.length} {workflows.length === 1 ? t('chat_history.workflow_count', 'Workflow') : t('chat_history.workflow_count_plural', 'Workflows')}
-
-
-
-
- {workflows.length === 0 ? (
-
- {t('chat_history.empty_state', 'No workflows available')}
-
- ) : (
-
- {workflows.map((workflow) => (
-
- ))}
-
- )}
-
-
-
- );
-};
-
-export default DashboardChatHistory;
\ No newline at end of file
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistoryItem.module.css b/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistoryItem.module.css
deleted file mode 100644
index 6ee1e96..0000000
--- a/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistoryItem.module.css
+++ /dev/null
@@ -1,177 +0,0 @@
-.workflowItem {
- background: var(--color-bg);
- border-radius: 12px;
- border: 1px solid var(--color-gray-disabled);
- margin-bottom: 12px;
- transition: all 0.2s ease;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
- font-family: var(--font-family);
-}
-
-.workflowItem:hover {
- border-color: var(--color-gray);
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
-}
-
-.workflowMain {
- display: flex;
- align-items: flex-start;
- padding: 16px;
- gap: 16px;
-}
-
-.workflowContent {
- flex: 1;
- min-width: 0;
-}
-
-.workflowInfo {
- margin-bottom: 8px;
-}
-
-.workflowId {
- font-size: 16px;
- font-weight: 600;
- color: var(--color-text);
- margin: 0 0 8px 0;
- line-height: 1.2;
- font-family: var(--font-family);
-}
-
-.workflowMeta {
- display: flex;
- align-items: center;
- gap: 12px;
- margin-bottom: 8px;
-}
-
-.workflowStatus {
- font-size: 12px;
- font-weight: 600;
- padding: 4px 8px;
- border-radius: 12px;
- background-color: var(--color-secondary-disabled);
- color: var(--color-secondary);
- font-family: var(--font-family);
-}
-
-.workflowRound {
- font-size: 12px;
- color: var(--color-gray);
- background-color: var(--color-surface);
- padding: 2px 6px;
- border-radius: 8px;
- font-family: var(--font-family);
-}
-
-.workflowDates {
- display: flex;
- flex-direction: column;
- gap: 2px;
-}
-
-.workflowDate {
- font-size: 12px;
- color: var(--color-gray);
- margin: 0;
- line-height: 1.3;
- font-family: var(--font-family);
-}
-
-.workflowDescription {
- margin-top: 8px;
-}
-
-.messagePreview {
- margin-bottom: 8px;
- padding: 8px;
- background-color: var(--color-surface);
- border-radius: 6px;
- border-left: 3px solid var(--color-gray);
-}
-
-.previewText {
- font-size: 13px;
- color: var(--color-gray);
- margin: 0;
- line-height: 1.4;
- word-break: break-word;
- font-style: italic;
- font-family: var(--font-family);
-}
-
-.workflowName {
- font-size: 14px;
- color: var(--color-gray);
- margin: 0;
- line-height: 1.4;
- word-break: break-word;
- font-family: var(--font-family);
-}
-
-.actionButtons {
- display: flex;
- flex-direction: column;
- gap: 8px;
- flex-shrink: 0;
-}
-
-.actionButton {
- width: 36px;
- height: 36px;
- border: none;
- border-radius: 8px;
- display: flex;
- align-items: center;
- justify-content: center;
- cursor: pointer;
- transition: all 0.2s ease;
- font-size: 14px;
-}
-
-.actionButton:disabled {
- opacity: 0.5;
- cursor: not-allowed;
-}
-
-.resumeButton {
- background-color: var(--color-secondary);
- color: var(--color-bg);
-}
-
-.resumeButton:hover:not(:disabled) {
- background-color: var(--color-secondary-hover);
- transform: translateY(-1px);
-}
-
-.deleteButton {
- background-color: var(--color-red);
- color: var(--color-bg);
-}
-
-.deleteButton:hover:not(:disabled) {
- background-color: var(--color-red-hover);
- transform: translateY(-1px);
-}
-
-.deletingMessage {
- padding: 8px 16px;
- background-color: var(--color-primary-disabled);
- border-top: 1px solid var(--color-gray-disabled);
- color: var(--color-primary);
- font-size: 12px;
- text-align: center;
- font-family: var(--font-family);
-}
-
-@media (max-width: 768px) {
- .workflowMain {
- flex-direction: column;
- gap: 12px;
- }
-
- .actionButtons {
- flex-direction: row;
- justify-content: flex-end;
- }
-}
\ No newline at end of file
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistoryItem.tsx b/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistoryItem.tsx
deleted file mode 100644
index d13f73e..0000000
--- a/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistoryItem.tsx
+++ /dev/null
@@ -1,212 +0,0 @@
-import React, { useState, useEffect } from 'react';
-import { FaArrowRight } from 'react-icons/fa';
-import { AiOutlineDelete } from 'react-icons/ai';
-import { motion } from 'framer-motion';
-import { useWorkflowOperations, useWorkflowMessages, Workflow } from '../../../../hooks/useWorkflows';
-import { useLanguage } from '../../../../contexts/LanguageContext';
-import styles from './DashboardChatHistoryItem.module.css';
-
-interface DashboardChatHistoryItemProps {
- workflow: Workflow;
- onDelete?: () => void;
- onResume: (workflowId: string) => void;
-}
-
-function DashboardChatHistoryItem({ workflow, onDelete, onResume }: DashboardChatHistoryItemProps) {
- const { deleteWorkflow, deletingWorkflows } = useWorkflowOperations();
- const { messages } = useWorkflowMessages(workflow.id);
- const { t } = useLanguage();
-
- const isDeleting = deletingWorkflows.has(workflow.id);
-
- // Get the first user message as preview
- const firstUserMessage = messages.find(msg => msg.role === 'user');
- const messagePreview = firstUserMessage?.content || t('chat_history.no_message_content', 'No message content available');
-
- const handleDelete = async () => {
- const workflowName = workflow.title || `Workflow ${workflow.id.substring(0, 8)}...`;
- const confirmMessage = t('chat_history.confirm_delete', 'Are you sure you want to delete "{name}"?').replace('{name}', workflowName);
- if (window.confirm(confirmMessage)) {
- const success = await deleteWorkflow(workflow.id);
- if (success && onDelete) {
- onDelete();
- }
- }
- };
-
- const handleResume = () => {
- onResume(workflow.id);
- };
-
- const formatDate = (dateString?: string) => {
- if (!dateString) return t('chat_history.unknown_date', 'Unknown date');
- try {
- return new Date(dateString).toLocaleDateString('en-US', {
- year: 'numeric',
- month: 'short',
- day: 'numeric',
- hour: '2-digit',
- minute: '2-digit'
- });
- } catch (error) {
- return t('chat_history.invalid_date', 'Invalid date');
- }
- };
-
- const getStatusColor = (status: string) => {
- switch (status.toLowerCase()) {
- case 'error':
- case 'failed':
- case 'stopped':
- case 'cancelled':
- return 'var(--color-red)';
- default:
- return 'var(--color-gray)';
- }
- };
-
- const getStatusBackgroundColor = (status: string) => {
- switch (status.toLowerCase()) {
- case 'error':
- case 'failed':
- case 'stopped':
- case 'cancelled':
- return 'var(--color-red-disabled)';
- default:
- return 'var(--color-gray-disabled)';
- }
- };
-
- const shouldShowStatus = (status: string) => {
- const statusLower = status.toLowerCase();
- return statusLower === 'error' ||
- statusLower === 'failed' ||
- statusLower === 'stopped' ||
- statusLower === 'cancelled';
- };
-
- const isRunning = (status: string) => {
- const statusLower = status.toLowerCase();
- return statusLower === 'running' || statusLower === 'processing';
- };
-
- const getTranslatedStatus = (status: string): string => {
- const statusKey = `status.${status.toLowerCase()}`;
- return t(statusKey, status.toUpperCase());
- };
-
- const renderStatusIndicator = () => {
- if (isRunning(workflow.status)) {
- return (
-
- );
- }
-
- if (shouldShowStatus(workflow.status)) {
- return (
-
- {getTranslatedStatus(workflow.status)}
-
- );
- }
-
- return null;
- };
-
- const truncateMessage = (message: string, maxLength: number = 150) => {
- if (message.length <= maxLength) return message;
- return message.substring(0, maxLength) + '...';
- };
-
- return (
-
-
-
-
-
- {workflow.title || `Workflow ${workflow.id.substring(0, 8)}...`}
-
-
- {renderStatusIndicator()}
- {workflow.currentRound && (
-
- {t('chat_history.round', 'Round')} {workflow.currentRound}
-
- )}
-
-
- {workflow.startedAt && (
-
- {t('chat_history.started', 'Started:')} {formatDate(workflow.startedAt)}
-
- )}
- {workflow.lastActivity && (
-
- {t('chat_history.last_activity', 'Last Activity:')} {formatDate(workflow.lastActivity)}
-
- )}
-
-
-
-
-
-
- {truncateMessage(messagePreview)}
-
-
-
-
-
-
-
-
-
- {isDeleting && (
-
- {t('chat_history.deleting', 'Deleting workflow...')}
-
- )}
-
- );
-}
-
-export default DashboardChatHistoryItem;
\ No newline at end of file
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/FileAttachmentPopup.tsx b/src/components/Dashboard/DashboardChat/FileAttachmentPopup.tsx
similarity index 99%
rename from src/components/Dashboard/DashboardChat/DashboardChatArea/FileAttachmentPopup.tsx
rename to src/components/Dashboard/DashboardChat/FileAttachmentPopup.tsx
index 6c382d1..0b7f89c 100644
--- a/src/components/Dashboard/DashboardChat/DashboardChatArea/FileAttachmentPopup.tsx
+++ b/src/components/Dashboard/DashboardChat/FileAttachmentPopup.tsx
@@ -1,5 +1,5 @@
import React, { useState, useRef, useEffect } from 'react';
-import { useUserFiles, UserFile } from '../../../../hooks/useFiles';
+import { useUserFiles, UserFile } from '../../../hooks/useFiles';
import DateienAll from '../../../Dateien/DateienAll';
import DateienShared from '../../../Dateien/DateienShared';
import DateienCreated from '../../../Dateien/DateienCreated';
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/README.md b/src/components/Dashboard/DashboardChat/README.md
similarity index 100%
rename from src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/README.md
rename to src/components/Dashboard/DashboardChat/README.md
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/dashboardChatAreaTypes.ts b/src/components/Dashboard/DashboardChat/dashboardChatAreaTypes.ts
similarity index 100%
rename from src/components/Dashboard/DashboardChat/DashboardChatArea/dashboardChatAreaTypes.ts
rename to src/components/Dashboard/DashboardChat/dashboardChatAreaTypes.ts
diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/index.ts b/src/components/Dashboard/DashboardChat/index.ts
similarity index 100%
rename from src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaOLD/index.ts
rename to src/components/Dashboard/DashboardChat/index.ts
diff --git a/src/components/Dateien/DateienItem.tsx b/src/components/Dateien/DateienItem.tsx
index eb03690..36a9e25 100644
--- a/src/components/Dateien/DateienItem.tsx
+++ b/src/components/Dateien/DateienItem.tsx
@@ -3,8 +3,8 @@ import { MdOutlineRemoveRedEye } from "react-icons/md";
import styles from "./DateienItem.module.css";
import { useState } from "react";
import { useFileOperations } from "../../hooks/useFiles";
-import FilePreviewPopup from "../Dashboard/DashboardChat/DashboardChatArea/DashboardChatAreaFilePreview";
-import { Document } from "../Dashboard/DashboardChat/DashboardChatArea/dashboardChatAreaTypes";
+import FilePreviewPopup from "../Dashboard/DashboardChat/DashboardChatAreaFilePreview";
+import { Document } from "../Dashboard/DashboardChat/dashboardChatAreaTypes";
import { useLanguage } from "../../contexts/LanguageContext";
type DateienItemProps = {
diff --git a/src/components/FormGenerator/FormGenerator.module.css b/src/components/FormGenerator/FormGenerator.module.css
new file mode 100644
index 0000000..ccb87ac
--- /dev/null
+++ b/src/components/FormGenerator/FormGenerator.module.css
@@ -0,0 +1,578 @@
+.formGenerator {
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+ width: 100%;
+ font-family: var(--font-family);
+}
+
+.title {
+ font-size: 1.5rem;
+ font-weight: 400;
+ color: var(--color-text);
+ margin: 0;
+ margin-bottom: 10px;
+}
+
+/* Controls Section */
+.controls {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+ gap: 20px;
+ padding: 15px;
+ background: var(--color-bg);
+ border: 1px solid var(--color-primary);
+ border-radius: 25px;
+}
+
+.searchContainer {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ flex-shrink: 0;
+}
+
+.floatingLabelInput {
+ position: relative;
+ width: 250px;
+}
+
+.label {
+ position: absolute;
+ left: 16px;
+ top: 50%;
+ transform: translateY(-50%);
+ color: var(--color-text);
+ opacity: 0.6;
+ font-size: 14px;
+ pointer-events: none;
+ transition: all 0.3s ease;
+ background-color: transparent;
+ font-family: var(--font-family);
+}
+
+.focusedLabel {
+ position: absolute;
+ left: 12px;
+ top: -8px;
+ transform: translateY(0);
+ color: var(--color-secondary);
+ font-size: 12px;
+ pointer-events: none;
+ transition: all 0.3s ease;
+ background-color: var(--color-bg);
+ padding: 0 4px;
+ font-family: var(--font-family);
+ font-weight: 500;
+}
+
+.searchInput {
+ width: 100%;
+ height: 40px;
+ padding: 8px 12px;
+ border: 1px solid var(--color-primary);
+ border-radius: 25px;
+ font-size: 14px;
+ font-family: var(--font-family);
+ background: var(--color-bg);
+ color: var(--color-text);
+ transition: all 0.2s ease;
+ box-sizing: border-box;
+}
+
+.searchInput:focus {
+ border-color: var(--color-secondary);
+ box-shadow: 0 0 0 2px rgba(var(--color-secondary), 0.1);
+}
+
+.searchInput::placeholder {
+ color: transparent;
+}
+
+.filtersContainer {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 15px;
+ align-items: center;
+}
+
+.filterGroup {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.filterGroup .floatingLabelInput {
+ width: 160px;
+}
+
+.customSelectContainer {
+ position: relative;
+ display: inline-block;
+ min-width: 120px;
+}
+
+.filterInput {
+ width: 100%;
+ height: 40px;
+ padding: 6px 10px;
+ border: 1px solid var(--color-primary);
+ border-radius: 25px;
+ font-size: 14px;
+ font-family: var(--font-family);
+ background: var(--color-bg);
+ color: var(--color-text);
+ opacity: 0.6;
+ min-width: 120px;
+ transition: all 0.2s ease;
+ box-sizing: border-box;
+}
+
+.filterInput::placeholder {
+ color: transparent;
+}
+
+.filterSelect {
+ height: 40px;
+ padding: 6px 10px;
+ border: 1px solid var(--color-primary);
+ border-radius: 25px;
+ font-size: 14px;
+ font-family: var(--font-family);
+ background: var(--color-bg);
+ color: var(--color-text);
+ opacity: 0.6;
+ min-width: 120px;
+ box-sizing: border-box;
+}
+
+
+
+
+.filterSelect {
+ appearance: none;
+ background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6,9 12,15 18,9'%3e%3c/polyline%3e%3c/svg%3e");
+ background-repeat: no-repeat;
+ background-position: right 10px center;
+ background-size: 16px;
+ padding-right: 35px;
+}
+
+/* Hide dropdown arrow when filter has a value */
+.filterSelect.hasValue {
+ background-image: none;
+ color: var(--color-secondary);
+ border-color: var(--color-secondary);
+ opacity: 1;
+}
+
+.filterInput:focus {
+ outline: none;
+ border-color: var(--color-secondary);
+ opacity: 1;
+ box-shadow: 0 0 0 2px rgba(var(--color-secondary), 0.1);
+}
+
+
+
+.filterSelect:focus {
+ outline: none;
+ border-color: var(--color-secondary);
+ opacity: 1;
+}
+
+
+.clearFilterButton {
+ position: absolute;
+ right: 8px;
+ top: 50%;
+ transform: translateY(-50%);
+ background: none;
+ border: none;
+ color: var(--color-primary);
+ cursor: pointer;
+ font-size: 16px;
+ padding: 2px;
+ border-radius: 50%;
+ width: 20px;
+ height: 20px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.2s ease;
+}
+
+.clearFilterButton:hover {
+ background: none;
+ color: var(--color-secondary);
+}
+
+
+
+/* Table Container */
+.tableContainer {
+ position: relative;
+ overflow: auto;
+ border: 1px solid var(--color-primary);
+ border-radius: 25px;
+ background: var(--color-bg);
+ max-height: 600px;
+}
+
+.loading {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 40px;
+ font-size: 16px;
+ color: var(--color-text);
+}
+
+/* Table Styles */
+.table {
+ width: 100%;
+ border-collapse: collapse;
+ font-size: 14px;
+ background: var(--color-bg);
+ table-layout: fixed;
+}
+
+.th {
+ position: sticky;
+ top: 0;
+ background: var(--color-bg);
+ padding: 10px 16px;
+ text-align: left;
+ font-weight: 400;
+ color: var(--color-text);
+ white-space: nowrap;
+ user-select: none;
+ position: relative;
+ z-index: 10;
+
+}
+
+.th.actionsColumn {
+ text-align: center;
+}
+
+.th.sortable {
+ cursor: pointer;
+ transition: background-color 0.2s ease;
+}
+
+.th.sortable:hover {
+ background: var(--color-gray-disabled);
+}
+
+.headerContent {
+ display: flex;
+ align-items: center;
+ justify-content: left;
+ gap: 8px;
+}
+
+.sortIcon {
+ font-size: 12px;
+ color: var(--color-secondary);
+ opacity: 1.;
+}
+
+.resizeHandle {
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 4px;
+ height: 100%;
+ cursor: col-resize;
+ z-index: 11;
+}
+
+.resizeHandle:hover {
+ background: var(--color-secondary);
+}
+
+.td {
+ padding: 12px 16px;
+ border-top: 1px solid var(--color-primary);
+ color: var(--color-text);
+ vertical-align: middle;
+}
+
+.tr {
+ transition: background-color 0.2s ease;
+}
+
+.tr:hover {
+ background: var(--color-gray-disabled);
+}
+
+.tr.selected {
+ background: rgba(var(--color-secondary-rgb), 0.1);
+}
+
+.tr.clickable {
+ cursor: pointer;
+}
+
+/* Selection Column */
+.selectColumn {
+ text-align: center;
+ padding: 8px !important;
+}
+
+.selectColumn input[type="checkbox"] {
+ cursor: pointer;
+ transform: scale(1.2);
+}
+
+/* Actions Column */
+.actionsColumn {
+ white-space: nowrap;
+ text-align: center;
+ padding: 12px 8px !important;
+ font-weight: 400;
+}
+
+/* Actions Column border only on body cells, not header */
+tbody .actionsColumn {
+ border-top: 1px solid var(--color-primary);
+}
+
+.actionButtons {
+ display: flex;
+ gap: 4px;
+ justify-content: center;
+ align-items: center;
+ width: fit-content;
+ margin: 0 auto;
+
+
+}
+
+.actionButton {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 8px;
+ border: none;
+ border-radius: 50%;
+ font-size: 12px;
+ font-family: var(--font-family);
+ cursor: pointer;
+ transition: all 0.2s ease;
+ white-space: nowrap;
+ position: relative;
+ min-width: 32px;
+ min-height: 32px;
+ background: var(--color-secondary);
+ color: var(--color-bg);
+}
+
+.actionButton:hover {
+ background: var(--color-secondary-hover);
+ transform: scale(1.05);
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
+}
+
+.actionIcon {
+ font-size: 16px;
+ height: 16px;
+ width: 16px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+/* Custom Tooltip */
+.tooltip {
+ position: absolute;
+ bottom: 120%;
+ left: 50%;
+ transform: translateX(-50%);
+ background: var(--color-text);
+ color: var(--color-bg);
+ padding: 6px 10px;
+ border-radius: 6px;
+ font-size: 12px;
+ white-space: nowrap;
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.2s ease, visibility 0.2s ease;
+ z-index: 1000;
+ pointer-events: none;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+}
+
+/* Tooltip arrow */
+.tooltip::after {
+ content: '';
+ position: absolute;
+ top: 100%;
+ left: 50%;
+ transform: translateX(-50%);
+ border: 5px solid transparent;
+ border-top-color: var(--color-text);
+}
+
+/* Show tooltip on button hover */
+.actionButton:hover .tooltip {
+ opacity: 1;
+ visibility: visible;
+}
+
+/* Pagination */
+.pagination {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 10px;
+ padding: 15px;
+ border-top: 1px solid var(--color-gray-disabled);
+ background: var(--color-bg);
+ border-radius: 0 0 8px 8px;
+}
+
+.paginationButton {
+ padding: 8px 12px;
+ border: 1px solid var(--color-gray-disabled);
+ background: var(--color-bg);
+ color: var(--color-text);
+ border-radius: 4px;
+ cursor: pointer;
+ font-family: var(--font-family);
+ transition: all 0.2s ease;
+}
+
+.paginationButton:hover:not(:disabled) {
+ background: var(--color-gray-disabled);
+ border-color: var(--color-secondary);
+}
+
+.paginationButton:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
+.paginationInfo {
+ font-size: 14px;
+ color: var(--color-text);
+ margin: 0 15px;
+ white-space: nowrap;
+}
+
+/* Responsive Design */
+@media (max-width: 768px) {
+ .controls {
+ flex-direction: column;
+ align-items: stretch;
+ gap: 15px;
+ padding: 10px;
+ }
+
+ .filtersContainer {
+ flex-direction: column;
+ align-items: stretch;
+ gap: 10px;
+ }
+
+ .filterGroup {
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 4px;
+ }
+
+ .filterInput,
+ .filterSelect {
+ width: 100%;
+ min-width: auto;
+ }
+
+ .floatingLabelInput {
+ max-width: none;
+ }
+
+ .filterGroup .floatingLabelInput {
+ width: 100%;
+ }
+
+ .tableContainer {
+ max-height: 400px;
+ }
+
+ .th,
+ .td {
+ padding: 8px 12px;
+ font-size: 13px;
+ }
+
+ .actionButtons {
+ flex-direction: column;
+ gap: 4px;
+ }
+
+ .actionButton {
+ padding: 4px 8px;
+ font-size: 11px;
+ }
+
+ .pagination {
+ flex-wrap: wrap;
+ gap: 5px;
+ padding: 10px;
+ }
+
+ .paginationInfo {
+ order: -1;
+ width: 100%;
+ text-align: center;
+ margin: 0 0 10px 0;
+ font-size: 13px;
+ }
+}
+
+/* Dark theme support */
+@media (prefers-color-scheme: dark) {
+ .th.sortable:hover {
+ background: rgba(255, 255, 255, 0.1);
+ }
+
+ .tr:hover {
+ background: rgba(255, 255, 255, 0.05);
+ }
+
+ .tr.selected {
+ background: rgba(var(--color-secondary-rgb), 0.2);
+ }
+}
+
+/* Accessibility */
+.actionButton:focus,
+.paginationButton:focus,
+.searchInput:focus,
+.filterInput:focus,
+.filterSelect:focus {
+ outline: none;
+}
+
+/* Custom scrollbar for table container */
+.tableContainer::-webkit-scrollbar {
+ width: 8px;
+ height: 8px;
+}
+
+.tableContainer::-webkit-scrollbar-track {
+ background: var(--color-gray-disabled);
+ border-radius: 4px;
+}
+
+.tableContainer::-webkit-scrollbar-thumb {
+ background: var(--color-gray);
+ border-radius: 4px;
+}
+
+.tableContainer::-webkit-scrollbar-thumb:hover {
+ background: var(--color-secondary);
+}
\ No newline at end of file
diff --git a/src/components/FormGenerator/FormGenerator.tsx b/src/components/FormGenerator/FormGenerator.tsx
new file mode 100644
index 0000000..df77ab0
--- /dev/null
+++ b/src/components/FormGenerator/FormGenerator.tsx
@@ -0,0 +1,660 @@
+import React, { useState, useMemo, useRef, useEffect } from 'react';
+import styles from './FormGenerator.module.css';
+
+// Types for the FormGenerator
+export interface ColumnConfig {
+ key: string;
+ label: string;
+ type?: 'string' | 'number' | 'date' | 'boolean' | 'enum';
+ width?: number;
+ minWidth?: number;
+ maxWidth?: number;
+ sortable?: boolean;
+ filterable?: boolean;
+ searchable?: boolean;
+ formatter?: (value: any, row: any) => React.ReactNode;
+ filterOptions?: string[]; // For enum/select filters
+}
+
+export interface FormGeneratorProps {
+ data: T[];
+ columns?: ColumnConfig[];
+ title?: string;
+ searchable?: boolean;
+ filterable?: boolean;
+ sortable?: boolean;
+ resizable?: boolean;
+ pagination?: boolean;
+ pageSize?: number;
+ onRowClick?: (row: T, index: number) => void;
+ onRowSelect?: (selectedRows: T[]) => void;
+ selectable?: boolean;
+ loading?: boolean;
+ actions?: {
+ label: string;
+ onClick: (row: T) => void;
+ icon?: string | React.ReactNode | ((row: T) => React.ReactNode);
+ }[];
+ className?: string;
+}
+
+export function FormGenerator>({
+ data,
+ columns: providedColumns,
+ title,
+ searchable = true,
+ filterable = true,
+ sortable = true,
+ resizable = true,
+ pagination = true,
+ pageSize = 10,
+ onRowClick,
+ onRowSelect,
+ selectable = false,
+ loading = false,
+ actions = [],
+ className = ''
+}: FormGeneratorProps) {
+ // Auto-detect columns if not provided
+ const detectedColumns = useMemo((): ColumnConfig[] => {
+ if (providedColumns) return providedColumns;
+
+ if (data.length === 0) return [];
+
+ const sampleRow = data[0];
+ return Object.keys(sampleRow).map(key => {
+ const value = sampleRow[key];
+ let type: ColumnConfig['type'] = 'string';
+
+ // Auto-detect type based on value
+ if (typeof value === 'number') {
+ type = 'number';
+ } else if (typeof value === 'boolean') {
+ type = 'boolean';
+ } else if (value instanceof Date || (typeof value === 'string' && !isNaN(Date.parse(value)) && value.includes('-'))) {
+ type = 'date';
+ }
+
+ return {
+ key,
+ label: key.charAt(0).toUpperCase() + key.slice(1).replace(/([A-Z])/g, ' $1'),
+ type,
+ sortable: true,
+ filterable: true,
+ searchable: type === 'string',
+ width: 150,
+ minWidth: 100,
+ maxWidth: 400
+ };
+ });
+ }, [data, providedColumns]);
+
+ // State management
+ const [searchTerm, setSearchTerm] = useState('');
+ const [searchFocused, setSearchFocused] = useState(false);
+ const [filterFocused, setFilterFocused] = useState>({});
+ const [sortConfig, setSortConfig] = useState<{ key: string; direction: 'asc' | 'desc' } | null>(null);
+ const [filters, setFilters] = useState>({});
+ const [columnWidths, setColumnWidths] = useState>({});
+ const [selectedRows, setSelectedRows] = useState>(new Set());
+ const [currentPage, setCurrentPage] = useState(1);
+
+ // Refs for resizing
+ const tableRef = useRef(null);
+ const resizingColumn = useRef(null);
+ const startX = useRef(0);
+ const startWidth = useRef(0);
+
+ // Initialize column widths
+ useEffect(() => {
+ const initialWidths: Record = {};
+ detectedColumns.forEach(col => {
+ // Set a default width if none specified to ensure all columns have explicit widths
+ initialWidths[col.key] = col.width || 150;
+ });
+ setColumnWidths(initialWidths);
+ }, [detectedColumns]);
+
+ // Filter and search data
+ const filteredData = useMemo(() => {
+ let result = [...data];
+
+ // Apply search filter
+ if (searchTerm && searchable) {
+ const searchLower = searchTerm.toLowerCase();
+ result = result.filter(row => {
+ return detectedColumns.some(col => {
+ if (!col.searchable) return false;
+ const value = row[col.key];
+ return String(value).toLowerCase().includes(searchLower);
+ });
+ });
+ }
+
+ // Apply column filters
+ Object.entries(filters).forEach(([key, filterValue]) => {
+ if (filterValue !== undefined && filterValue !== '') {
+ result = result.filter(row => {
+ const value = row[key];
+ const column = detectedColumns.find(col => col.key === key);
+
+ if (column?.type === 'boolean') {
+ return Boolean(value) === Boolean(filterValue);
+ } else if (column?.type === 'number') {
+ return Number(value) === Number(filterValue);
+ } else if (column?.type === 'date') {
+ // Convert DD.MM.YYYY to comparable format
+ const parseDate = (dateStr: string) => {
+ if (dateStr.includes('.')) {
+ const [day, month, year] = dateStr.split('.');
+ return new Date(parseInt(year), parseInt(month) - 1, parseInt(day));
+ }
+ return new Date(dateStr);
+ };
+
+ // Convert row value to DD.MM.YYYY format for comparison
+ const rowDate = new Date(value);
+ const rowFormatted = `${rowDate.getDate().toString().padStart(2, '0')}.${(rowDate.getMonth() + 1).toString().padStart(2, '0')}.${rowDate.getFullYear()}`;
+
+ // Check if filter value is complete (DD.MM.YYYY)
+ if (filterValue.length === 10 && filterValue.match(/^\d{2}\.\d{2}\.\d{4}$/)) {
+ return rowFormatted === filterValue;
+ } else {
+ // Partial matching for incomplete dates
+ return rowFormatted.startsWith(filterValue);
+ }
+ } else {
+ return String(value).toLowerCase().includes(String(filterValue).toLowerCase());
+ }
+ });
+ }
+ });
+
+ // Apply sorting
+ if (sortConfig) {
+ result.sort((a, b) => {
+ const aVal = a[sortConfig.key];
+ const bVal = b[sortConfig.key];
+
+ if (aVal < bVal) return sortConfig.direction === 'asc' ? -1 : 1;
+ if (aVal > bVal) return sortConfig.direction === 'asc' ? 1 : -1;
+ return 0;
+ });
+ }
+
+ return result;
+ }, [data, searchTerm, filters, sortConfig, detectedColumns, searchable]);
+
+ // Pagination
+ const paginatedData = useMemo(() => {
+ if (!pagination) return filteredData;
+
+ const startIndex = (currentPage - 1) * pageSize;
+ return filteredData.slice(startIndex, startIndex + pageSize);
+ }, [filteredData, currentPage, pageSize, pagination]);
+
+ const totalPages = Math.ceil(filteredData.length / pageSize);
+
+ // Handle sorting
+ const handleSort = (key: string) => {
+ if (!sortable) return;
+
+ setSortConfig(current => {
+ if (current?.key === key) {
+ return current.direction === 'asc'
+ ? { key, direction: 'desc' }
+ : null;
+ }
+ return { key, direction: 'asc' };
+ });
+ };
+
+ // Handle filtering
+ const handleFilter = (key: string, value: any) => {
+ setFilters(prev => ({
+ ...prev,
+ [key]: value
+ }));
+ setCurrentPage(1); // Reset to first page when filtering
+ };
+
+ // Handle filter input focus
+ const handleFilterFocus = (key: string, focused: boolean) => {
+ setFilterFocused(prev => ({
+ ...prev,
+ [key]: focused
+ }));
+ };
+
+ // Handle row selection
+ const handleRowSelect = (index: number) => {
+ if (!selectable) return;
+
+ const newSelected = new Set(selectedRows);
+ if (newSelected.has(index)) {
+ newSelected.delete(index);
+ } else {
+ newSelected.add(index);
+ }
+ setSelectedRows(newSelected);
+
+ if (onRowSelect) {
+ const selectedData = Array.from(newSelected).map(i => paginatedData[i]);
+ onRowSelect(selectedData);
+ }
+ };
+
+ // Handle select all
+ const handleSelectAll = () => {
+ if (!selectable) return;
+
+ if (selectedRows.size === paginatedData.length) {
+ setSelectedRows(new Set());
+ onRowSelect?.([]);
+ } else {
+ const allIndices = new Set(paginatedData.map((_, index) => index));
+ setSelectedRows(allIndices);
+ onRowSelect?.(paginatedData);
+ }
+ };
+
+ // Handle column resizing
+ const handleMouseDown = (e: React.MouseEvent, columnKey: string) => {
+ if (!resizable) return;
+
+ e.preventDefault();
+ resizingColumn.current = columnKey;
+ startX.current = e.clientX;
+ startWidth.current = columnWidths[columnKey] || 150;
+
+ document.addEventListener('mousemove', handleMouseMove);
+ document.addEventListener('mouseup', handleMouseUp);
+ };
+
+ const handleMouseMove = (e: MouseEvent) => {
+ if (!resizingColumn.current) return;
+
+ const diff = e.clientX - startX.current;
+ let newWidth = Math.max(100, startWidth.current + diff);
+
+ // Prevent extending beyond table container
+ const tableContainer = tableRef.current?.parentElement;
+ if (tableContainer) {
+ const containerWidth = tableContainer.clientWidth;
+ const actionsColumnWidth = actions.length > 0 ? 120 : 0;
+ const selectColumnWidth = selectable ? 40 : 0;
+ const fixedWidth = actionsColumnWidth + selectColumnWidth;
+
+ // Calculate total width of all OTHER data columns (excluding the one being resized)
+ const otherDataColumnsWidth = detectedColumns.reduce((total, col) => {
+ if (col.key !== resizingColumn.current) {
+ return total + (columnWidths[col.key] || col.width || 150);
+ }
+ return total;
+ }, 0);
+
+ // Maximum allowed width for this column
+ const maxAllowedWidth = containerWidth - fixedWidth - otherDataColumnsWidth - 40; // 40px buffer
+ newWidth = Math.min(newWidth, Math.max(100, maxAllowedWidth));
+ }
+
+ setColumnWidths(prev => ({
+ ...prev,
+ [resizingColumn.current!]: newWidth
+ }));
+ };
+
+ const handleMouseUp = () => {
+ resizingColumn.current = null;
+ document.removeEventListener('mousemove', handleMouseMove);
+ document.removeEventListener('mouseup', handleMouseUp);
+ };
+
+ // Format cell value
+ const formatCellValue = (value: any, column: ColumnConfig, row: T) => {
+ if (column.formatter) {
+ return column.formatter(value, row);
+ }
+
+ if (value === null || value === undefined) {
+ return '-';
+ }
+
+ switch (column.type) {
+ case 'date':
+ return new Date(value).toLocaleDateString();
+ case 'boolean':
+ return value ? '✓' : '✗';
+ case 'number':
+ return typeof value === 'number' ? value.toLocaleString() : value;
+ default:
+ return String(value);
+ }
+ };
+
+ return (
+
+ {(searchable || filterable) && (
+
+ {searchable && (
+
+
+ setSearchTerm(e.target.value)}
+ onFocus={() => setSearchFocused(true)}
+ onBlur={() => setSearchFocused(false)}
+ className={`${styles.searchInput} ${searchFocused || searchTerm ? styles.focused : ''}`}
+ />
+ Search...
+
+
+ )}
+
+ {filterable && (
+
+ {detectedColumns.filter(col => col.filterable).map(column => (
+
+ {column.type === 'boolean' ? (
+
+ handleFilter(column.key, e.target.value === '' ? undefined : e.target.value === 'true')}
+ className={`${styles.filterSelect} ${filters[column.key] ? styles.hasValue : ''}`}
+ >
+ {column.label}
+ Yes
+ No
+
+ {filters[column.key] && (
+ handleFilter(column.key, '')}
+ className={styles.clearFilterButton}
+ title="Clear filter"
+ >
+ ✕
+
+ )}
+
+ ) : column.filterOptions ? (
+
+ handleFilter(column.key, e.target.value)}
+ className={`${styles.filterSelect} ${filters[column.key] ? styles.hasValue : ''}`}
+ >
+ {column.label}
+
+ {column.filterOptions.map(option => (
+ {option}
+ ))}
+
+ {filters[column.key] && (
+ handleFilter(column.key, '')}
+ className={styles.clearFilterButton}
+ title="Clear filter"
+ >
+ ✕
+
+ )}
+
+ ) : column.type === 'date' ? (
+
+ {
+ let value = e.target.value;
+ const currentValue = filters[column.key] || '';
+
+ // Check if user is deleting (new value is shorter)
+ const isDeleting = value.length < currentValue.length;
+
+ if (isDeleting) {
+ // When deleting, preserve the exact input without auto-formatting
+ handleFilter(column.key, value);
+ return;
+ }
+
+ // Auto-pad single digits followed by dot (e.g., "4." -> "04.")
+ value = value.replace(/^(\d)\./, '0$1.');
+ value = value.replace(/\.(\d)\./, '.0$1.');
+
+ // Allow typing and format as DD.MM.YYYY
+ const digitsOnly = value.replace(/\D/g, ''); // Remove non-digits
+
+ let formatted = '';
+ if (digitsOnly.length >= 8) {
+ // Full format: DDMMYYYY -> DD.MM.YYYY
+ const day = digitsOnly.slice(0, 2);
+ const month = digitsOnly.slice(2, 4);
+ const year = digitsOnly.slice(4, 8);
+
+ // Validate day (01-31) and month (01-12)
+ if (parseInt(day) > 31 || parseInt(month) > 12 || parseInt(day) === 0 || parseInt(month) === 0) {
+ return; // Don't update if invalid
+ }
+ formatted = `${day}.${month}.${year}`;
+ } else if (digitsOnly.length >= 4) {
+ // Partial format: DDMM -> DD.MM.
+ const day = digitsOnly.slice(0, 2);
+ const month = digitsOnly.slice(2, 4);
+ const remaining = digitsOnly.slice(4);
+
+ // Validate day (01-31) and month (01-12)
+ if (parseInt(day) > 31 || parseInt(month) > 12 || parseInt(day) === 0 || parseInt(month) === 0) {
+ return; // Don't update if invalid
+ }
+ formatted = `${day}.${month}.${remaining}`;
+ } else if (digitsOnly.length >= 2) {
+ // Start format: DD -> DD.
+ const day = digitsOnly.slice(0, 2);
+ const remaining = digitsOnly.slice(2);
+
+ // Validate day (01-31)
+ if (parseInt(day) > 31 || parseInt(day) === 0) {
+ return; // Don't update if invalid
+ }
+ formatted = `${day}.${remaining}`;
+ } else {
+ // Just digits
+ formatted = digitsOnly;
+ }
+
+ handleFilter(column.key, formatted);
+ }}
+ onFocus={() => handleFilterFocus(column.key, true)}
+ onBlur={() => handleFilterFocus(column.key, false)}
+ className={`${styles.filterInput} ${filterFocused[column.key] || filters[column.key] ? styles.focused : ''}`}
+ maxLength={10}
+ />
+
+ {column.label}
+
+
+ ) : (
+
+ handleFilter(column.key, e.target.value)}
+ onFocus={() => handleFilterFocus(column.key, true)}
+ onBlur={() => handleFilterFocus(column.key, false)}
+ className={`${styles.filterInput} ${filterFocused[column.key] || filters[column.key] ? styles.focused : ''}`}
+ />
+
+ Filter {column.label}
+
+
+ )}
+
+ ))}
+
+ )}
+
+ )}
+
+ {/* Table */}
+
+
+ {/* Pagination */}
+ {pagination && totalPages > 1 && (
+
+ setCurrentPage(1)}
+ disabled={currentPage === 1}
+ className={styles.paginationButton}
+ >
+ ««
+
+ setCurrentPage(currentPage - 1)}
+ disabled={currentPage === 1}
+ className={styles.paginationButton}
+ >
+ «
+
+
+
+ Page {currentPage} of {totalPages} ({filteredData.length} items)
+
+
+ setCurrentPage(currentPage + 1)}
+ disabled={currentPage === totalPages}
+ className={styles.paginationButton}
+ >
+ »
+
+ setCurrentPage(totalPages)}
+ disabled={currentPage === totalPages}
+ className={styles.paginationButton}
+ >
+ »»
+
+
+ )}
+
+ );
+}
+
+export default FormGenerator;
\ No newline at end of file
diff --git a/src/components/FormGenerator/index.ts b/src/components/FormGenerator/index.ts
new file mode 100644
index 0000000..e489813
--- /dev/null
+++ b/src/components/FormGenerator/index.ts
@@ -0,0 +1,2 @@
+export { default as FormGenerator } from './FormGenerator';
+export type { ColumnConfig, FormGeneratorProps } from './FormGenerator';
\ No newline at end of file
diff --git a/src/components/Popup/EditForm.module.css b/src/components/Popup/EditForm.module.css
new file mode 100644
index 0000000..05e8290
--- /dev/null
+++ b/src/components/Popup/EditForm.module.css
@@ -0,0 +1,197 @@
+/* EditForm container */
+.editForm {
+ width: 100%;
+}
+
+/* Field styling */
+.fieldGroup {
+ margin-bottom: 20px;
+}
+
+.fieldLabel {
+ display: block;
+ font-weight: 500;
+ color: var(--color-text);
+ margin-bottom: 6px;
+ font-size: 14px;
+}
+
+/* Floating label container */
+.floatingLabelInput {
+ position: relative;
+ margin-bottom: 20px;
+}
+
+.fieldInput {
+ width: 100%;
+ padding: 12px 12px 8px 12px;
+ border: 1px solid var(--color-primary);
+ border-radius: 25px;
+ font-size: 14px;
+ transition: all 0.2s ease;
+ background-color: var(--color-bg);
+ box-sizing: border-box;
+ color: var(--color-text);
+}
+
+.fieldInput:focus {
+ outline: none;
+ border-color: var(--color-secondary);
+}
+
+.fieldInput.fieldError {
+ border-color: #ef4444;
+ box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
+}
+
+/* Floating label styles */
+.label {
+ position: absolute;
+ left: 12px;
+ top: 50%;
+ transform: translateY(-50%);
+ color: var(--color-primary);
+ opacity: 0.7;
+ font-size: 14px;
+ transition: all 0.2s ease;
+ pointer-events: none;
+ z-index: 1;
+}
+
+.focusedLabel {
+ position: absolute;
+ left: 12px;
+ top: -8px;
+ transform: translateY(0);
+ color: var(--color-primary);
+ opacity: 1;
+ font-size: 12px;
+ font-weight: 500;
+ background-color: var(--color-bg);
+ padding: 0 4px;
+ transition: all 0.2s ease;
+ pointer-events: none;
+ z-index: 2;
+}
+
+.activeFocusedLabel {
+ position: absolute;
+ left: 12px;
+ top: -8px;
+ transform: translateY(0);
+ color: var(--color-secondary);
+ opacity: 1;
+ font-size: 12px;
+ font-weight: 500;
+ background-color: var(--color-bg);
+ padding: 0 4px;
+ transition: all 0.2s ease;
+ pointer-events: none;
+ z-index: 2;
+}
+
+.readonlyField {
+ padding: 12px 12px 8px 12px;
+ background-color: var(--color-bg);
+ border: 1px solid var(--color-primary);
+ border-radius: 25px;
+ color: var(--color-text);
+ font-size: 14px;
+ min-height: 20px;
+ opacity: 0.7;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+/* Checkbox styling */
+.checkboxLabel {
+ display: flex;
+ align-items: center;
+ cursor: pointer;
+ font-weight: 500;
+ color: var(--color-text);
+ font-size: 14px;
+}
+
+.checkboxInput {
+ margin-right: 8px;
+ width: 16px;
+ height: 16px;
+ cursor: pointer;
+}
+
+/* Required field indicator */
+.required {
+ color: #ef4444;
+ margin-left: 4px;
+}
+
+/* Error text */
+.errorText {
+ color: #ef4444;
+ font-size: 12px;
+ margin-top: 4px;
+ display: block;
+}
+
+/* Button group */
+.buttonGroup {
+ display: flex;
+ justify-content: flex-end;
+ gap: 12px;
+ margin-top: 24px;
+ padding-top: 16px;
+ border-top: 1px solid var(--color-primary);
+}
+
+.cancelButton {
+ padding: 8px 16px;
+ border: 1px solid var(--color-primary);
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ border-radius: 25px;
+ font-size: 14px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: all 0.2s ease;
+}
+
+.cancelButton:hover {
+ background-color: var(--color-primary-hover);
+ border-color: var(--color-primary);
+ color: #181818;
+}
+
+.saveButton {
+ padding: 8px 16px;
+ border: none;
+ background-color: var(--color-secondary);
+ color: var(--color-bg);
+ border-radius: 25px;
+ font-size: 14px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: all 0.2s ease;
+}
+
+.saveButton:hover {
+ background-color: var(--color-secondary-hover);
+}
+
+.saveButton:disabled {
+ background-color: #9ca3af;
+ cursor: not-allowed;
+}
+
+/* Responsive design */
+@media (max-width: 640px) {
+ .buttonGroup {
+ flex-direction: column-reverse;
+ }
+
+ .cancelButton,
+ .saveButton {
+ width: 100%;
+ padding: 12px;
+ }
+}
\ No newline at end of file
diff --git a/src/components/Popup/EditForm.tsx b/src/components/Popup/EditForm.tsx
new file mode 100644
index 0000000..25d8a39
--- /dev/null
+++ b/src/components/Popup/EditForm.tsx
@@ -0,0 +1,250 @@
+import React, { useState, useEffect } from 'react';
+import styles from './EditForm.module.css';
+
+// Field configuration interface (moved from EditPopup)
+export interface EditFieldConfig {
+ key: string;
+ label: string;
+ type: 'string' | 'email' | 'date' | 'enum' | 'boolean' | 'readonly';
+ editable: boolean;
+ required?: boolean;
+ options?: string[]; // For enum types
+ formatter?: (value: any) => string; // For display formatting
+ validator?: (value: any) => string | null; // Returns error message or null
+ placeholder?: string;
+}
+
+// EditForm props
+export interface EditFormProps {
+ data: T;
+ fields: EditFieldConfig[];
+ onSave: (updatedData: T) => void;
+ onCancel?: () => void;
+ saveButtonText?: string;
+ cancelButtonText?: string;
+ showButtons?: boolean;
+ className?: string;
+}
+
+// EditForm component - handles form logic
+export function EditForm>({
+ data,
+ fields,
+ onSave,
+ onCancel,
+ saveButtonText = 'Save',
+ cancelButtonText = 'Cancel',
+ showButtons = true,
+ className = ''
+}: EditFormProps) {
+ const [editedData, setEditedData] = useState(data);
+ const [errors, setErrors] = useState>({});
+ const [fieldFocused, setFieldFocused] = useState>({});
+
+ // Reset data when data changes
+ useEffect(() => {
+ setEditedData({ ...data });
+ setErrors({});
+ setFieldFocused({});
+ }, [data]);
+
+ // Handle field focus
+ const handleFieldFocus = (fieldKey: string, focused: boolean) => {
+ setFieldFocused(prev => ({
+ ...prev,
+ [fieldKey]: focused
+ }));
+ };
+
+ // Handle field value changes
+ const handleFieldChange = (fieldKey: string, value: any) => {
+ setEditedData(prev => ({
+ ...prev,
+ [fieldKey]: value
+ }));
+
+ // Clear error for this field when user starts typing
+ if (errors[fieldKey]) {
+ setErrors(prev => {
+ const newErrors = { ...prev };
+ delete newErrors[fieldKey];
+ return newErrors;
+ });
+ }
+ };
+
+ // Validate all fields
+ const validateFields = (): boolean => {
+ const newErrors: Record = {};
+
+ fields.forEach(field => {
+ const value = editedData[field.key];
+
+ // Check required fields
+ if (field.required && (!value || value.toString().trim() === '')) {
+ newErrors[field.key] = `${field.label} is required`;
+ return;
+ }
+
+ // Run custom validator
+ if (field.validator && value) {
+ const error = field.validator(value);
+ if (error) {
+ newErrors[field.key] = error;
+ }
+ }
+
+ // Basic email validation
+ if (field.type === 'email' && value && !/\S+@\S+\.\S+/.test(value)) {
+ newErrors[field.key] = 'Invalid email format';
+ }
+ });
+
+ setErrors(newErrors);
+ return Object.keys(newErrors).length === 0;
+ };
+
+ // Handle save
+ const handleSave = () => {
+ if (validateFields()) {
+ onSave(editedData);
+ }
+ };
+
+ // Handle cancel
+ const handleCancel = () => {
+ setEditedData({ ...data });
+ setErrors({});
+ onCancel?.();
+ };
+
+ // Helper function to get label class
+ const getLabelClass = (fieldKey: string, value: any) => {
+ const isFocused = fieldFocused[fieldKey];
+ const hasValue = value && value.toString().trim() !== '';
+
+ if (isFocused) {
+ return styles.activeFocusedLabel; // Secondary color when actively focused
+ } else if (hasValue) {
+ return styles.focusedLabel; // Primary color when has value but not focused
+ } else {
+ return styles.label; // Regular position when empty and not focused
+ }
+ };
+
+ // Render field based on its type
+ const renderField = (field: EditFieldConfig) => {
+ const value = editedData[field.key];
+ const hasError = errors[field.key];
+
+ if (field.type === 'readonly' || !field.editable) {
+ return (
+
+
+ {field.formatter ? field.formatter(value) : (value || 'N/A')}
+
+
+ {field.label}
+
+
+ );
+ }
+
+ if (field.type === 'enum') {
+ return (
+
+ handleFieldChange(field.key, e.target.value)}
+ onFocus={() => handleFieldFocus(field.key, true)}
+ onBlur={() => handleFieldFocus(field.key, false)}
+ className={`${styles.fieldInput} ${hasError ? styles.fieldError : ''}`}
+ >
+
+ {field.options?.map(option => (
+ {option}
+ ))}
+
+
+ {field.label}
+ {field.required && * }
+
+ {hasError && {hasError} }
+
+ );
+ }
+
+ if (field.type === 'boolean') {
+ return (
+
+
+ handleFieldChange(field.key, e.target.checked)}
+ onFocus={() => handleFieldFocus(field.key, true)}
+ onBlur={() => handleFieldFocus(field.key, false)}
+ className={styles.checkboxInput}
+ />
+ {field.label}
+ {field.required && * }
+
+ {hasError && {hasError} }
+
+ );
+ }
+
+ // Default to text input for string, email, date types
+ const inputType = field.type === 'email' ? 'email' :
+ field.type === 'date' ? 'date' : 'text';
+
+ return (
+
+ handleFieldChange(field.key, e.target.value)}
+ onFocus={() => handleFieldFocus(field.key, true)}
+ onBlur={() => handleFieldFocus(field.key, false)}
+ className={`${styles.fieldInput} ${hasError ? styles.fieldError : ''}`}
+ />
+
+ {field.label}
+ {field.required && * }
+
+ {hasError && {hasError} }
+
+ );
+ };
+
+ return (
+
+
+
+ {showButtons && (
+
+ {onCancel && (
+
+ {cancelButtonText}
+
+ )}
+
+ {saveButtonText}
+
+
+ )}
+
+ );
+}
+
+export default EditForm;
\ No newline at end of file
diff --git a/src/components/Popup/Popup.module.css b/src/components/Popup/Popup.module.css
new file mode 100644
index 0000000..bf0f79b
--- /dev/null
+++ b/src/components/Popup/Popup.module.css
@@ -0,0 +1,148 @@
+/* Overlay that covers the entire screen */
+.overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.5);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 1000;
+ padding: 20px;
+}
+
+/* Main popup container */
+.popup {
+ border: 1px solid var(--color-primary);
+ background: var(--color-bg);
+ border-radius: 25px;
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
+ max-height: 90vh;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+ animation: popupSlideIn 0.2s ease-out;
+}
+
+/* Size variants */
+.small {
+ max-width: 400px;
+ min-width: 300px;
+}
+
+.medium {
+ max-width: 600px;
+ min-width: 400px;
+}
+
+.large {
+ max-width: 900px;
+ min-width: 600px;
+}
+
+.fullscreen {
+ width: 95vw;
+ height: 95vh;
+ max-width: none;
+ max-height: none;
+}
+
+/* Popup animation */
+@keyframes popupSlideIn {
+ from {
+ opacity: 0;
+ transform: scale(0.9) translateY(-20px);
+ }
+ to {
+ opacity: 1;
+ transform: scale(1) translateY(0);
+ }
+}
+
+/* Header section */
+.header {
+ padding: 20px 24px 16px;
+ border-bottom: 1px solid var(--color-primary);
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ background: var(--color-bg);
+ flex-shrink: 0;
+}
+
+.title {
+ margin: 0;
+ font-size: 18px;
+ font-weight: 400;
+ color: var(--color-text);
+}
+
+.closeButton {
+ background: none;
+ border: none;
+ font-size: 24px;
+ color: var(--color-primary);
+ cursor: pointer;
+ padding: 4px;
+ border-radius: 4px;
+ transition: all 0.2s ease;
+ line-height: 1;
+}
+
+.closeButton:hover {
+ background-color: var(--color-bg);
+ color: var(--color-primary-hover);
+}
+
+/* Content section */
+.content {
+ padding: 24px;
+ overflow-y: auto;
+ flex: 1;
+}
+
+/* Footer section */
+.footer {
+ padding: 16px 24px;
+ border-top: 1px solid var(--color-primary);
+ display: flex;
+ justify-content: flex-end;
+ gap: 12px;
+ background: var(--color-bg);
+ flex-shrink: 0;
+}
+
+/* Responsive design */
+@media (max-width: 640px) {
+ .popup {
+ margin: 10px;
+ }
+
+ .small,
+ .medium,
+ .large {
+ min-width: 280px;
+ width: 100%;
+ }
+
+ .fullscreen {
+ width: 100vw;
+ height: 100vh;
+ border-radius: 0;
+ }
+
+ .content {
+ padding: 16px;
+ }
+
+ .header {
+ padding: 16px;
+ }
+
+ .footer {
+ padding: 12px 16px;
+ flex-direction: column-reverse;
+ }
+}
\ No newline at end of file
diff --git a/src/components/Popup/Popup.tsx b/src/components/Popup/Popup.tsx
new file mode 100644
index 0000000..217d393
--- /dev/null
+++ b/src/components/Popup/Popup.tsx
@@ -0,0 +1,90 @@
+import React from 'react';
+import styles from './Popup.module.css';
+
+// Generic popup props
+export interface PopupProps {
+ isOpen: boolean;
+ title: string;
+ onClose: () => void;
+ children: React.ReactNode;
+ footerContent?: React.ReactNode;
+ className?: string;
+ size?: 'small' | 'medium' | 'large' | 'fullscreen';
+ closable?: boolean;
+}
+
+// Generic Popup component - can be used for any content
+export function Popup({
+ isOpen,
+ title,
+ onClose,
+ children,
+ footerContent,
+ className = '',
+ size = 'medium',
+ closable = true
+}: PopupProps) {
+
+ // Handle escape key
+ React.useEffect(() => {
+ const handleEscape = (e: KeyboardEvent) => {
+ if (e.key === 'Escape' && closable) {
+ onClose();
+ }
+ };
+
+ if (isOpen) {
+ document.addEventListener('keydown', handleEscape);
+ // Prevent body scroll when popup is open
+ document.body.style.overflow = 'hidden';
+ }
+
+ return () => {
+ document.removeEventListener('keydown', handleEscape);
+ document.body.style.overflow = 'unset';
+ };
+ }, [isOpen, closable, onClose]);
+
+ if (!isOpen) return null;
+
+ // Handle backdrop click
+ const handleBackdropClick = (e: React.MouseEvent) => {
+ if (e.target === e.currentTarget && closable) {
+ onClose();
+ }
+ };
+
+ return (
+
+
+ {/* Header */}
+
+
{title}
+ {closable && (
+
+ ×
+
+ )}
+
+
+ {/* Content */}
+
+ {children}
+
+
+ {/* Footer (optional) */}
+ {footerContent && (
+
+ {footerContent}
+
+ )}
+
+
+ );
+}
+
+export default Popup;
\ No newline at end of file
diff --git a/src/components/Popup/ViewForm.module.css b/src/components/Popup/ViewForm.module.css
new file mode 100644
index 0000000..9927ac7
--- /dev/null
+++ b/src/components/Popup/ViewForm.module.css
@@ -0,0 +1,56 @@
+/* ViewForm container */
+.viewForm {
+ width: 100%;
+}
+
+/* Field styling */
+.fieldGroup {
+ margin-bottom: 16px;
+ padding-bottom: 12px;
+ border-bottom: 1px solid #f3f4f6;
+}
+
+.fieldGroup:last-child {
+ border-bottom: none;
+ margin-bottom: 0;
+}
+
+.fieldLabel {
+ display: block;
+ font-weight: 600;
+ color: #374151;
+ margin-bottom: 6px;
+ font-size: 14px;
+ text-transform: capitalize;
+}
+
+.fieldValue {
+ color: #6b7280;
+ font-size: 14px;
+ line-height: 1.5;
+ word-break: break-word;
+ padding: 4px 0;
+}
+
+/* Special styling for different value types */
+.fieldValue:empty::before {
+ content: 'N/A';
+ color: #9ca3af;
+ font-style: italic;
+}
+
+/* Responsive design */
+@media (max-width: 640px) {
+ .fieldGroup {
+ margin-bottom: 12px;
+ padding-bottom: 8px;
+ }
+
+ .fieldLabel {
+ font-size: 13px;
+ }
+
+ .fieldValue {
+ font-size: 13px;
+ }
+}
\ No newline at end of file
diff --git a/src/components/Popup/ViewForm.tsx b/src/components/Popup/ViewForm.tsx
new file mode 100644
index 0000000..9d8e537
--- /dev/null
+++ b/src/components/Popup/ViewForm.tsx
@@ -0,0 +1,40 @@
+import React from 'react';
+import styles from './ViewForm.module.css';
+import { EditFieldConfig } from './EditForm';
+
+// ViewForm props - for display-only purposes
+export interface ViewFormProps {
+ data: T;
+ fields: EditFieldConfig[];
+ className?: string;
+}
+
+// ViewForm component - displays data in read-only format
+export function ViewForm>({
+ data,
+ fields,
+ className = ''
+}: ViewFormProps) {
+
+ // Render field in view-only mode
+ const renderField = (field: EditFieldConfig) => {
+ const value = data[field.key];
+
+ return (
+
+
{field.label}
+
+ {field.formatter ? field.formatter(value) : (value || 'N/A')}
+
+
+ );
+ };
+
+ return (
+
+ {fields.map(field => renderField(field))}
+
+ );
+}
+
+export default ViewForm;
\ No newline at end of file
diff --git a/src/components/Popup/index.ts b/src/components/Popup/index.ts
new file mode 100644
index 0000000..78ab2a1
--- /dev/null
+++ b/src/components/Popup/index.ts
@@ -0,0 +1,11 @@
+// Generic Popup components
+export { Popup, default as DefaultPopup } from './Popup';
+export type { PopupProps } from './Popup';
+
+// EditForm component
+export { EditForm } from './EditForm';
+export type { EditFormProps, EditFieldConfig } from './EditForm';
+
+// ViewForm component
+export { ViewForm } from './ViewForm';
+export type { ViewFormProps } from './ViewForm';
\ No newline at end of file
diff --git a/src/components/Sidebar/Sidebar.tsx b/src/components/Sidebar/Sidebar.tsx
index 58ab253..c092d75 100644
--- a/src/components/Sidebar/Sidebar.tsx
+++ b/src/components/Sidebar/Sidebar.tsx
@@ -1,111 +1,63 @@
import React from 'react'
-import { motion, AnimatePresence } from 'framer-motion'
-import styles from './Sidebar.module.css'
+
+import styles from './SidebarStyles/Sidebar.module.css'
import SidebarItem from './SidebarItem';
import useSidebarData from '../../contexts/SidebarData';
import SidebarUser from './SidebarUser';
-import { useCurrentUser } from '../../hooks/useUsers';
-import { useSidebarMachine } from '../../hooks/machines/useSidebarMachine';
+import { useSidebarLogic } from './sidebarLogic';
+import { SidebarProps } from './sidebarTypes';
import { GoSidebarExpand, GoSidebarCollapse } from 'react-icons/go';
-interface SidebarItemType {
- id: string;
- name: string;
- link?: string;
- submenu?: SidebarItemType[];
-}
-
-interface SidebarProps {
- data: SidebarItemType[];
-}
-
const Sidebar: React.FC = ({ data }) => {
- const { user, isLoading, error } = useCurrentUser();
-
- const sidebarMachine = useSidebarMachine();
+ const sidebar = useSidebarLogic();
return (
-
-
- {!sidebarMachine.isMinimized && (
-
-
- Power
- On
-
-
- )}
-
+
{/* Minimize/Expand Toggle Button */}
- {sidebarMachine.isMinimized ? (
+ {sidebar.state.isMinimized ? (
) : (
)}
-
-
-
-
-
{data.map(item => {
return (
sidebarMachine.toggleItem(item.id)}
- isActive={sidebarMachine.isItemActive(item.link)}
- isMinimized={sidebarMachine.isMinimized}
+ isOpen={sidebar.isItemOpen(item.id)}
+ onToggle={() => sidebar.toggleItem(item.id)}
+ isActive={sidebar.isItemActive(item.link)}
+ isMinimized={sidebar.state.isMinimized}
/>
);
})}
-
+
-
+
+
)
}
diff --git a/src/components/Sidebar/SidebarItem.tsx b/src/components/Sidebar/SidebarItem.tsx
index 2d88747..47bebe2 100644
--- a/src/components/Sidebar/SidebarItem.tsx
+++ b/src/components/Sidebar/SidebarItem.tsx
@@ -3,26 +3,9 @@ import { Link } from "react-router-dom";
import { IoIosArrowDown } from "react-icons/io";
import { motion, AnimatePresence } from "framer-motion";
-import styles from './SidebarItem.module.css';
+import styles from './SidebarStyles/SidebarItem.module.css';
import SidebarSubmenu from "./SidebarSubmenu";
-
-interface SidebarItemProps {
- item: {
- id: string;
- name: string;
- link?: string;
- icon?: React.ComponentType;
- submenu?: {
- id: string;
- name: string;
- link?: string;
- }[];
- };
- isOpen: boolean;
- onToggle: () => void;
- isActive: boolean;
- isMinimized: boolean;
-}
+import { SidebarItemProps } from "./sidebarTypes";
const SidebarItem: React.FC = ({
item,
@@ -59,7 +42,7 @@ const SidebarItem: React.FC = ({
)}
- {/* Overlay for minimized state to ensure full area is clickable */}
+
{isMinimized && (
= ({ item, isOpen }) => {
if (!item.submenu) return null;
@@ -30,7 +18,6 @@ const SidebarSubmenu: React.FC = ({ item, isOpen }) => {
className={styles.submenu}
>
-
{item.submenu.map(subitem => {
const textRef = useRef(null);
diff --git a/src/components/Sidebar/SidebarUser.module.css b/src/components/Sidebar/SidebarUser.module.css
deleted file mode 100644
index 66818a3..0000000
--- a/src/components/Sidebar/SidebarUser.module.css
+++ /dev/null
@@ -1,124 +0,0 @@
-.user_section {
- display: flex;
- width: 240px;
- padding: 20px;
- flex-direction: column;
- align-items: left;
- gap: 8px;
- font-family: var(--font-family);
- box-sizing: border-box;
-}
-
-.user_info {
- display: flex;
- align-items: center;
- gap: 12px;
- width: 100%;
- transition: justify-content 0.3s ease;
-}
-
-.user_icon {
- font-size: 40px;
- color: var(--color-gray);
- flex-shrink: 0;
- transition: all 0.3s ease;
-}
-
-.text_content {
- display: flex;
- flex-direction: column;
- gap: 4px;
- transition: opacity 0.4s ease, width 0.4s ease;
- overflow: hidden;
-}
-
-.user_section h1 {
- margin: 0;
- font-size: 16pt;
- line-height: 1.;
- color: var(--color-text);
- font-family: var(--font-family);
- font-weight: 400;
- transition: opacity 0.3s ease;
- white-space: nowrap;
-}
-
-.user_section p {
- margin: 0;
- font-size: 0.9rem;
- color: var(--color-gray);
- font-family: var(--font-family);
- transition: opacity 0.35s ease;
- white-space: nowrap;
-}
-
-.logout_button {
- margin-top: 4px;
- padding: 8px 16px;
- background-color: var(--color-secondary);
- color: var(--color-bg);
- border: none;
- border-radius: 15px;
- cursor: pointer;
- font-size: 14px;
- font-family: var(--font-family);
- transition: all 0.4s ease;
- width: 100%;
-}
-
-.logout_button:hover {
- background-color: var(--color-secondary-hover);
- cursor: pointer;
-}
-
-.logout_button:active {
- background-color: var(--color-red);
-}
-
-.logout_text {
- transition: opacity 0.3s ease, width 0.3s ease;
- white-space: nowrap;
- overflow: hidden;
-}
-
-/* Minimized User Section Styles */
-.user_section.minimized {
- width: 46px; /* Match menu item width */
- padding: 20px 15px 20px 15px; /* Match menu item padding structure */
- align-items: center;
- box-sizing: border-box;
- justify-content: center;
-}
-
-.user_section.minimized .user_info {
- justify-content: flex-start; /* Match menu items positioning */
- width: 100%;
-}
-
-.user_section.minimized .user_icon {
- margin-left: -12px; /* Align with menu item icons at margin-left: -4px */
- font-size: 40px; /* Keep same size as expanded state */
-}
-
-.user_section.minimized .text_content {
- opacity: 0;
- width: 0;
-}
-
-.user_section.minimized h1 {
- opacity: 0;
-}
-
-.user_section.minimized p {
- opacity: 0;
-}
-
-.user_section.minimized .logout_button {
- opacity: 0;
- width: 0;
- height: 0;
- overflow: hidden;
- margin: 0;
- padding: 0;
-}
-
diff --git a/src/components/Sidebar/SidebarUser.tsx b/src/components/Sidebar/SidebarUser.tsx
index 6be2bcb..fc9eade 100644
--- a/src/components/Sidebar/SidebarUser.tsx
+++ b/src/components/Sidebar/SidebarUser.tsx
@@ -1,53 +1,122 @@
-import React from 'react'
+import React, { useState, useEffect, useRef } from 'react'
import { useMsal } from '@azure/msal-react'
-import { FaUserCircle } from 'react-icons/fa'
-import styles from './SidebarUser.module.css'
+import { FaSignOutAlt } from 'react-icons/fa'
+import styles from './SidebarStyles/SidebarUser.module.css'
+import { useCurrentUser } from '../../hooks/useUsers'
+import { SidebarUserProps } from './sidebarTypes';
-interface User {
- id: number;
- name: string;
- role: string;
-}
-
-interface SidebarUserProps {
- user: User;
- isLoading?: boolean;
- error?: string | null;
- isMinimized?: boolean;
-}
-
-const SidebarUser: React.FC = ({ user, isLoading, error, isMinimized = false }) => {
+const SidebarUser: React.FC = ({ isMinimized = false }) => {
const { instance } = useMsal();
+ const { user, isLoading, error, logout } = useCurrentUser();
+ const [showLogoutMenu, setShowLogoutMenu] = useState(false);
+ const [isLoggingOut, setIsLoggingOut] = useState(false);
+ const userSectionRef = useRef(null);
+
+ // Function to get initials from full name
+ const getInitials = (fullName: string): string => {
+ return fullName
+ .split(' ')
+ .map(name => name.charAt(0).toUpperCase())
+ .join('')
+ .substring(0, 2); // Limit to 2 characters
+ };
+
+ const handleUserClick = () => {
+ setShowLogoutMenu(!showLogoutMenu);
+ };
const handleLogout = async () => {
+ if (!user || isLoggingOut) return;
+
+ setIsLoggingOut(true);
try {
- // Clear MSAL cache and sign out
- await instance.logoutRedirect({
- onRedirectNavigate: () => {
- // Clear any application-specific data from localStorage
- localStorage.clear();
- return true;
- }
- });
+ // Pass MSAL instance for Microsoft authentication
+ if (user.authenticationAuthority === 'msft') {
+ await logout(instance);
+ } else {
+ await logout();
+ }
+ setShowLogoutMenu(false);
} catch (error) {
console.error('Logout failed:', error);
+ // Keep the menu open if logout fails so user can try again
+ setIsLoggingOut(false);
}
};
+ // Close popup when clicking outside
+ useEffect(() => {
+ const handleClickOutside = (event: MouseEvent) => {
+ if (userSectionRef.current && !userSectionRef.current.contains(event.target as Node)) {
+ setShowLogoutMenu(false);
+ }
+ };
+
+ if (showLogoutMenu) {
+ document.addEventListener('mousedown', handleClickOutside);
+ }
+
+ return () => {
+ document.removeEventListener('mousedown', handleClickOutside);
+ };
+ }, [showLogoutMenu]);
+
if (isLoading) {
- return Lädt...
;
+ return (
+
+ );
}
if (error) {
- return Fehler beim Laden des Benutzerprofils
;
+ return (
+
+
Fehler beim Laden des Benutzerprofils
+
+ );
+ }
+
+ if (!user) {
+ return (
+
+
Kein Benutzer gefunden
+
+ );
}
return (
-
-
-
-
{ user.name }
-
Rolle: {user.role}
+
+ {showLogoutMenu && (
+
+
+
+ {!isMinimized && (isLoggingOut ? 'Abmelden...' : 'Abmelden')}
+
+
+ )}
+
+
+
+
+ {getInitials(user.fullName)}
+
+ {!isMinimized && (
+
+
{user.fullName}
+
{user.username}
+
+ )}
diff --git a/src/components/Sidebar/index.ts b/src/components/Sidebar/index.ts
index f94a268..38709bc 100644
--- a/src/components/Sidebar/index.ts
+++ b/src/components/Sidebar/index.ts
@@ -1,3 +1,7 @@
import Sidebar from "./Sidebar";
-export default Sidebar;
\ No newline at end of file
+export default Sidebar;
+export { default as SidebarItem } from './SidebarItem';
+export { default as SidebarUser } from './SidebarUser';
+export * from './sidebarTypes';
+export { useSidebarLogic } from './sidebarLogic';
\ No newline at end of file
diff --git a/src/components/Sidebar/sidebarLogic.ts b/src/components/Sidebar/sidebarLogic.ts
new file mode 100644
index 0000000..fc95d94
--- /dev/null
+++ b/src/components/Sidebar/sidebarLogic.ts
@@ -0,0 +1,68 @@
+import { useState, useCallback } from 'react';
+import { useLocation } from 'react-router-dom';
+import { SidebarState, SidebarContextType } from './sidebarTypes';
+
+// Custom hook for sidebar logic
+export const useSidebarLogic = (): SidebarContextType => {
+ const location = useLocation();
+
+ // Simple React state instead of state machine
+ const [state, setState] = useState
({
+ openItemId: null,
+ isMinimized: false,
+ });
+
+ // Toggle a specific menu item
+ const toggleItem = useCallback((itemId: string) => {
+ setState(prevState => ({
+ ...prevState,
+ openItemId: prevState.openItemId === itemId ? null : itemId,
+ }));
+ }, []);
+
+ // Close all submenus
+ const closeAll = useCallback(() => {
+ setState(prevState => ({
+ ...prevState,
+ openItemId: null,
+ }));
+ }, []);
+
+ // Check if a specific item is open
+ const isItemOpen = useCallback((itemId: string) => {
+ return state.openItemId === itemId;
+ }, [state.openItemId]);
+
+ // Check if an item is the active route
+ const isItemActive = useCallback((itemPath?: string) => {
+ if (!itemPath) return false;
+ return location.pathname === itemPath;
+ }, [location.pathname]);
+
+ // Minimize sidebar
+ const minimizeSidebar = useCallback(() => {
+ setState(prevState => ({
+ ...prevState,
+ isMinimized: true,
+ openItemId: null, // Close any open submenu when minimizing
+ }));
+ }, []);
+
+ // Expand sidebar
+ const expandSidebar = useCallback(() => {
+ setState(prevState => ({
+ ...prevState,
+ isMinimized: false,
+ }));
+ }, []);
+
+ return {
+ state,
+ toggleItem,
+ closeAll,
+ isItemOpen,
+ isItemActive,
+ minimizeSidebar,
+ expandSidebar,
+ };
+};
\ No newline at end of file
diff --git a/src/components/Sidebar/sidebarTypes.ts b/src/components/Sidebar/sidebarTypes.ts
new file mode 100644
index 0000000..ff92513
--- /dev/null
+++ b/src/components/Sidebar/sidebarTypes.ts
@@ -0,0 +1,56 @@
+import React from 'react';
+
+// Base sidebar item interface
+export interface SidebarItemData {
+ id: string;
+ name: string;
+ link?: string;
+ icon?: React.ComponentType>;
+ submenu?: SidebarSubmenuItemData[];
+}
+
+// Submenu item interface
+export interface SidebarSubmenuItemData {
+ id: string;
+ name: string;
+ link?: string;
+}
+
+// Sidebar state interface
+export interface SidebarState {
+ openItemId: string | null;
+ isMinimized: boolean;
+}
+
+// Sidebar context interface
+export interface SidebarContextType {
+ state: SidebarState;
+ toggleItem: (itemId: string) => void;
+ closeAll: () => void;
+ isItemOpen: (itemId: string) => boolean;
+ isItemActive: (itemPath?: string) => boolean;
+ minimizeSidebar: () => void;
+ expandSidebar: () => void;
+}
+
+// Component props interfaces
+export interface SidebarProps {
+ data: SidebarItemData[];
+}
+
+export interface SidebarItemProps {
+ item: SidebarItemData;
+ isOpen: boolean;
+ onToggle: () => void;
+ isActive: boolean;
+ isMinimized: boolean;
+}
+
+export interface SidebarSubmenuProps {
+ item: SidebarItemData;
+ isOpen: boolean;
+}
+
+export interface SidebarUserProps {
+ isMinimized?: boolean;
+}
\ No newline at end of file
diff --git a/src/contexts/LanguageContext.tsx b/src/contexts/LanguageContext.tsx
index ec61b84..c63dbd4 100644
--- a/src/contexts/LanguageContext.tsx
+++ b/src/contexts/LanguageContext.tsx
@@ -1,5 +1,5 @@
import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
-import { Language, translations } from './languageContextData';
+import { Language, TranslationKeys, loadLanguage } from '../locales';
// Re-export Language type for convenience
export type { Language };
@@ -8,6 +8,8 @@ interface LanguageContextType {
currentLanguage: Language;
setLanguage: (language: Language) => void;
t: (key: string, fallback?: string) => string;
+ isLoading: boolean;
+ reloadLanguage: () => Promise;
}
const LanguageContext = createContext(undefined);
@@ -16,39 +18,68 @@ interface LanguageProviderProps {
children: ReactNode;
}
-
-
export const LanguageProvider: React.FC = ({ children }) => {
const [currentLanguage, setCurrentLanguage] = useState('de');
+ const [translations, setTranslations] = useState({});
+ const [isLoading, setIsLoading] = useState(true);
+
+ // Function to load and set a language
+ const loadAndSetLanguage = async (language: Language) => {
+ setIsLoading(true);
+ try {
+ const newTranslations = await loadLanguage(language);
+ setTranslations(newTranslations);
+ setCurrentLanguage(language);
+ } catch (error) {
+ console.error('Failed to load language:', error);
+ // Keep current language and translations if loading fails
+ } finally {
+ setIsLoading(false);
+ }
+ };
// Load saved language preference on mount
useEffect(() => {
- const savedLanguage = localStorage.getItem('language') as Language;
- if (savedLanguage && ['de', 'en', 'fr'].includes(savedLanguage)) {
- setCurrentLanguage(savedLanguage);
- } else {
- // Detect browser language
- const browserLang = navigator.language.split('-')[0] as Language;
- if (['de', 'en', 'fr'].includes(browserLang)) {
- setCurrentLanguage(browserLang);
+ const initializeLanguage = async () => {
+ const savedLanguage = localStorage.getItem('language') as Language;
+ let initialLanguage: Language = 'de';
+
+ if (savedLanguage && ['de', 'en', 'fr'].includes(savedLanguage)) {
+ initialLanguage = savedLanguage;
+ } else {
+ // Detect browser language
+ const browserLang = navigator.language.split('-')[0] as Language;
+ if (['de', 'en', 'fr'].includes(browserLang)) {
+ initialLanguage = browserLang;
+ }
}
- }
+
+ await loadAndSetLanguage(initialLanguage);
+ };
+
+ initializeLanguage();
}, []);
- const setLanguage = (language: Language) => {
- setCurrentLanguage(language);
+ const setLanguage = async (language: Language) => {
localStorage.setItem('language', language);
+ await loadAndSetLanguage(language);
+ };
+
+ const reloadLanguage = async () => {
+ await loadAndSetLanguage(currentLanguage);
};
const t = (key: string, fallback?: string): string => {
- const translation = translations[currentLanguage]?.[key] || translations['de'][key] || fallback || key;
+ const translation = translations[key] || fallback || key;
return translation;
};
const contextValue: LanguageContextType = {
currentLanguage,
setLanguage,
- t
+ t,
+ isLoading,
+ reloadLanguage
};
return (
diff --git a/src/contexts/SidebarData.tsx b/src/contexts/SidebarData.tsx
index 3b01a7d..025cda7 100644
--- a/src/contexts/SidebarData.tsx
+++ b/src/contexts/SidebarData.tsx
@@ -1,11 +1,12 @@
import { MdOutlineWorkOutline } from 'react-icons/md';
import { BsChatDots } from "react-icons/bs";
-import { LuTicket } from "react-icons/lu";
+import { LuWorkflow, LuTicket } from "react-icons/lu";
import { RiTeamLine } from "react-icons/ri";
import { BiInfoSquare } from "react-icons/bi";
import { GoGear } from "react-icons/go";
-import { FaRegFileAlt } from "react-icons/fa";
+import { FaPlug, FaRegFileAlt } from "react-icons/fa";
import { TbLogs } from "react-icons/tb";
+import { FaShare } from "react-icons/fa";
import { useMemo } from 'react';
import { useLanguage } from './LanguageContext';
@@ -16,40 +17,48 @@ const useSidebarData = () => {
return useMemo(() => [
{
id: '1',
- name: t('nav.team'),
- link: '/team-bereich',
- icon: MdOutlineWorkOutline,
- },
- {
- id: '2',
name: t('nav.dashboard'),
link: '/dashboard',
icon: LuTicket,
},
+
{
id: '3',
name: t('nav.files'),
link: '/dateien',
icon: FaRegFileAlt,
},
- /*{
- id: '6',
- name: 'Logs',
- link: '',
- icon: TbLogs ,
- },*/
+ {
+ id: '4',
+ name: t('nav.workflows'),
+ link: '/workflows',
+ icon: LuWorkflow ,
+ },
+ {
+ id: '5',
+ name: t('nav.connections'),
+ link: '/connections',
+ icon: FaPlug ,
+ },
+ {
+ id: '2',
+ name: t('nav.team'),
+ link: '/team-bereich',
+ icon: MdOutlineWorkOutline,
+ },
{
id: '7',
name: t('nav.settings'),
link: '/einstellungen',
icon: GoGear,
},
- /*{
+ {
id: '8',
- name: 'Help',
- link: '',
- icon: BiInfoSquare,
- },*/
+ name: t('nav.testSharepoint'),
+ link: '/testSharepoint',
+ icon: FaShare,
+ },
+
], [t]);
}
diff --git a/src/contexts/languageContextData.ts b/src/contexts/languageContextData.ts
deleted file mode 100644
index c38e730..0000000
--- a/src/contexts/languageContextData.ts
+++ /dev/null
@@ -1,683 +0,0 @@
-// Language type definition
-export type Language = 'de' | 'en' | 'fr';
-
-// Translation keys and their values for each language
-export type TranslationKeys = {
- [key: string]: string;
-};
-
-export type Translations = {
- [K in Language]: TranslationKeys;
-};
-
-export const translations: Translations = {
- de: {
- // Navigation
- 'nav.dashboard': 'Aktivitätszentrum',
- 'nav.files': 'Dateien',
- 'nav.team': 'Team-Bereich',
- 'nav.settings': 'Einstellungen',
-
- // Settings page
- 'settings.title': 'Einstellungen',
- 'settings.appearance': 'Darstellung',
- 'settings.language': 'Sprache',
- 'settings.about': 'Über',
- 'settings.version': 'Version',
- 'settings.theme': 'Theme',
- 'settings.theme.description': 'Wechseln Sie zwischen hellem und dunklem Modus',
- 'settings.language.description': 'Wählen Sie Ihre bevorzugte Sprache',
- 'settings.theme.light': 'Hell',
- 'settings.theme.dark': 'Dunkel',
- 'settings.theme.toggle.light': 'Zu hellem Modus wechseln',
- 'settings.theme.toggle.dark': 'Zu dunklem Modus wechseln',
-
- // Languages
- 'language.german': 'Deutsch',
- 'language.english': 'English',
- 'language.french': 'Français',
-
- // Common
- 'common.loading': 'Laden...',
- 'common.error': 'Fehler',
- 'common.success': 'Erfolgreich',
- 'common.cancel': 'Abbrechen',
- 'common.save': 'Speichern',
- 'common.delete': 'Löschen',
- 'common.edit': 'Bearbeiten',
- 'common.close': 'Schließen',
-
- // Auth
- 'auth.login': 'Anmelden',
- 'auth.register': 'Registrieren',
- 'auth.logout': 'Abmelden',
- 'auth.email': 'E-Mail',
- 'auth.password': 'Passwort',
-
- // Dashboard
- 'dashboard.prompt.template': 'Prompt Vorlage',
- 'dashboard.prompt.settings': 'Einstellungen',
- 'dashboard.chat.area': 'Chatbereich',
- 'dashboard.chat.history': 'Workflow-Verlauf',
- 'dashboard.log.title': 'Log',
- 'dashboard.log.workflow': 'Workflow',
- 'dashboard.log.no_workflow': 'Kein Workflow ausgewählt',
- 'dashboard.log.loading': 'Logs werden geladen...',
- 'dashboard.log.error': 'Fehler beim Laden der Logs',
- 'dashboard.log.no_logs': 'Keine Logs für diesen Workflow verfügbar',
- 'dashboard.log.waiting': 'Workflow läuft... Warte auf Logs...',
- 'dashboard.log.fetch_failed': 'Logs konnten nicht geladen werden',
- 'dashboard.log.level.info': 'INFO',
-
- // Prompt Set
- 'promptset.loading': 'Prompts werden geladen...',
- 'promptset.error.loading': 'Fehler beim Laden der Prompts',
- 'promptset.retry': 'Erneut versuchen',
- 'promptset.new_prompt': 'Neuer Prompt',
- 'promptset.prompt_count': 'Prompt',
- 'promptset.prompt_count_plural': 'Prompts',
- 'promptset.no_prompts': 'Keine Prompts verfügbar',
- 'promptset.created': 'Erstellt',
- 'promptset.run_tooltip': 'Prompt ausführen',
- 'promptset.share_tooltip': 'Prompt teilen',
- 'promptset.delete_tooltip': 'Prompt löschen',
- 'promptset.confirm_delete': 'Klicken Sie erneut zum Bestätigen',
- 'promptset.deleting': 'Löschen...',
- 'promptset.confirm_click': 'Zum Bestätigen klicken',
- 'promptset.delete_error': 'Fehler beim Löschen',
- 'promptset.deleting_message': 'Prompt wird gelöscht...',
-
- // Prompt Modal
- 'modal.create_prompt': 'Neuen Prompt erstellen',
- 'modal.name_required': 'Name ist erforderlich',
- 'modal.content_required': 'Inhalt ist erforderlich',
- 'modal.create_error': 'Fehler beim Erstellen des Prompts',
- 'modal.name_label': 'Name',
- 'modal.content_label': 'Inhalt',
- 'modal.name_placeholder': 'Geben Sie einen Namen für den Prompt ein',
- 'modal.content_placeholder': 'Geben Sie den Inhalt des Prompts ein',
- 'modal.cancel': 'Abbrechen',
- 'modal.creating': 'Erstellen...',
- 'modal.create': 'Prompt erstellen',
-
- // Share Modal
- 'share_modal.title': 'Prompt teilen',
- 'share_modal.select_users': 'Benutzer auswählen',
- 'share_modal.select_all': 'Alle auswählen',
- 'share_modal.deselect_all': 'Alle abwählen',
- 'share_modal.loading_users': 'Benutzer werden geladen...',
- 'share_modal.error_loading_users': 'Fehler beim Laden der Benutzer',
- 'share_modal.no_users_available': 'Keine Benutzer verfügbar',
- 'share_modal.no_users_selected': 'Bitte wählen Sie mindestens einen Benutzer aus',
- 'share_modal.one_user_selected': '1 Benutzer ausgewählt',
- 'share_modal.multiple_users_selected': '{count} Benutzer ausgewählt',
- 'share_modal.custom_title': 'Benutzerdefinierter Titel (optional)',
- 'share_modal.title_placeholder': 'Geben Sie einen benutzerdefinierten Titel ein',
- 'share_modal.message': 'Nachricht (optional)',
- 'share_modal.message_placeholder': 'Fügen Sie eine Nachricht für die Empfänger hinzu',
- 'share_modal.share': 'Teilen',
- 'share_modal.sharing': 'Wird geteilt...',
- 'share_modal.share_error': 'Fehler beim Teilen des Prompts',
-
- // Prompt Settings
- 'prompt_settings.title': 'Prompt Einstellungen',
- 'prompt_settings.content_placeholder': 'Einstellungen werden in zukünftigen Updates hinzugefügt.',
-
- // Chat Area
- 'chat.continue_conversation': 'Gespräch fortsetzen...',
- 'chat.enter_message': 'Nachricht eingeben...',
- 'chat.remove_file': 'Datei entfernen',
- 'chat.attach_file': 'Datei anhängen',
- 'chat.you': 'You',
- 'chat.click_to_open': 'Klicken Sie, um zu öffnen',
- 'chat.preview_document': 'Dokument vorschauen',
- 'chat.download_document': 'Dokument herunterladen',
- 'chat.workflow_failed': 'Workflow fehlgeschlagen.',
- 'chat.retry_workflow': 'Nochmal versuchen',
- 'chat.sending_followup': 'Folgenachricht wird gesendet...',
- 'chat.sending_message': 'Nachricht wird gesendet...',
- 'chat.error_prefix': 'Fehler:',
- 'chat.error_loading_messages': 'Fehler beim Laden der Nachrichten:',
- 'chat.loading_workflow_messages': 'Workflow-Nachrichten werden geladen...',
- 'chat.start_conversation': 'Beginne ein Gespräch, indem du eine Nachricht eingibst, eine Vorlage auswählst oder einen vorherigen Workflow fortsetzt …',
-
- // File Preview
- 'file_preview.loading': 'Vorschau wird geladen...',
- 'file_preview.error': 'Fehler',
- 'file_preview.no_preview': 'Keine Vorschau verfügbar',
- 'file_preview.close_preview': 'Vorschau schließen',
- 'file_preview.python': 'Python',
-
- // Chat History
- 'chat_history.loading': 'Workflows werden geladen...',
- 'chat_history.error_loading': 'Fehler beim Laden der Workflows:',
- 'chat_history.try_again': 'Nochmal versuchen',
- 'chat_history.title': 'Workflow-Verlauf',
- 'chat_history.workflow_count': 'Workflow',
- 'chat_history.workflow_count_plural': 'Workflows',
- 'chat_history.empty_state': 'Keine Workflows verfügbar',
- 'chat_history.confirm_delete': 'Sind Sie sicher, dass Sie Workflow "{id}..." löschen möchten?',
- 'chat_history.no_message_content': 'Kein Nachrichteninhalt verfügbar',
- 'chat_history.unknown_date': 'Unbekanntes Datum',
- 'chat_history.invalid_date': 'Ungültiges Datum',
- 'chat_history.started': 'Gestartet:',
- 'chat_history.last_activity': 'Letzte Aktivität:',
- 'chat_history.round': 'Runde',
- 'chat_history.resume_tooltip': 'Workflow fortsetzen',
- 'chat_history.delete_tooltip': 'Workflow löschen',
- 'chat_history.deleting': 'Workflow wird gelöscht...',
-
- // Workflow Status
- 'status.error': 'FEHLER',
- 'status.failed': 'FEHLGESCHLAGEN',
- 'status.stopped': 'GESTOPPT',
- 'status.cancelled': 'ABGEBROCHEN',
- 'status.running': 'LÄUFT',
- 'status.processing': 'VERARBEITUNG',
- 'status.completed': 'ABGESCHLOSSEN',
- 'status.pending': 'WARTEND',
-
- // Files
- 'files.unknown_size': 'Unbekannte Größe',
- 'files.unknown_date': 'Unbekanntes Datum',
- 'files.source.uploaded': 'Hochgeladen',
- 'files.source.ai_created': 'KI-erstellt',
- 'files.source.shared': 'Geteilt',
- 'files.source.unknown': 'Unbekannt',
- 'files.preview_tooltip': 'Datei vorschauen',
- 'files.download_tooltip': 'Datei herunterladen',
- 'files.delete_tooltip': 'Datei löschen',
- 'files.delete_confirm_tooltip': 'Klicken Sie erneut zum Bestätigen der Löschung',
- 'files.downloading': 'Laden...',
- 'files.deleting': 'Löschen...',
- 'files.delete_confirm': 'Zum Bestätigen klicken...',
- 'files.no_files': 'Keine Dateien gefunden.',
- 'files.no_shared_files': 'Keine mit Ihnen geteilten Dateien gefunden.',
- 'files.no_ai_files': 'Keine von der KI erstellten Dateien gefunden.',
- 'files.no_uploaded_files': 'Keine hochgeladenen Dateien gefunden.',
- 'files.header.name': 'Name',
- 'files.header.type': 'Typ',
- 'files.header.size': 'Größe',
- 'files.header.date': 'Datum',
- 'files.selector.title': 'Dateien auswählen',
- 'files.selector.tab.all': 'Alle Dateien',
- 'files.selector.tab.uploads': 'Hochgeladen',
- 'files.selector.tab.created': 'KI-erstellt',
- 'files.selector.tab.shared': 'Geteilt',
- 'files.selector.select_all': 'Alle auswählen',
- 'files.selector.deselect_all': 'Alle abwählen',
- 'files.selector.file_selected': 'Datei',
- 'files.selector.files_selected': 'Dateien',
- 'files.selector.selected_suffix': 'ausgewählt',
- 'files.selector.upload_new': 'Neue Datei hochladen',
- 'files.selector.loading': 'Dateien werden geladen...',
- 'files.selector.error_loading': 'Fehler beim Laden der Dateien:',
- 'files.upload.title': 'Datei hochladen',
- 'files.upload.drop_here': 'Datei hier ablegen...',
- 'files.upload.uploading': 'Lädt hoch...',
- 'files.upload.drag_files': 'Dateien hierher ziehen',
- 'files.upload.or': 'oder',
- 'files.upload.browse': 'Durchsuchen',
- 'files.upload.selected_file': 'Ausgewählte Datei:',
- 'files.upload.upload_button': 'Hochladen',
- 'files.upload.uploading_button': 'Wird hochgeladen...',
- 'files.upload.success': 'Datei erfolgreich hochgeladen!',
- 'files.upload.error': 'Beim Hochladen ist ein Fehler aufgetreten.',
- 'files.upload.unexpected_error': 'Beim Hochladen ist ein unerwarteter Fehler aufgetreten.',
-
- // Files Page
- 'files.page.tab.all': 'Alle Dateien',
- 'files.page.tab.uploads': 'Meine Uploads',
- 'files.page.tab.created': 'Erstellte Dateien',
- 'files.page.tab.shared': 'Geteilte Dateien',
- 'files.page.add_file': 'Datei hinzufügen',
- 'files.page.loading': 'Dateien werden geladen...',
- 'files.page.error': 'Fehler:',
- },
- en: {
- // Navigation
- 'nav.dashboard': 'Activity Center',
- 'nav.files': 'Files',
- 'nav.team': 'Team Area',
- 'nav.settings': 'Settings',
-
- // Settings page
- 'settings.title': 'Settings',
- 'settings.appearance': 'Appearance',
- 'settings.language': 'Language',
- 'settings.about': 'About',
- 'settings.version': 'Version',
- 'settings.theme': 'Theme',
- 'settings.theme.description': 'Switch between light and dark mode',
- 'settings.language.description': 'Choose your preferred language',
- 'settings.theme.light': 'Light',
- 'settings.theme.dark': 'Dark',
- 'settings.theme.toggle.light': 'Switch to light mode',
- 'settings.theme.toggle.dark': 'Switch to dark mode',
-
- // Languages
- 'language.german': 'Deutsch',
- 'language.english': 'English',
- 'language.french': 'Français',
-
- // Common
- 'common.loading': 'Loading...',
- 'common.error': 'Error',
- 'common.success': 'Success',
- 'common.cancel': 'Cancel',
- 'common.save': 'Save',
- 'common.delete': 'Delete',
- 'common.edit': 'Edit',
- 'common.close': 'Close',
-
- // Auth
- 'auth.login': 'Login',
- 'auth.register': 'Register',
- 'auth.logout': 'Logout',
- 'auth.email': 'Email',
- 'auth.password': 'Password',
-
- // Dashboard
- 'dashboard.prompt.template': 'Prompt Template',
- 'dashboard.prompt.settings': 'Settings',
- 'dashboard.chat.area': 'Chat Area',
- 'dashboard.chat.history': 'Workflow History',
- 'dashboard.log.title': 'Log',
- 'dashboard.log.workflow': 'Workflow',
- 'dashboard.log.no_workflow': 'No workflow selected',
- 'dashboard.log.loading': 'Loading logs...',
- 'dashboard.log.error': 'Error loading logs',
- 'dashboard.log.no_logs': 'No logs available for this workflow',
- 'dashboard.log.waiting': 'Workflow running... Waiting for logs...',
- 'dashboard.log.fetch_failed': 'Failed to fetch logs',
- 'dashboard.log.level.info': 'INFO',
-
- // Prompt Set
- 'promptset.loading': 'Loading prompts...',
- 'promptset.error.loading': 'Error loading prompts',
- 'promptset.retry': 'Try again',
- 'promptset.new_prompt': 'New Prompt',
- 'promptset.prompt_count': 'Prompt',
- 'promptset.prompt_count_plural': 'Prompts',
- 'promptset.no_prompts': 'No prompts available',
- 'promptset.created': 'Created',
- 'promptset.run_tooltip': 'Run prompt',
- 'promptset.share_tooltip': 'Share prompt',
- 'promptset.delete_tooltip': 'Delete prompt',
- 'promptset.confirm_delete': 'Click again to confirm',
- 'promptset.deleting': 'Deleting...',
- 'promptset.confirm_click': 'Click to confirm',
- 'promptset.delete_error': 'Error deleting',
- 'promptset.deleting_message': 'Deleting prompt...',
-
- // Prompt Modal
- 'modal.create_prompt': 'Create New Prompt',
- 'modal.name_required': 'Name is required',
- 'modal.content_required': 'Content is required',
- 'modal.create_error': 'Error creating prompt',
- 'modal.name_label': 'Name',
- 'modal.content_label': 'Content',
- 'modal.name_placeholder': 'Enter a name for the prompt',
- 'modal.content_placeholder': 'Enter the prompt content',
- 'modal.cancel': 'Cancel',
- 'modal.creating': 'Creating...',
- 'modal.create': 'Create Prompt',
-
- // Share Modal
- 'share_modal.title': 'Share Prompt',
- 'share_modal.select_users': 'Select Users',
- 'share_modal.select_all': 'Select All',
- 'share_modal.deselect_all': 'Deselect All',
- 'share_modal.loading_users': 'Loading users...',
- 'share_modal.error_loading_users': 'Error loading users',
- 'share_modal.no_users_available': 'No users available',
- 'share_modal.no_users_selected': 'Please select at least one user',
- 'share_modal.one_user_selected': '1 user selected',
- 'share_modal.multiple_users_selected': '{count} users selected',
- 'share_modal.custom_title': 'Custom Title (optional)',
- 'share_modal.title_placeholder': 'Enter a custom title',
- 'share_modal.message': 'Message (optional)',
- 'share_modal.message_placeholder': 'Add a message for recipients',
- 'share_modal.share': 'Share',
- 'share_modal.sharing': 'Sharing...',
- 'share_modal.share_error': 'Error sharing prompt',
-
- // Prompt Settings
- 'prompt_settings.title': 'Prompt Settings',
- 'prompt_settings.content_placeholder': 'Settings content will be added here in future updates.',
-
- // Chat Area
- 'chat.continue_conversation': 'Continue conversation...',
- 'chat.enter_message': 'Enter message...',
- 'chat.remove_file': 'Remove file',
- 'chat.attach_file': 'Attach file',
- 'chat.you': 'You',
- 'chat.click_to_open': 'Click to open',
- 'chat.preview_document': 'Preview document',
- 'chat.download_document': 'Download document',
- 'chat.workflow_failed': 'Workflow failed.',
- 'chat.retry_workflow': 'Try again',
- 'chat.sending_followup': 'Sending follow-up message...',
- 'chat.sending_message': 'Sending message...',
- 'chat.error_prefix': 'Error:',
- 'chat.error_loading_messages': 'Error loading messages:',
- 'chat.loading_workflow_messages': 'Loading workflow messages...',
- 'chat.start_conversation': 'Start a conversation by entering a message, selecting a template, or continuing a previous workflow...',
-
- // File Preview
- 'file_preview.loading': 'Loading preview...',
- 'file_preview.error': 'Error',
- 'file_preview.no_preview': 'No preview available',
- 'file_preview.close_preview': 'Close preview',
- 'file_preview.python': 'Python',
-
- // Chat History
- 'chat_history.loading': 'Loading workflows...',
- 'chat_history.error_loading': 'Error loading workflows:',
- 'chat_history.try_again': 'Try Again',
- 'chat_history.title': 'Workflow History',
- 'chat_history.workflow_count': 'Workflow',
- 'chat_history.workflow_count_plural': 'Workflows',
- 'chat_history.empty_state': 'No workflows available',
- 'chat_history.confirm_delete': 'Are you sure you want to delete workflow "{id}..."?',
- 'chat_history.no_message_content': 'No message content available',
- 'chat_history.unknown_date': 'Unknown date',
- 'chat_history.invalid_date': 'Invalid date',
- 'chat_history.started': 'Started:',
- 'chat_history.last_activity': 'Last Activity:',
- 'chat_history.round': 'Round',
- 'chat_history.resume_tooltip': 'Resume workflow',
- 'chat_history.delete_tooltip': 'Delete workflow',
- 'chat_history.deleting': 'Deleting workflow...',
-
- // Workflow Status
- 'status.error': 'ERROR',
- 'status.failed': 'FAILED',
- 'status.stopped': 'STOPPED',
- 'status.cancelled': 'CANCELLED',
- 'status.running': 'RUNNING',
- 'status.processing': 'PROCESSING',
- 'status.completed': 'COMPLETED',
- 'status.pending': 'PENDING',
-
- // Files
- 'files.unknown_size': 'Unknown Size',
- 'files.unknown_date': 'Unknown Date',
- 'files.source.uploaded': 'Uploaded',
- 'files.source.ai_created': 'AI-created',
- 'files.source.shared': 'Shared',
- 'files.source.unknown': 'Unknown',
- 'files.preview_tooltip': 'Preview file',
- 'files.download_tooltip': 'Download file',
- 'files.delete_tooltip': 'Delete file',
- 'files.delete_confirm_tooltip': 'Click again to confirm deletion',
- 'files.downloading': 'Downloading...',
- 'files.deleting': 'Deleting...',
- 'files.delete_confirm': 'Click to confirm...',
- 'files.no_files': 'No files found.',
- 'files.no_shared_files': 'No shared files found.',
- 'files.no_ai_files': 'No AI-created files found.',
- 'files.no_uploaded_files': 'No uploaded files found.',
- 'files.header.name': 'Name',
- 'files.header.type': 'Type',
- 'files.header.size': 'Size',
- 'files.header.date': 'Date',
- 'files.selector.title': 'Select files',
- 'files.selector.tab.all': 'All files',
- 'files.selector.tab.uploads': 'Uploaded',
- 'files.selector.tab.created': 'AI-created',
- 'files.selector.tab.shared': 'Shared',
- 'files.selector.select_all': 'Select all',
- 'files.selector.deselect_all': 'Deselect all',
- 'files.selector.file_selected': 'File',
- 'files.selector.files_selected': 'Files',
- 'files.selector.selected_suffix': 'selected',
- 'files.selector.upload_new': 'Upload new file',
- 'files.selector.loading': 'Loading files...',
- 'files.selector.error_loading': 'Error loading files:',
- 'files.upload.title': 'Upload file',
- 'files.upload.drop_here': 'Drop file here...',
- 'files.upload.uploading': 'Uploading...',
- 'files.upload.drag_files': 'Drag files here',
- 'files.upload.or': 'or',
- 'files.upload.browse': 'Browse',
- 'files.upload.selected_file': 'Selected file:',
- 'files.upload.upload_button': 'Upload',
- 'files.upload.uploading_button': 'Uploading...',
- 'files.upload.success': 'File uploaded successfully!',
- 'files.upload.error': 'An error occurred while uploading.',
- 'files.upload.unexpected_error': 'An unexpected error occurred while uploading.',
-
- // Files Page
- 'files.page.tab.all': 'All Files',
- 'files.page.tab.uploads': 'My Uploads',
- 'files.page.tab.created': 'Created Files',
- 'files.page.tab.shared': 'Shared Files',
- 'files.page.add_file': 'Add File',
- 'files.page.loading': 'Loading files...',
- 'files.page.error': 'Error:',
- },
- fr: {
- // Navigation
- 'nav.dashboard': 'Centre d\'activité',
- 'nav.files': 'Fichiers',
- 'nav.team': 'Espace équipe',
- 'nav.settings': 'Paramètres',
-
- // Settings page
- 'settings.title': 'Paramètres',
- 'settings.appearance': 'Apparence',
- 'settings.language': 'Langue',
- 'settings.about': 'À propos',
- 'settings.version': 'Version',
- 'settings.theme': 'Thème',
- 'settings.theme.description': 'Basculer entre le mode clair et sombre',
- 'settings.language.description': 'Choisissez votre langue préférée',
- 'settings.theme.light': 'Clair',
- 'settings.theme.dark': 'Sombre',
- 'settings.theme.toggle.light': 'Passer en mode clair',
- 'settings.theme.toggle.dark': 'Passer en mode sombre',
-
- // Languages
- 'language.german': 'Deutsch',
- 'language.english': 'English',
- 'language.french': 'Français',
-
- // Common
- 'common.loading': 'Chargement...',
- 'common.error': 'Erreur',
- 'common.success': 'Succès',
- 'common.cancel': 'Annuler',
- 'common.save': 'Enregistrer',
- 'common.delete': 'Supprimer',
- 'common.edit': 'Modifier',
- 'common.close': 'Fermer',
-
- // Auth
- 'auth.login': 'Se connecter',
- 'auth.register': 'S\'inscrire',
- 'auth.logout': 'Se déconnecter',
- 'auth.email': 'E-mail',
- 'auth.password': 'Mot de passe',
-
- // Dashboard
- 'dashboard.prompt.template': 'Modèle de prompt',
- 'dashboard.prompt.settings': 'Paramètres',
- 'dashboard.chat.area': 'Zone de chat',
- 'dashboard.chat.history': 'Historique des workflows',
- 'dashboard.log.title': 'Journal',
- 'dashboard.log.workflow': 'Workflow',
- 'dashboard.log.no_workflow': 'Aucun workflow sélectionné',
- 'dashboard.log.loading': 'Chargement des logs...',
- 'dashboard.log.error': 'Erreur lors du chargement des logs',
- 'dashboard.log.no_logs': 'Aucun log disponible pour ce workflow',
- 'dashboard.log.waiting': 'Workflow en cours... En attente des logs...',
- 'dashboard.log.fetch_failed': 'Échec du chargement des logs',
- 'dashboard.log.level.info': 'INFO',
-
- // Prompt Set
- 'promptset.loading': 'Chargement des prompts...',
- 'promptset.error.loading': 'Erreur lors du chargement des prompts',
- 'promptset.retry': 'Réessayer',
- 'promptset.new_prompt': 'Nouveau prompt',
- 'promptset.prompt_count': 'Prompt',
- 'promptset.prompt_count_plural': 'Prompts',
- 'promptset.no_prompts': 'Aucun prompt disponible',
- 'promptset.created': 'Créé',
- 'promptset.run_tooltip': 'Exécuter le prompt',
- 'promptset.share_tooltip': 'Partager le prompt',
- 'promptset.delete_tooltip': 'Supprimer le prompt',
- 'promptset.confirm_delete': 'Cliquez à nouveau pour confirmer',
- 'promptset.deleting': 'Suppression...',
- 'promptset.confirm_click': 'Cliquez pour confirmer',
- 'promptset.delete_error': 'Erreur lors de la suppression',
- 'promptset.deleting_message': 'Suppression du prompt...',
-
- // Prompt Modal
- 'modal.create_prompt': 'Créer un nouveau prompt',
- 'modal.name_required': 'Le nom est requis',
- 'modal.content_required': 'Le contenu est requis',
- 'modal.create_error': 'Erreur lors de la création du prompt',
- 'modal.name_label': 'Nom',
- 'modal.content_label': 'Contenu',
- 'modal.name_placeholder': 'Entrez un nom pour le prompt',
- 'modal.content_placeholder': 'Entrez le contenu du prompt',
- 'modal.cancel': 'Annuler',
- 'modal.creating': 'Création...',
- 'modal.create': 'Créer le prompt',
-
- // Share Modal
- 'share_modal.title': 'Partager le prompt',
- 'share_modal.select_users': 'Sélectionner les utilisateurs',
- 'share_modal.select_all': 'Tout sélectionner',
- 'share_modal.deselect_all': 'Tout désélectionner',
- 'share_modal.loading_users': 'Chargement des utilisateurs...',
- 'share_modal.error_loading_users': 'Erreur lors du chargement des utilisateurs',
- 'share_modal.no_users_available': 'Aucun utilisateur disponible',
- 'share_modal.no_users_selected': 'Veuillez sélectionner au moins un utilisateur',
- 'share_modal.one_user_selected': '1 utilisateur sélectionné',
- 'share_modal.multiple_users_selected': '{count} utilisateurs sélectionnés',
- 'share_modal.custom_title': 'Titre personnalisé (facultatif)',
- 'share_modal.title_placeholder': 'Entrez un titre personnalisé',
- 'share_modal.message': 'Message (facultatif)',
- 'share_modal.message_placeholder': 'Ajoutez un message pour les destinataires',
- 'share_modal.share': 'Partager',
- 'share_modal.sharing': 'Partage en cours...',
- 'share_modal.share_error': 'Erreur lors du partage du prompt',
-
- // Prompt Settings
- 'prompt_settings.title': 'Paramètres de prompt',
- 'prompt_settings.content_placeholder': 'Le contenu des paramètres sera ajouté dans les futures mises à jour.',
-
- // Chat Area
- 'chat.continue_conversation': 'Continuer la conversation...',
- 'chat.enter_message': 'Entrez votre message...',
- 'chat.remove_file': 'Supprimer le fichier',
- 'chat.attach_file': 'Joindre un fichier',
- 'chat.you': 'Vous',
- 'chat.click_to_open': 'Cliquez pour ouvrir',
- 'chat.preview_document': 'Aperçu du document',
- 'chat.download_document': 'Télécharger le document',
- 'chat.workflow_failed': 'Échec du workflow.',
- 'chat.retry_workflow': 'Réessayer',
- 'chat.sending_followup': 'Envoi du message de suivi...',
- 'chat.sending_message': 'Envoi du message...',
- 'chat.error_prefix': 'Erreur:',
- 'chat.error_loading_messages': 'Erreur lors du chargement des messages:',
- 'chat.loading_workflow_messages': 'Chargement des messages de workflow...',
- 'chat.start_conversation': 'Commencez une conversation en entrant un message, en sélectionnant un modèle ou en continuant un workflow précédent...',
-
- // File Preview
- 'file_preview.loading': 'Chargement de l\'aperçu...',
- 'file_preview.error': 'Erreur',
- 'file_preview.no_preview': 'Aucun aperçu disponible',
- 'file_preview.close_preview': 'Fermer l\'aperçu',
- 'file_preview.python': 'Python',
-
- // Chat History
- 'chat_history.loading': 'Chargement des workflows...',
- 'chat_history.error_loading': 'Erreur lors du chargement des workflows:',
- 'chat_history.try_again': 'Réessayer',
- 'chat_history.title': 'Historique des workflows',
- 'chat_history.workflow_count': 'Workflow',
- 'chat_history.workflow_count_plural': 'Workflows',
- 'chat_history.empty_state': 'Aucun workflow disponible',
- 'chat_history.confirm_delete': 'Êtes-vous sûr de vouloir supprimer le workflow "{id}..."?',
- 'chat_history.no_message_content': 'Aucun contenu de message disponible',
- 'chat_history.unknown_date': 'Date inconnue',
- 'chat_history.invalid_date': 'Date invalide',
- 'chat_history.started': 'Démarré:',
- 'chat_history.last_activity': 'Dernière activité:',
- 'chat_history.round': 'Tour',
- 'chat_history.resume_tooltip': 'Reprendre le workflow',
- 'chat_history.delete_tooltip': 'Supprimer le workflow',
- 'chat_history.deleting': 'Suppression du workflow...',
-
- // Workflow Status
- 'status.error': 'ERREUR',
- 'status.failed': 'ÉCHEC',
- 'status.stopped': 'ARRÊTÉ',
- 'status.cancelled': 'ANNULÉ',
- 'status.running': 'EN COURS',
- 'status.processing': 'TRAITEMENT',
- 'status.completed': 'TERMINÉ',
- 'status.pending': 'EN ATTENTE',
-
- // Files
- 'files.unknown_size': 'Taille inconnue',
- 'files.unknown_date': 'Date inconnue',
- 'files.source.uploaded': 'Téléchargé',
- 'files.source.ai_created': 'Créé par IA',
- 'files.source.shared': 'Partagé',
- 'files.source.unknown': 'Inconnu',
- 'files.preview_tooltip': 'Aperçu du fichier',
- 'files.download_tooltip': 'Télécharger le fichier',
- 'files.delete_tooltip': 'Supprimer le fichier',
- 'files.delete_confirm_tooltip': 'Cliquez à nouveau pour confirmer la suppression',
- 'files.downloading': 'Téléchargement...',
- 'files.deleting': 'Suppression...',
- 'files.delete_confirm': 'Cliquez pour confirmer...',
- 'files.no_files': 'Aucun fichier trouvé.',
- 'files.no_shared_files': 'Aucun fichier partagé trouvé.',
- 'files.no_ai_files': 'Aucun fichier créé par IA trouvé.',
- 'files.no_uploaded_files': 'Aucun fichier téléchargé trouvé.',
- 'files.header.name': 'Nom',
- 'files.header.type': 'Type',
- 'files.header.size': 'Taille',
- 'files.header.date': 'Date',
- 'files.selector.title': 'Sélectionner des fichiers',
- 'files.selector.tab.all': 'Tous les fichiers',
- 'files.selector.tab.uploads': 'Téléchargés',
- 'files.selector.tab.created': 'Créés par IA',
- 'files.selector.tab.shared': 'Partagés',
- 'files.selector.select_all': 'Tout sélectionner',
- 'files.selector.deselect_all': 'Tout désélectionner',
- 'files.selector.file_selected': 'Fichier',
- 'files.selector.files_selected': 'Fichiers',
- 'files.selector.selected_suffix': 'sélectionné(s)',
- 'files.selector.upload_new': 'Télécharger un nouveau fichier',
- 'files.selector.loading': 'Chargement des fichiers...',
- 'files.selector.error_loading': 'Erreur lors du chargement des fichiers:',
- 'files.upload.title': 'Télécharger un fichier',
- 'files.upload.drop_here': 'Déposer le fichier ici...',
- 'files.upload.uploading': 'Téléchargement...',
- 'files.upload.drag_files': 'Glisser les fichiers ici',
- 'files.upload.or': 'ou',
- 'files.upload.browse': 'Parcourir',
- 'files.upload.selected_file': 'Fichier sélectionné:',
- 'files.upload.upload_button': 'Télécharger',
- 'files.upload.uploading_button': 'Téléchargement...',
- 'files.upload.success': 'Fichier téléchargé avec succès!',
- 'files.upload.error': 'Une erreur s\'est produite lors du téléchargement.',
- 'files.upload.unexpected_error': 'Une erreur inattendue s\'est produite lors du téléchargement.',
-
- // Files Page
- 'files.page.tab.all': 'Tous les fichiers',
- 'files.page.tab.uploads': 'Mes téléchargements',
- 'files.page.tab.created': 'Fichiers créés',
- 'files.page.tab.shared': 'Fichiers partagés',
- 'files.page.add_file': 'Ajouter un fichier',
- 'files.page.loading': 'Chargement des fichiers...',
- 'files.page.error': 'Erreur:',
- }
-};
\ No newline at end of file
diff --git a/src/hooks/machines/useSidebarMachine.ts b/src/hooks/machines/useSidebarMachine.ts
deleted file mode 100644
index 55faccc..0000000
--- a/src/hooks/machines/useSidebarMachine.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-import { useActor } from '@xstate/react';
-import { useLocation } from 'react-router-dom';
-import { useEffect } from 'react';
-import { sidebarMachine, getSidebarState } from '../../machines/sidebarMachine';
-
-// Custom hook that provides all sidebar functionality
-export const useSidebarMachine = () => {
- // Step 1: Create the machine actor (this is like useState but for state machines)
- const [state, send] = useActor(sidebarMachine);
-
- // Step 2: Get the current route from React Router
- const location = useLocation();
-
- // Step 3: Update the machine when the route changes
- useEffect(() => {
- send({
- type: 'NAVIGATE',
- path: location.pathname,
- });
- }, [location.pathname, send]);
-
- // Step 4: Get derived state using our helper function
- const sidebarState = getSidebarState(state.context);
-
- // Step 5: Create easy-to-use action functions
- const actions = {
- // Toggle a specific menu item
- toggleItem: (itemId: string) => {
- send({
- type: 'TOGGLE_ITEM',
- itemId,
- });
- },
-
- // Close all submenus
- closeAll: () => {
- send({
- type: 'CLOSE_ALL',
- });
- },
-
- // Check if a specific item is open
- isItemOpen: (itemId: string) => {
- return sidebarState.isItemOpen(itemId);
- },
-
- // Check if an item is the active route
- isItemActive: (itemPath?: string) => {
- if (!itemPath) return false;
- return location.pathname === itemPath;
- },
-
- // Minimize/expand sidebar
- minimizeSidebar: () => {
- send({
- type: 'MINIMIZE_SIDEBAR',
- });
- },
-
- expandSidebar: () => {
- send({
- type: 'EXPAND_SIDEBAR',
- });
- },
- };
-
- // Step 6: Return everything the components need
- return {
- // State queries (read-only)
- hasOpenSubmenu: sidebarState.hasOpenSubmenu,
- openItemId: sidebarState.openItemId,
- activePath: sidebarState.activePath,
- isMinimized: sidebarState.isMinimized,
- currentState: state.value, // For debugging: 'collapsed' or 'expanded'
-
- // Actions (functions to call)
- toggleItem: actions.toggleItem,
- closeAll: actions.closeAll,
- isItemOpen: actions.isItemOpen,
- isItemActive: actions.isItemActive,
- minimizeSidebar: actions.minimizeSidebar,
- expandSidebar: actions.expandSidebar,
-
- // Raw state machine state (for debugging)
- _debugState: state,
- _debugSend: send,
- };
-};
-
-// Step 7: Type export for components that need it
-export type UseSidebarMachine = ReturnType;
\ No newline at end of file
diff --git a/src/hooks/useApi.ts b/src/hooks/useApi.ts
index d083884..b48e2a9 100644
--- a/src/hooks/useApi.ts
+++ b/src/hooks/useApi.ts
@@ -1,4 +1,4 @@
-import { useState } from 'react';
+import { useState, useCallback } from 'react';
import api from '../api';
// Generic API error handling
@@ -26,7 +26,7 @@ export function useApiRequest() {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
- const request = async ({
+ const request = useCallback(async ({
url,
method,
data,
@@ -52,7 +52,7 @@ export function useApiRequest() {
} finally {
setIsLoading(false);
}
- };
+ }, []);
return {
request,
diff --git a/src/hooks/useAuthentication.ts b/src/hooks/useAuthentication.ts
index 7882250..6b00eb8 100644
--- a/src/hooks/useAuthentication.ts
+++ b/src/hooks/useAuthentication.ts
@@ -30,23 +30,43 @@ export function useAuth() {
params.append('client_id', '');
params.append('client_secret', '');
- // Create a custom axios instance for this request
- const instance = axios.create({
- baseURL: import.meta.env.VITE_API_BASE_URL,
- withCredentials: true,
+ // Generate a simple CSRF token (in production, this should come from the server)
+ const csrfToken = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
+
+ // Use the existing api instance with custom headers for this request
+ const response = await api.post('/api/local/login', params, {
headers: {
- 'Content-Type': 'application/x-www-form-urlencoded'
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ 'X-CSRF-Token': csrfToken
}
});
- const response = await instance.post('/api/token', params);
-
- // Store the entire auth response
- if (response.data.accessToken) {
- localStorage.setItem('auth_data', JSON.stringify(response.data));
+ // Normalize the response structure to match what the frontend expects
+ let normalizedAuthData;
+ if (response.data.token_data) {
+ // Backend returns token_data with tokenAccess field, normalize to accessToken
+ normalizedAuthData = {
+ accessToken: response.data.token_data.tokenAccess || response.data.access_token,
+ tokenType: response.data.token_data.tokenType || 'bearer',
+ userId: response.data.token_data.userId,
+ expiresAt: response.data.token_data.expiresAt,
+ createdAt: response.data.token_data.createdAt
+ };
+ } else {
+ // Fallback to old structure if needed
+ normalizedAuthData = {
+ accessToken: response.data.access_token,
+ tokenType: response.data.token_type || 'bearer'
+ };
}
- return response.data;
+ // Store the normalized auth response
+ localStorage.setItem('auth_data', JSON.stringify(normalizedAuthData));
+
+ return {
+ accessToken: normalizedAuthData.accessToken,
+ tokenType: normalizedAuthData.tokenType
+ };
} catch (error: any) {
let errorMessage = 'An error occurred during login';
@@ -85,8 +105,6 @@ interface MsalAuthResponse {
}
export function useMsalAuth() {
- const { instance, accounts } = useMsal();
- const { request, isLoading, error } = useApiRequest();
const [msalError, setMsalError] = useState(null);
const [isMsalLoading, setIsMsalLoading] = useState(false);
@@ -95,75 +113,93 @@ export function useMsalAuth() {
setMsalError(null);
try {
- let msalToken;
+ return new Promise((resolve, reject) => {
+ // Open popup to backend Microsoft login route
+ const popup = window.open(
+ `${import.meta.env.VITE_API_BASE_URL}/api/msft/login?state=login`,
+ 'msft-login',
+ 'width=500,height=600,scrollbars=yes,resizable=yes'
+ );
- // If we have an account, try to get the token silently
- if (accounts.length > 0) {
- const silentRequest = {
- scopes: ['user.read'],
- account: accounts[0]
+ if (!popup) {
+ setMsalError('Popup was blocked. Please allow popups and try again.');
+ setIsMsalLoading(false);
+ reject(new Error('Popup was blocked'));
+ return;
+ }
+
+ // Listen for messages from the popup
+ const messageListener = (event: MessageEvent) => {
+ // Verify origin for security
+ const apiUrl = new URL(import.meta.env.VITE_API_BASE_URL);
+ if (event.origin !== apiUrl.origin) {
+ return;
+ }
+
+ if (event.data.type === 'msft_auth_success') {
+ // Store the auth data with normalized field names
+ if (event.data.token_data) {
+ const normalizedTokenData = {
+ accessToken: event.data.token_data.tokenAccess, // Convert tokenAccess to accessToken
+ tokenType: event.data.token_data.tokenType,
+ userId: event.data.token_data.userId,
+ expiresAt: event.data.token_data.expiresAt,
+ createdAt: event.data.token_data.createdAt
+ };
+ localStorage.setItem('auth_data', JSON.stringify(normalizedTokenData));
+ }
+
+ // Clean up
+ window.removeEventListener('message', messageListener);
+ popup.close();
+ setIsMsalLoading(false);
+
+ // Resolve with the token data
+ resolve({
+ accessToken: event.data.token_data.tokenAccess,
+ tokenType: event.data.token_data.tokenType || 'bearer',
+ user: {
+ username: '', // Will be populated by the backend
+ email: '',
+ fullName: '',
+ mandateId: 0
+ }
+ });
+ } else if (event.data.type === 'msft_connection_error') {
+ // Handle error
+ window.removeEventListener('message', messageListener);
+ popup.close();
+ setIsMsalLoading(false);
+ setMsalError(event.data.error || 'Microsoft authentication failed');
+ reject(new Error(event.data.error || 'Microsoft authentication failed'));
+ }
};
- try {
- const response = await instance.acquireTokenSilent(silentRequest);
- msalToken = response.accessToken;
- } catch (e) {
- // If silent token acquisition fails, fall back to popup
- const response = await instance.acquireTokenPopup(silentRequest);
- msalToken = response.accessToken;
- }
- } else {
- // No account, do popup login
- const response = await instance.loginPopup({
- scopes: ['user.read']
- });
-
- if (response.account) {
- const tokenResponse = await instance.acquireTokenSilent({
- scopes: ['user.read'],
- account: response.account
- });
- msalToken = tokenResponse.accessToken;
- } else {
- throw new Error('Failed to get account after login');
- }
- }
-
- // Exchange MSAL token for backend token
- const response = await api.post('/api/msft/token', null, {
- headers: {
- 'Authorization': `Bearer ${msalToken}`
- }
+ // Add message listener
+ window.addEventListener('message', messageListener);
+
+ // Handle popup closing without completing auth
+ const checkClosed = setInterval(() => {
+ if (popup.closed) {
+ clearInterval(checkClosed);
+ window.removeEventListener('message', messageListener);
+ setIsMsalLoading(false);
+ setMsalError('Authentication was cancelled');
+ reject(new Error('Authentication was cancelled'));
+ }
+ }, 1000);
});
-
- // Store the backend token
- if (response.data.accessToken) {
- localStorage.setItem('auth_data', JSON.stringify(response.data));
- }
-
- return response.data;
} catch (error: any) {
- let errorMessage = 'MSAL Login fehlgeschlagen';
-
- if (error.response) {
- errorMessage = error.response.data?.detail || error.response.data?.message || errorMessage;
- } else if (error.request) {
- errorMessage = 'Keine Antwort vom Server erhalten';
- } else {
- errorMessage = error.message || errorMessage;
- }
-
- setMsalError(errorMessage);
- throw new Error(errorMessage);
- } finally {
+ setMsalError(error.message || 'Microsoft authentication failed');
setIsMsalLoading(false);
+ throw error;
}
};
return {
loginWithMsal,
- error: msalError || error,
- isLoading: isMsalLoading || isLoading
+ error: msalError,
+ isLoading: isMsalLoading
};
}
@@ -174,47 +210,83 @@ interface RegisterData {
email: string;
fullName: string;
language?: string;
+ enabled?: boolean;
+ privilege?: string;
}
interface RegisterResponse {
success: boolean;
message?: string;
user?: {
+ id: string;
username: string;
email: string;
fullName: string;
+ language: string;
+ enabled: boolean;
+ privilege: string;
};
}
export function useRegister() {
- const { request, isLoading, error } = useApiRequest();
+ const [error, setError] = useState(null);
+ const [isLoading, setIsLoading] = useState(false);
const register = async (userData: RegisterData): Promise => {
+ setIsLoading(true);
+ setError(null);
+
try {
- // Add default language if not provided
+ // Prepare data to match backend expectations
+ // Backend expects userData as object and password as embedded field
const dataToSend = {
- ...userData,
- language: userData.language || 'de'
+ userData: {
+ username: userData.username,
+ email: userData.email,
+ fullName: userData.fullName,
+ language: userData.language || 'de',
+ enabled: userData.enabled !== undefined ? userData.enabled : true,
+ privilege: userData.privilege || 'user'
+ },
+ password: userData.password
};
- const response = await request({
- url: '/api/users/register',
- method: 'post',
- data: dataToSend,
- additionalConfig: {
- headers: {
- 'Content-Type': 'application/json'
- }
+ const response = await api.post('/api/local/register', dataToSend, {
+ headers: {
+ 'Content-Type': 'application/json'
}
});
return {
success: true,
message: 'Registration successful',
- user: response
+ user: response.data
};
} catch (error: any) {
+ let errorMessage = 'An error occurred during registration';
+
+ if (error.response) {
+ // Handle validation errors from FastAPI
+ if (error.response.data?.detail) {
+ if (Array.isArray(error.response.data.detail)) {
+ // Handle FastAPI validation errors array
+ errorMessage = error.response.data.detail.map((err: any) => err.msg).join(', ');
+ } else {
+ errorMessage = error.response.data.detail;
+ }
+ } else {
+ errorMessage = 'Registration failed';
+ }
+ } else if (error.request) {
+ errorMessage = 'No response received from server';
+ } else {
+ errorMessage = error.message;
+ }
+
+ setError(errorMessage);
throw error;
+ } finally {
+ setIsLoading(false);
}
};
@@ -262,7 +334,7 @@ export function useMsalRegister() {
// Register the user through our backend
const response = await request({
- url: '/api/users/register-with-msal',
+ url: '/api/msft/register',
method: 'post',
data: userData,
additionalConfig: {
@@ -287,4 +359,122 @@ export function useMsalRegister() {
error,
isLoading
};
+}
+
+// Username availability check
+export function useUsernameAvailability() {
+ const [isChecking, setIsChecking] = useState(false);
+ const [error, setError] = useState(null);
+
+ const checkAvailability = async (username: string, authenticationAuthority: string = 'local'): Promise<{
+ username: string;
+ authenticationAuthority: string;
+ available: boolean;
+ message: string;
+ }> => {
+ setIsChecking(true);
+ setError(null);
+
+ try {
+ const response = await api.get('/api/local/available', {
+ params: {
+ username,
+ authenticationAuthority
+ }
+ });
+
+ return response.data;
+ } catch (error: any) {
+ let errorMessage = 'Failed to check username availability';
+
+ if (error.response) {
+ errorMessage = error.response.data?.detail || errorMessage;
+ }
+
+ setError(errorMessage);
+ throw error;
+ } finally {
+ setIsChecking(false);
+ }
+ };
+
+ return {
+ checkAvailability,
+ isChecking,
+ error
+ };
+}
+
+// Logout function
+export function useLogout() {
+ const [isLoading, setIsLoading] = useState(false);
+ const [error, setError] = useState(null);
+
+ const logout = async (): Promise => {
+ setIsLoading(true);
+ setError(null);
+
+ try {
+ await api.post('/api/local/logout');
+
+ // Clear local storage
+ localStorage.removeItem('auth_data');
+
+ // Redirect to login page
+ window.location.href = '/login';
+ } catch (error: any) {
+ let errorMessage = 'Logout failed';
+
+ if (error.response) {
+ errorMessage = error.response.data?.detail || errorMessage;
+ }
+
+ setError(errorMessage);
+ throw error;
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ return {
+ logout,
+ isLoading,
+ error
+ };
+}
+
+// Get current user
+export function useCurrentUser() {
+ const [user, setUser] = useState(null);
+ const [isLoading, setIsLoading] = useState(false);
+ const [error, setError] = useState(null);
+
+ const getCurrentUser = async (): Promise => {
+ setIsLoading(true);
+ setError(null);
+
+ try {
+ const response = await api.get('/api/local/me');
+ setUser(response.data);
+ return response.data;
+ } catch (error: any) {
+ let errorMessage = 'Failed to get current user';
+
+ if (error.response) {
+ errorMessage = error.response.data?.detail || errorMessage;
+ }
+
+ setError(errorMessage);
+ throw error;
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ return {
+ user,
+ getCurrentUser,
+ isLoading,
+ error
+ };
}
\ No newline at end of file
diff --git a/src/hooks/useConnections.ts b/src/hooks/useConnections.ts
new file mode 100644
index 0000000..dc9aa8c
--- /dev/null
+++ b/src/hooks/useConnections.ts
@@ -0,0 +1,336 @@
+import { useState, useEffect } from 'react';
+import { useApiRequest } from './useApi';
+
+// Connection interfaces based on backend UserConnection model
+export interface Connection {
+ id: string;
+ userId: string;
+ authority: 'local' | 'google' | 'msft';
+ externalId: string;
+ externalUsername: string;
+ externalEmail?: string;
+ status: 'active' | 'expired' | 'revoked' | 'pending';
+ connectedAt: string;
+ lastChecked: string;
+ expiresAt?: string;
+}
+
+export interface CreateConnectionData {
+ id?: string;
+ userId?: string;
+ authority?: 'msft' | 'google'; // Keep for compatibility with existing code
+ type?: 'msft' | 'google'; // Backend expects this field
+ externalId?: string;
+ externalUsername?: string;
+ externalEmail?: string;
+ status?: 'active' | 'expired' | 'revoked' | 'pending';
+ connectedAt?: string;
+ lastChecked?: string;
+ expiresAt?: string;
+}
+
+export interface ConnectResponse {
+ authUrl: string;
+}
+
+// Hook for managing connections
+export function useConnections() {
+ const [connections, setConnections] = useState([]);
+ const { request, isLoading, error } = useApiRequest();
+
+ // Fetch all connections
+ const fetchConnections = async (): Promise => {
+ try {
+ const data = await request({
+ url: '/api/connections/',
+ method: 'get'
+ });
+ setConnections(data);
+ return data;
+ } catch (error) {
+ console.error('Error fetching connections:', error);
+ setConnections([]);
+ throw error;
+ }
+ };
+
+ // Create a new connection
+ const createConnection = async (connectionData: CreateConnectionData): Promise => {
+ try {
+ const data = await request({
+ url: '/api/connections/',
+ method: 'post',
+ data: connectionData
+ });
+
+ // Update local state
+ setConnections(prev => {
+ const existing = prev.find(conn => conn.id === data.id);
+ if (existing) {
+ return prev.map(conn => conn.id === data.id ? data : conn);
+ } else {
+ return [...prev, data];
+ }
+ });
+
+ return data;
+ } catch (error) {
+ console.error('Error creating connection:', error);
+ throw error;
+ }
+ };
+
+ // Connect to a service (initiate OAuth)
+ const connectService = async (connectionId: string): Promise => {
+ try {
+ const data = await request({
+ url: `/api/connections/${connectionId}/connect`,
+ method: 'post'
+ });
+ return data;
+ } catch (error) {
+ console.error('Error connecting service:', error);
+ throw error;
+ }
+ };
+
+ // Disconnect from a service
+ const disconnectService = async (connectionId: string): Promise<{ message: string }> => {
+ try {
+ const data = await request({
+ url: `/api/connections/${connectionId}/disconnect`,
+ method: 'post'
+ });
+
+ // Update local state
+ setConnections(prev =>
+ prev.map(conn =>
+ conn.id === connectionId
+ ? { ...conn, status: 'inactive' as any, lastChecked: new Date().toISOString() }
+ : conn
+ )
+ );
+
+ return data;
+ } catch (error) {
+ console.error('Error disconnecting service:', error);
+ throw error;
+ }
+ };
+
+ // Delete a connection
+ const deleteConnection = async (connectionId: string): Promise<{ message: string }> => {
+ try {
+ const data = await request({
+ url: `/api/connections/${connectionId}`,
+ method: 'delete'
+ });
+
+ // Update local state
+ setConnections(prev => prev.filter(conn => conn.id !== connectionId));
+
+ return data;
+ } catch (error) {
+ console.error('Error deleting connection:', error);
+ throw error;
+ }
+ };
+
+ // Update a connection
+ const updateConnection = async (connectionId: string, updateData: Partial): Promise => {
+ try {
+ // Use PUT endpoint for updating connections
+ const data = await request({
+ url: `/api/connections/${connectionId}`,
+ method: 'put',
+ data: updateData
+ });
+
+ // Update local state
+ setConnections(prev =>
+ prev.map(conn => conn.id === connectionId ? { ...conn, ...data } : conn)
+ );
+
+ return data;
+ } catch (error) {
+ console.error('Error updating connection:', error);
+ throw error;
+ }
+ };
+
+ return {
+ connections,
+ fetchConnections,
+ createConnection,
+ updateConnection,
+ connectService,
+ disconnectService,
+ deleteConnection,
+ isLoading,
+ error
+ };
+}
+
+// Hook for OAuth connection popup flow (similar to useMsalAuth)
+export function useOAuthConnect() {
+ const { connectService, fetchConnections } = useConnections();
+ const [isConnecting, setIsConnecting] = useState(false);
+ const [connectError, setConnectError] = useState(null);
+
+ const connectWithPopup = async (connectionId: string): Promise => {
+ setIsConnecting(true);
+ setConnectError(null);
+
+ try {
+ // Get the OAuth URL from backend
+ const response = await connectService(connectionId);
+ if (!response.authUrl) {
+ throw new Error('No OAuth URL received from backend');
+ }
+
+ console.log('OAuth URL from backend:', response.authUrl);
+
+ return new Promise((resolve, reject) => {
+ // Convert relative URL to absolute URL if needed
+ let authUrl = response.authUrl;
+ if (authUrl.startsWith('/')) {
+ authUrl = `${import.meta.env.VITE_API_BASE_URL}${authUrl}`;
+ }
+
+ // Open popup using the same pattern as useAuthentication.ts
+ const popup = window.open(
+ authUrl,
+ 'oauth-connect',
+ 'width=500,height=600,scrollbars=yes,resizable=yes'
+ );
+
+ if (!popup) {
+ setConnectError('Popup was blocked. Please allow popups and try again.');
+ setIsConnecting(false);
+ reject(new Error('Popup was blocked'));
+ return;
+ }
+
+ // Handle popup closing without completing auth
+ const checkClosed = setInterval(() => {
+ if (popup.closed) {
+ clearInterval(checkClosed);
+ window.removeEventListener('message', messageListener);
+ setIsConnecting(false);
+ console.log('OAuth popup closed');
+ // Refresh connections anyway in case it succeeded
+ fetchConnections();
+ setConnectError('Authentication was cancelled');
+ reject(new Error('Authentication was cancelled'));
+ }
+ }, 1000);
+
+ // Listen for messages from the popup (similar to useMsalAuth)
+ const messageListener = (event: MessageEvent) => {
+ // Verify origin for security
+ const apiUrl = new URL(import.meta.env.VITE_API_BASE_URL);
+ if (event.origin !== apiUrl.origin) {
+ return;
+ }
+
+ if (event.data.type === 'msft_connection_success' || event.data.type === 'google_connection_success') {
+ // Clean up - IMPORTANT: clear the checkClosed interval first
+ clearInterval(checkClosed);
+ window.removeEventListener('message', messageListener);
+ popup.close();
+ setIsConnecting(false);
+ console.log('OAuth connection successful');
+ // Refresh connections
+ fetchConnections();
+ resolve();
+ } else if (event.data.type === 'msft_connection_error' || event.data.type === 'google_connection_error') {
+ // Handle error - also clear the checkClosed interval
+ clearInterval(checkClosed);
+ window.removeEventListener('message', messageListener);
+ popup.close();
+ setIsConnecting(false);
+ setConnectError(event.data.error || 'OAuth connection failed');
+ reject(new Error(event.data.error || 'OAuth connection failed'));
+ }
+ };
+
+ // Add message listener
+ window.addEventListener('message', messageListener);
+ });
+ } catch (error: any) {
+ setConnectError(error.message || 'OAuth connection failed');
+ setIsConnecting(false);
+ throw error;
+ }
+ };
+
+ return {
+ connectWithPopup,
+ isConnecting,
+ error: connectError
+ };
+}
+
+// Hook for disconnecting services
+export function useDisconnect() {
+ const { disconnectService, fetchConnections } = useConnections();
+ const [isDisconnecting, setIsDisconnecting] = useState(false);
+ const [disconnectError, setDisconnectError] = useState(null);
+
+ const disconnect = async (connectionId: string): Promise => {
+ setIsDisconnecting(true);
+ setDisconnectError(null);
+
+ try {
+ await disconnectService(connectionId);
+ console.log('Service disconnected successfully');
+ // Refresh connections to update the status
+ await fetchConnections();
+ } catch (error: any) {
+ setDisconnectError(error.message || 'Disconnect failed');
+ console.error('Error disconnecting service:', error);
+ throw error;
+ } finally {
+ setIsDisconnecting(false);
+ }
+ };
+
+ return {
+ disconnect,
+ isDisconnecting,
+ error: disconnectError
+ };
+}
+
+// Hook for individual connection operations
+export function useConnection(connectionId?: string) {
+ const [connection, setConnection] = useState(null);
+ const { request, isLoading, error } = useApiRequest();
+
+ const fetchConnection = async (id: string = connectionId!): Promise => {
+ if (!id) return null;
+
+ try {
+ // Since there's no individual connection endpoint, fetch all and filter
+ const data: Connection[] = await request({
+ url: '/api/connections/',
+ method: 'get'
+ });
+
+ const foundConnection = data.find((conn: Connection) => conn.id === id);
+ setConnection(foundConnection || null);
+ return foundConnection || null;
+ } catch (error) {
+ console.error('Error fetching connection:', error);
+ setConnection(null);
+ throw error;
+ }
+ };
+
+ return {
+ connection,
+ fetchConnection,
+ isLoading,
+ error
+ };
+}
\ No newline at end of file
diff --git a/src/hooks/useSharePointTest.ts b/src/hooks/useSharePointTest.ts
new file mode 100644
index 0000000..fe4b5cb
--- /dev/null
+++ b/src/hooks/useSharePointTest.ts
@@ -0,0 +1,277 @@
+import { useState } from 'react';
+import { useApiRequest } from './useApi';
+
+// SharePoint interfaces
+export interface SharePointConnection {
+ id: string;
+ name: string;
+ description: string;
+ status: string;
+ authority: string;
+ lastChecked: string | null;
+ expiresAt: string | null;
+ externalUsername: string;
+ externalEmail: string;
+}
+
+export interface SharePointDocument {
+ documentName: string;
+ documentData: any;
+ mimeType: string;
+}
+
+export interface SharePointResponse {
+ success: boolean;
+ data?: {
+ documents?: SharePointDocument[];
+ };
+ error?: string;
+ message: string;
+}
+
+export interface SharePointListRequest {
+ connectionReference: string;
+ siteUrl: string;
+ folderPaths: string[];
+ includeSubfolders?: boolean;
+ expectedDocumentFormats?: Array<{
+ extension: string;
+ mimeType: string;
+ description?: string;
+ }>;
+}
+
+export interface SharePointFindRequest {
+ connectionReference: string;
+ siteUrl: string;
+ query: string;
+ searchScope?: string;
+ expectedDocumentFormats?: Array<{
+ extension: string;
+ mimeType: string;
+ description?: string;
+ }>;
+}
+
+export interface SharePointReadRequest {
+ documentList: string;
+ connectionReference: string;
+ siteUrl: string;
+ documentPaths: string[];
+ includeMetadata?: boolean;
+ expectedDocumentFormats?: Array<{
+ extension: string;
+ mimeType: string;
+ description?: string;
+ }>;
+}
+
+export interface SharePointUploadRequest {
+ connectionReference: string;
+ siteUrl: string;
+ documentPaths: string[];
+ documentList: string;
+ fileNames: string[];
+ expectedDocumentFormats?: Array<{
+ extension: string;
+ mimeType: string;
+ description?: string;
+ }>;
+}
+
+// Hook for SharePoint testing operations
+export function useSharePointTest() {
+ const { request, isLoading, error } = useApiRequest();
+ const [lastResponse, setLastResponse] = useState(null);
+
+ // Get user's Microsoft connections
+ const getConnections = async (): Promise => {
+ try {
+ const response = await request({
+ url: '/api/test-sharepoint/connections',
+ method: 'get'
+ });
+ return response.data || [];
+ } catch (error) {
+ console.error('Error fetching SharePoint connections:', error);
+ throw error;
+ }
+ };
+
+ // Test a specific connection
+ const testConnection = async (connectionId: string): Promise => {
+ try {
+ const response = await request({
+ url: `/api/test-sharepoint/test-connection/${connectionId}`,
+ method: 'get'
+ });
+ return response;
+ } catch (error) {
+ console.error('Error testing connection:', error);
+ throw error;
+ }
+ };
+
+ // List documents in SharePoint folders
+ const listDocuments = async (data: SharePointListRequest): Promise => {
+ try {
+ const response = await request({
+ url: '/api/test-sharepoint/list-documents',
+ method: 'post',
+ data
+ });
+ setLastResponse(response);
+ return response;
+ } catch (error) {
+ console.error('Error listing SharePoint documents:', error);
+ const errorResponse: SharePointResponse = {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error',
+ message: 'Failed to list documents'
+ };
+ setLastResponse(errorResponse);
+ throw error;
+ }
+ };
+
+ // Find documents by query
+ const findDocuments = async (data: SharePointFindRequest): Promise => {
+ try {
+ const response = await request({
+ url: '/api/test-sharepoint/find-documents',
+ method: 'post',
+ data
+ });
+ setLastResponse(response);
+ return response;
+ } catch (error) {
+ console.error('Error finding SharePoint documents:', error);
+ const errorResponse: SharePointResponse = {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error',
+ message: 'Failed to find documents'
+ };
+ setLastResponse(errorResponse);
+ throw error;
+ }
+ };
+
+ // Read documents from SharePoint
+ const readDocuments = async (data: SharePointReadRequest): Promise => {
+ try {
+ const response = await request({
+ url: '/api/test-sharepoint/read-documents',
+ method: 'post',
+ data
+ });
+ setLastResponse(response);
+ return response;
+ } catch (error) {
+ console.error('Error reading SharePoint documents:', error);
+ const errorResponse: SharePointResponse = {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error',
+ message: 'Failed to read documents'
+ };
+ setLastResponse(errorResponse);
+ throw error;
+ }
+ };
+
+ // Upload documents to SharePoint
+ const uploadDocuments = async (data: SharePointUploadRequest): Promise => {
+ try {
+ const response = await request({
+ url: '/api/test-sharepoint/upload-documents',
+ method: 'post',
+ data
+ });
+ setLastResponse(response);
+ return response;
+ } catch (error) {
+ console.error('Error uploading SharePoint documents:', error);
+ const errorResponse: SharePointResponse = {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error',
+ message: 'Failed to upload documents'
+ };
+ setLastResponse(errorResponse);
+ throw error;
+ }
+ };
+
+ // Get example request bodies
+ const getExamples = async (): Promise => {
+ try {
+ const response = await request({
+ url: '/api/test-sharepoint/example-requests',
+ method: 'get'
+ });
+ return response.examples || {};
+ } catch (error) {
+ console.error('Error getting example requests:', error);
+ throw error;
+ }
+ };
+
+ // Debug user's authentication tokens
+ const debugTokens = async (): Promise => {
+ try {
+ const response = await request({
+ url: '/api/test-sharepoint/debug-tokens',
+ method: 'get'
+ });
+ return response;
+ } catch (error) {
+ console.error('Error debugging tokens:', error);
+ throw error;
+ }
+ };
+
+ // Debug detailed token information
+ const debugTokenDetails = async (): Promise => {
+ try {
+ const response = await request({
+ url: '/api/test-sharepoint/debug-token-details',
+ method: 'get'
+ });
+ return response;
+ } catch (error) {
+ console.error('Error debugging token details:', error);
+ throw error;
+ }
+ };
+
+ // Discover SharePoint sites
+ const discoverSites = async (): Promise => {
+ try {
+ const response = await request({
+ url: '/api/test-sharepoint/discover-sites',
+ method: 'get'
+ });
+ return response;
+ } catch (error) {
+ console.error('Error discovering SharePoint sites:', error);
+ throw error;
+ }
+ };
+
+ return {
+ // API methods
+ getConnections,
+ testConnection,
+ listDocuments,
+ findDocuments,
+ readDocuments,
+ uploadDocuments,
+ getExamples,
+ debugTokens,
+ debugTokenDetails,
+ discoverSites,
+
+ // State
+ isLoading,
+ error,
+ lastResponse
+ };
+}
\ No newline at end of file
diff --git a/src/hooks/useUsers.ts b/src/hooks/useUsers.ts
index 70ae9fa..31c5162 100644
--- a/src/hooks/useUsers.ts
+++ b/src/hooks/useUsers.ts
@@ -3,12 +3,15 @@ import { useApiRequest } from './useApi';
// User interfaces
export interface User {
- id: number;
+ id: string;
username: string;
email: string;
fullName: string;
+ language: string;
+ enabled: boolean;
privilege: string;
- mandateId: number;
+ authenticationAuthority: string;
+ mandateId: string;
}
export type UserUpdateData = Partial>;
@@ -21,7 +24,7 @@ export function useCurrentUser() {
const fetchCurrentUser = async () => {
try {
const data = await request({
- url: '/api/user/me',
+ url: '/api/local/me',
method: 'get'
});
setUser(data);
@@ -30,6 +33,54 @@ export function useCurrentUser() {
}
};
+ const logout = async (msalInstance?: any) => {
+ if (!user) {
+ throw new Error('No user to logout');
+ }
+
+ try {
+ let logoutEndpoint = '/api/local/logout';
+
+ // Determine the correct logout endpoint based on authentication authority
+ if (user.authenticationAuthority === 'msft') {
+ logoutEndpoint = '/api/msft/logout';
+ } else if (user.authenticationAuthority === 'local') {
+ logoutEndpoint = '/api/local/logout';
+ }
+
+ await request({
+ url: logoutEndpoint,
+ method: 'post'
+ });
+
+ // Clear user state after successful logout
+ setUser(null);
+
+ // Clear any local storage data
+ localStorage.clear();
+
+ // Handle MSAL logout for Microsoft authentication
+ if (user.authenticationAuthority === 'msft' && msalInstance) {
+ try {
+ await msalInstance.logoutRedirect({
+ onRedirectNavigate: () => true
+ });
+ return; // MSAL will handle the redirect
+ } catch (msalError) {
+ console.error('MSAL logout failed:', msalError);
+ // Continue with regular redirect if MSAL logout fails
+ }
+ }
+
+ // Redirect to login or home page
+ window.location.href = '/login';
+
+ } catch (error) {
+ console.error('Logout failed:', error);
+ throw error;
+ }
+ };
+
useEffect(() => {
fetchCurrentUser();
}, []);
@@ -38,7 +89,8 @@ export function useCurrentUser() {
user,
error,
isLoading,
- refetch: fetchCurrentUser
+ refetch: fetchCurrentUser,
+ logout
};
}
diff --git a/src/locales/de.ts b/src/locales/de.ts
new file mode 100644
index 0000000..b934c93
--- /dev/null
+++ b/src/locales/de.ts
@@ -0,0 +1,263 @@
+export default {
+ // Navigation
+ 'nav.dashboard': 'Zentrale',
+ 'nav.files': 'Dateien',
+ 'nav.team': 'Team-Bereich',
+ 'nav.connections': 'Verbindungen',
+ 'nav.workflows': 'Workflows',
+ 'nav.settings': 'Einstellungen',
+
+ // Settings page
+ 'settings.title': 'Einstellungen',
+ 'settings.appearance': 'Darstellung',
+ 'settings.language': 'Sprache',
+ 'settings.about': 'Über',
+ 'settings.version': 'Version',
+ 'settings.theme': 'Theme',
+ 'settings.theme.description': 'Wechseln Sie zwischen hellem und dunklem Modus',
+ 'settings.language.description': 'Wählen Sie Ihre bevorzugte Sprache',
+ 'settings.theme.light': 'Hell',
+ 'settings.theme.dark': 'Dunkel',
+ 'settings.theme.toggle.light': 'Zu hellem Modus wechseln',
+ 'settings.theme.toggle.dark': 'Zu dunklem Modus wechseln',
+
+ // Languages
+ 'language.german': 'Deutsch',
+ 'language.english': 'English',
+ 'language.french': 'Français',
+
+ // Common
+ 'common.loading': 'Laden...',
+ 'common.error': 'Fehler',
+ 'common.success': 'Erfolgreich',
+ 'common.cancel': 'Abbrechen',
+ 'common.save': 'Speichern',
+ 'common.delete': 'Löschen',
+ 'common.edit': 'Bearbeiten',
+ 'common.close': 'Schließen',
+
+ // Auth
+ 'auth.login': 'Anmelden',
+ 'auth.register': 'Registrieren',
+ 'auth.logout': 'Abmelden',
+ 'auth.email': 'E-Mail',
+ 'auth.password': 'Passwort',
+
+ // Dashboard
+ 'dashboard.prompt.template': 'Prompt Vorlage',
+ 'dashboard.prompt.settings': 'Einstellungen',
+ 'dashboard.chat.area': 'Chatbereich',
+ 'dashboard.chat.history': 'Workflow-Verlauf',
+ 'dashboard.log.title': 'Log',
+ 'dashboard.log.workflow': 'Workflow',
+ 'dashboard.log.no_workflow': 'Kein Workflow ausgewählt',
+ 'dashboard.log.loading': 'Logs werden geladen...',
+ 'dashboard.log.error': 'Fehler beim Laden der Logs',
+ 'dashboard.log.no_logs': 'Keine Logs für diesen Workflow verfügbar',
+ 'dashboard.log.waiting': 'Workflow läuft... Warte auf Logs...',
+ 'dashboard.log.fetch_failed': 'Logs konnten nicht geladen werden',
+ 'dashboard.log.level.info': 'INFO',
+
+ // Prompt Set
+ 'promptset.loading': 'Prompts werden geladen...',
+ 'promptset.error.loading': 'Fehler beim Laden der Prompts',
+ 'promptset.retry': 'Erneut versuchen',
+ 'promptset.new_prompt': 'Neuer Prompt',
+ 'promptset.prompt_count': 'Prompt',
+ 'promptset.prompt_count_plural': 'Prompts',
+ 'promptset.no_prompts': 'Keine Prompts verfügbar',
+ 'promptset.created': 'Erstellt',
+ 'promptset.run_tooltip': 'Prompt ausführen',
+ 'promptset.share_tooltip': 'Prompt teilen',
+ 'promptset.delete_tooltip': 'Prompt löschen',
+ 'promptset.confirm_delete': 'Klicken Sie erneut zum Bestätigen',
+ 'promptset.deleting': 'Löschen...',
+ 'promptset.confirm_click': 'Zum Bestätigen klicken',
+ 'promptset.delete_error': 'Fehler beim Löschen',
+ 'promptset.deleting_message': 'Prompt wird gelöscht...',
+
+ // Connections
+ 'connections.title': 'Verbindungen',
+ 'connections.connect_google': 'Google verbinden',
+ 'connections.connect_microsoft': 'Microsoft verbinden',
+ 'connections.edit_connection_title': '{authority} Verbindung bearbeiten',
+ 'connections.update_connection': 'Verbindung aktualisieren',
+ 'connections.service_connections': 'Service-Verbindungen',
+ 'connections.error': 'Fehler',
+ 'connections.connection_error': 'Verbindungsfehler',
+ 'connections.disconnect_error': 'Trennungsfehler',
+ 'connections.unknown': 'Unbekannt',
+ 'connections.not_available': 'Nicht verfügbar',
+ 'connections.invalid_date': 'Ungültiges Datum',
+ 'connections.confirm_delete': 'Sind Sie sicher, dass Sie die {service} Verbindung löschen möchten?',
+
+ // Connection Fields
+ 'connections.field.service': 'Service',
+ 'connections.field.status': 'Status',
+ 'connections.field.external_username': 'Externer Benutzername',
+ 'connections.field.external_email': 'Externe E-Mail',
+ 'connections.field.connected_at': 'Verbunden am',
+ 'connections.field.last_checked': 'Zuletzt geprüft',
+ 'connections.field.expires_at': 'Läuft ab am',
+
+ // Connection Services
+ 'connections.service.google': 'Google',
+ 'connections.service.microsoft': 'Microsoft',
+ 'connections.service.local': 'Lokal',
+
+ // Connection Placeholders
+ 'connections.placeholder.external_username': 'Externen Benutzernamen eingeben',
+ 'connections.placeholder.external_email': 'Externe E-Mail-Adresse eingeben',
+
+ // Connection Actions
+ 'connections.action.edit': 'Bearbeiten',
+ 'connections.action.toggle_connection': 'Verbindung umschalten',
+ 'connections.action.delete': 'Löschen',
+
+ // Prompt Modal
+ 'modal.create_prompt': 'Neuen Prompt erstellen',
+ 'modal.name_required': 'Name ist erforderlich',
+ 'modal.content_required': 'Inhalt ist erforderlich',
+ 'modal.create_error': 'Fehler beim Erstellen des Prompts',
+ 'modal.name_label': 'Name',
+ 'modal.content_label': 'Inhalt',
+ 'modal.name_placeholder': 'Geben Sie einen Namen für den Prompt ein',
+ 'modal.content_placeholder': 'Geben Sie den Inhalt des Prompts ein',
+ 'modal.cancel': 'Abbrechen',
+ 'modal.creating': 'Erstellen...',
+ 'modal.create': 'Prompt erstellen',
+
+ // Share Modal
+ 'share_modal.title': 'Prompt teilen',
+ 'share_modal.select_users': 'Benutzer auswählen',
+ 'share_modal.select_all': 'Alle auswählen',
+ 'share_modal.deselect_all': 'Alle abwählen',
+ 'share_modal.loading_users': 'Benutzer werden geladen...',
+ 'share_modal.error_loading_users': 'Fehler beim Laden der Benutzer',
+ 'share_modal.no_users_available': 'Keine Benutzer verfügbar',
+ 'share_modal.no_users_selected': 'Bitte wählen Sie mindestens einen Benutzer aus',
+ 'share_modal.one_user_selected': '1 Benutzer ausgewählt',
+ 'share_modal.multiple_users_selected': '{count} Benutzer ausgewählt',
+ 'share_modal.custom_title': 'Benutzerdefinierter Titel (optional)',
+ 'share_modal.title_placeholder': 'Geben Sie einen benutzerdefinierten Titel ein',
+ 'share_modal.message': 'Nachricht (optional)',
+ 'share_modal.message_placeholder': 'Fügen Sie eine Nachricht für die Empfänger hinzu',
+ 'share_modal.share': 'Teilen',
+ 'share_modal.sharing': 'Wird geteilt...',
+ 'share_modal.share_error': 'Fehler beim Teilen des Prompts',
+
+ // Prompt Settings
+ 'prompt_settings.title': 'Prompt Einstellungen',
+ 'prompt_settings.content_placeholder': 'Einstellungen werden in zukünftigen Updates hinzugefügt.',
+
+ // Chat Area
+ 'chat.continue_conversation': 'Gespräch fortsetzen...',
+ 'chat.enter_message': 'Nachricht eingeben...',
+ 'chat.remove_file': 'Datei entfernen',
+ 'chat.attach_file': 'Datei anhängen',
+ 'chat.you': 'You',
+ 'chat.click_to_open': 'Klicken Sie, um zu öffnen',
+ 'chat.preview_document': 'Dokument vorschauen',
+ 'chat.download_document': 'Dokument herunterladen',
+ 'chat.workflow_failed': 'Workflow fehlgeschlagen.',
+ 'chat.retry_workflow': 'Nochmal versuchen',
+ 'chat.sending_followup': 'Folgenachricht wird gesendet...',
+ 'chat.sending_message': 'Nachricht wird gesendet...',
+ 'chat.error_prefix': 'Fehler:',
+ 'chat.error_loading_messages': 'Fehler beim Laden der Nachrichten:',
+ 'chat.loading_workflow_messages': 'Workflow-Nachrichten werden geladen...',
+ 'chat.start_conversation': 'Beginne ein Gespräch, indem du eine Nachricht eingibst, eine Vorlage auswählst oder einen vorherigen Workflow fortsetzt …',
+
+ // File Preview
+ 'file_preview.loading': 'Vorschau wird geladen...',
+ 'file_preview.error': 'Fehler',
+ 'file_preview.no_preview': 'Keine Vorschau verfügbar',
+ 'file_preview.close_preview': 'Vorschau schließen',
+ 'file_preview.python': 'Python',
+
+ // Chat History
+ 'chat_history.loading': 'Workflows werden geladen...',
+ 'chat_history.error_loading': 'Fehler beim Laden der Workflows:',
+ 'chat_history.try_again': 'Nochmal versuchen',
+ 'chat_history.title': 'Workflow-Verlauf',
+ 'chat_history.workflow_count': 'Workflow',
+ 'chat_history.workflow_count_plural': 'Workflows',
+ 'chat_history.empty_state': 'Keine Workflows verfügbar',
+ 'chat_history.confirm_delete': 'Sind Sie sicher, dass Sie Workflow "{id}..." löschen möchten?',
+ 'chat_history.no_message_content': 'Kein Nachrichteninhalt verfügbar',
+ 'chat_history.unknown_date': 'Unbekanntes Datum',
+ 'chat_history.invalid_date': 'Ungültiges Datum',
+ 'chat_history.started': 'Gestartet:',
+ 'chat_history.last_activity': 'Letzte Aktivität:',
+ 'chat_history.round': 'Runde',
+ 'chat_history.resume_tooltip': 'Workflow fortsetzen',
+ 'chat_history.delete_tooltip': 'Workflow löschen',
+ 'chat_history.deleting': 'Workflow wird gelöscht...',
+
+ // Workflow Status
+ 'status.error': 'FEHLER',
+ 'status.failed': 'FEHLGESCHLAGEN',
+ 'status.stopped': 'GESTOPPT',
+ 'status.cancelled': 'ABGEBROCHEN',
+ 'status.running': 'LÄUFT',
+ 'status.processing': 'VERARBEITUNG',
+ 'status.completed': 'ABGESCHLOSSEN',
+ 'status.pending': 'WARTEND',
+
+ // Files
+ 'files.unknown_size': 'Unbekannte Größe',
+ 'files.unknown_date': 'Unbekanntes Datum',
+ 'files.source.uploaded': 'Hochgeladen',
+ 'files.source.ai_created': 'KI-erstellt',
+ 'files.source.shared': 'Geteilt',
+ 'files.source.unknown': 'Unbekannt',
+ 'files.preview_tooltip': 'Datei vorschauen',
+ 'files.download_tooltip': 'Datei herunterladen',
+ 'files.delete_tooltip': 'Datei löschen',
+ 'files.delete_confirm_tooltip': 'Klicken Sie erneut zum Bestätigen der Löschung',
+ 'files.downloading': 'Laden...',
+ 'files.deleting': 'Löschen...',
+ 'files.delete_confirm': 'Zum Bestätigen klicken...',
+ 'files.no_files': 'Keine Dateien gefunden.',
+ 'files.no_shared_files': 'Keine mit Ihnen geteilten Dateien gefunden.',
+ 'files.no_ai_files': 'Keine von der KI erstellten Dateien gefunden.',
+ 'files.no_uploaded_files': 'Keine hochgeladenen Dateien gefunden.',
+ 'files.header.name': 'Name',
+ 'files.header.type': 'Typ',
+ 'files.header.size': 'Größe',
+ 'files.header.date': 'Datum',
+ 'files.selector.title': 'Dateien auswählen',
+ 'files.selector.tab.all': 'Alle Dateien',
+ 'files.selector.tab.uploads': 'Hochgeladen',
+ 'files.selector.tab.created': 'KI-erstellt',
+ 'files.selector.tab.shared': 'Geteilt',
+ 'files.selector.select_all': 'Alle auswählen',
+ 'files.selector.deselect_all': 'Alle abwählen',
+ 'files.selector.file_selected': 'Datei',
+ 'files.selector.files_selected': 'Dateien',
+ 'files.selector.selected_suffix': 'ausgewählt',
+ 'files.selector.upload_new': 'Neue Datei hochladen',
+ 'files.selector.loading': 'Dateien werden geladen...',
+ 'files.selector.error_loading': 'Fehler beim Laden der Dateien:',
+ 'files.upload.title': 'Datei hochladen',
+ 'files.upload.drop_here': 'Datei hier ablegen...',
+ 'files.upload.uploading': 'Lädt hoch...',
+ 'files.upload.drag_files': 'Dateien hierher ziehen',
+ 'files.upload.or': 'oder',
+ 'files.upload.browse': 'Durchsuchen',
+ 'files.upload.selected_file': 'Ausgewählte Datei:',
+ 'files.upload.upload_button': 'Hochladen',
+ 'files.upload.uploading_button': 'Wird hochgeladen...',
+ 'files.upload.success': 'Datei erfolgreich hochgeladen!',
+ 'files.upload.error': 'Beim Hochladen ist ein Fehler aufgetreten.',
+ 'files.upload.unexpected_error': 'Beim Hochladen ist ein unerwarteter Fehler aufgetreten.',
+
+ // Files Page
+ 'files.page.tab.all': 'Alle Dateien',
+ 'files.page.tab.uploads': 'Meine Uploads',
+ 'files.page.tab.created': 'Erstellte Dateien',
+ 'files.page.tab.shared': 'Geteilte Dateien',
+ 'files.page.add_file': 'Datei hinzufügen',
+ 'files.page.loading': 'Dateien werden geladen...',
+ 'files.page.error': 'Fehler:',
+};
\ No newline at end of file
diff --git a/src/locales/en.ts b/src/locales/en.ts
new file mode 100644
index 0000000..83ab5c6
--- /dev/null
+++ b/src/locales/en.ts
@@ -0,0 +1,264 @@
+export default {
+ // Navigation
+ 'nav.dashboard': 'Dashboard',
+ 'nav.files': 'Files',
+ 'nav.team': 'Team Area',
+ 'nav.workflows': 'Workflows',
+ 'nav.connections': 'Connections',
+ 'nav.settings': 'Settings',
+
+ // Settings page
+ 'settings.title': 'Settings',
+ 'settings.appearance': 'Appearance',
+ 'settings.language': 'Language',
+ 'settings.about': 'About',
+ 'settings.version': 'Version',
+ 'settings.theme': 'Theme',
+ 'settings.theme.description': 'Switch between light and dark mode',
+ 'settings.language.description': 'Choose your preferred language',
+ 'settings.theme.light': 'Light',
+ 'settings.theme.dark': 'Dark',
+ 'settings.theme.toggle.light': 'Switch to light mode',
+ 'settings.theme.toggle.dark': 'Switch to dark mode',
+
+ // Languages
+ 'language.german': 'Deutsch',
+ 'language.english': 'English',
+ 'language.french': 'Français',
+
+ // Common
+ 'common.loading': 'Loading...',
+ 'common.error': 'Error',
+ 'common.success': 'Success',
+ 'common.cancel': 'Cancel',
+ 'common.save': 'Save',
+ 'common.delete': 'Delete',
+ 'common.edit': 'Edit',
+ 'common.close': 'Close',
+
+ // Auth
+ 'auth.login': 'Login',
+ 'auth.register': 'Register',
+ 'auth.logout': 'Logout',
+ 'auth.email': 'Email',
+ 'auth.password': 'Password',
+
+ // Dashboard
+ 'dashboard.prompt.template': 'Prompt Template',
+ 'dashboard.prompt.settings': 'Settings',
+ 'dashboard.chat.area': 'Chat Area',
+ 'dashboard.chat.history': 'Workflow History',
+ 'dashboard.log.title': 'Log',
+ 'dashboard.log.workflow': 'Workflow',
+ 'dashboard.log.no_workflow': 'No workflow selected',
+ 'dashboard.log.loading': 'Loading logs...',
+ 'dashboard.log.error': 'Error loading logs',
+ 'dashboard.log.no_logs': 'No logs available for this workflow',
+ 'dashboard.log.waiting': 'Workflow running... Waiting for logs...',
+ 'dashboard.log.fetch_failed': 'Failed to fetch logs',
+ 'dashboard.log.level.info': 'INFO',
+
+ // Prompt Set
+ 'promptset.loading': 'Loading prompts...',
+ 'promptset.error.loading': 'Error loading prompts',
+ 'promptset.retry': 'Try again',
+ 'promptset.new_prompt': 'New Prompt',
+ 'promptset.prompt_count': 'Prompt',
+ 'promptset.prompt_count_plural': 'Prompts',
+ 'promptset.no_prompts': 'No prompts available',
+ 'promptset.created': 'Created',
+ 'promptset.run_tooltip': 'Run prompt',
+ 'promptset.share_tooltip': 'Share prompt',
+ 'promptset.delete_tooltip': 'Delete prompt',
+ 'promptset.confirm_delete': 'Click again to confirm',
+ 'promptset.deleting': 'Deleting...',
+ 'promptset.confirm_click': 'Click to confirm',
+ 'promptset.delete_error': 'Error deleting',
+ 'promptset.deleting_message': 'Deleting prompt...',
+
+ // Connections
+ 'connections.title': 'Connections',
+ 'connections.connect_google': 'Connect Google',
+ 'connections.connect_microsoft': 'Connect Microsoft',
+ 'connections.edit_connection_title': 'Edit {authority} Connection',
+ 'connections.update_connection': 'Update Connection',
+ 'connections.service_connections': 'Service Connections',
+ 'connections.error': 'Error',
+ 'connections.connection_error': 'Connection Error',
+ 'connections.disconnect_error': 'Disconnect Error',
+ 'connections.unknown': 'Unknown',
+ 'connections.not_available': 'N/A',
+ 'connections.invalid_date': 'Invalid Date',
+ 'connections.confirm_delete': 'Are you sure you want to delete the {service} connection?',
+
+ // Connection Fields
+ 'connections.field.service': 'Service',
+ 'connections.field.status': 'Status',
+ 'connections.field.external_username': 'External Username',
+ 'connections.field.external_email': 'External Email',
+ 'connections.field.connected_at': 'Connected At',
+ 'connections.field.last_checked': 'Last Checked',
+ 'connections.field.expires_at': 'Expires At',
+
+ // Connection Services
+ 'connections.service.google': 'Google',
+ 'connections.service.microsoft': 'Microsoft',
+ 'connections.service.local': 'Local',
+
+ // Connection Placeholders
+ 'connections.placeholder.external_username': 'Enter external username',
+ 'connections.placeholder.external_email': 'Enter external email address',
+
+ // Connection Actions
+ 'connections.action.edit': 'Edit',
+ 'connections.action.toggle_connection': 'Toggle Connection',
+ 'connections.action.delete': 'Delete',
+
+
+ // Prompt Modal
+ 'modal.create_prompt': 'Create New Prompt',
+ 'modal.name_required': 'Name is required',
+ 'modal.content_required': 'Content is required',
+ 'modal.create_error': 'Error creating prompt',
+ 'modal.name_label': 'Name',
+ 'modal.content_label': 'Content',
+ 'modal.name_placeholder': 'Enter a name for the prompt',
+ 'modal.content_placeholder': 'Enter the prompt content',
+ 'modal.cancel': 'Cancel',
+ 'modal.creating': 'Creating...',
+ 'modal.create': 'Create Prompt',
+
+ // Share Modal
+ 'share_modal.title': 'Share Prompt',
+ 'share_modal.select_users': 'Select Users',
+ 'share_modal.select_all': 'Select All',
+ 'share_modal.deselect_all': 'Deselect All',
+ 'share_modal.loading_users': 'Loading users...',
+ 'share_modal.error_loading_users': 'Error loading users',
+ 'share_modal.no_users_available': 'No users available',
+ 'share_modal.no_users_selected': 'Please select at least one user',
+ 'share_modal.one_user_selected': '1 user selected',
+ 'share_modal.multiple_users_selected': '{count} users selected',
+ 'share_modal.custom_title': 'Custom Title (optional)',
+ 'share_modal.title_placeholder': 'Enter a custom title',
+ 'share_modal.message': 'Message (optional)',
+ 'share_modal.message_placeholder': 'Add a message for recipients',
+ 'share_modal.share': 'Share',
+ 'share_modal.sharing': 'Sharing...',
+ 'share_modal.share_error': 'Error sharing prompt',
+
+ // Prompt Settings
+ 'prompt_settings.title': 'Prompt Settings',
+ 'prompt_settings.content_placeholder': 'Settings content will be added here in future updates.',
+
+ // Chat Area
+ 'chat.continue_conversation': 'Continue conversation...',
+ 'chat.enter_message': 'Enter message...',
+ 'chat.remove_file': 'Remove file',
+ 'chat.attach_file': 'Attach file',
+ 'chat.you': 'You',
+ 'chat.click_to_open': 'Click to open',
+ 'chat.preview_document': 'Preview document',
+ 'chat.download_document': 'Download document',
+ 'chat.workflow_failed': 'Workflow failed.',
+ 'chat.retry_workflow': 'Try again',
+ 'chat.sending_followup': 'Sending follow-up message...',
+ 'chat.sending_message': 'Sending message...',
+ 'chat.error_prefix': 'Error:',
+ 'chat.error_loading_messages': 'Error loading messages:',
+ 'chat.loading_workflow_messages': 'Loading workflow messages...',
+ 'chat.start_conversation': 'Start a conversation by entering a message, selecting a template, or continuing a previous workflow...',
+
+ // File Preview
+ 'file_preview.loading': 'Loading preview...',
+ 'file_preview.error': 'Error',
+ 'file_preview.no_preview': 'No preview available',
+ 'file_preview.close_preview': 'Close preview',
+ 'file_preview.python': 'Python',
+
+ // Chat History
+ 'chat_history.loading': 'Loading workflows...',
+ 'chat_history.error_loading': 'Error loading workflows:',
+ 'chat_history.try_again': 'Try Again',
+ 'chat_history.title': 'Workflow History',
+ 'chat_history.workflow_count': 'Workflow',
+ 'chat_history.workflow_count_plural': 'Workflows',
+ 'chat_history.empty_state': 'No workflows available',
+ 'chat_history.confirm_delete': 'Are you sure you want to delete workflow "{id}..."?',
+ 'chat_history.no_message_content': 'No message content available',
+ 'chat_history.unknown_date': 'Unknown date',
+ 'chat_history.invalid_date': 'Invalid date',
+ 'chat_history.started': 'Started:',
+ 'chat_history.last_activity': 'Last Activity:',
+ 'chat_history.round': 'Round',
+ 'chat_history.resume_tooltip': 'Resume workflow',
+ 'chat_history.delete_tooltip': 'Delete workflow',
+ 'chat_history.deleting': 'Deleting workflow...',
+
+ // Workflow Status
+ 'status.error': 'ERROR',
+ 'status.failed': 'FAILED',
+ 'status.stopped': 'STOPPED',
+ 'status.cancelled': 'CANCELLED',
+ 'status.running': 'RUNNING',
+ 'status.processing': 'PROCESSING',
+ 'status.completed': 'COMPLETED',
+ 'status.pending': 'PENDING',
+
+ // Files
+ 'files.unknown_size': 'Unknown Size',
+ 'files.unknown_date': 'Unknown Date',
+ 'files.source.uploaded': 'Uploaded',
+ 'files.source.ai_created': 'AI-created',
+ 'files.source.shared': 'Shared',
+ 'files.source.unknown': 'Unknown',
+ 'files.preview_tooltip': 'Preview file',
+ 'files.download_tooltip': 'Download file',
+ 'files.delete_tooltip': 'Delete file',
+ 'files.delete_confirm_tooltip': 'Click again to confirm deletion',
+ 'files.downloading': 'Downloading...',
+ 'files.deleting': 'Deleting...',
+ 'files.delete_confirm': 'Click to confirm...',
+ 'files.no_files': 'No files found.',
+ 'files.no_shared_files': 'No shared files found.',
+ 'files.no_ai_files': 'No AI-created files found.',
+ 'files.no_uploaded_files': 'No uploaded files found.',
+ 'files.header.name': 'Name',
+ 'files.header.type': 'Type',
+ 'files.header.size': 'Size',
+ 'files.header.date': 'Date',
+ 'files.selector.title': 'Select files',
+ 'files.selector.tab.all': 'All files',
+ 'files.selector.tab.uploads': 'Uploaded',
+ 'files.selector.tab.created': 'AI-created',
+ 'files.selector.tab.shared': 'Shared',
+ 'files.selector.select_all': 'Select all',
+ 'files.selector.deselect_all': 'Deselect all',
+ 'files.selector.file_selected': 'File',
+ 'files.selector.files_selected': 'Files',
+ 'files.selector.selected_suffix': 'selected',
+ 'files.selector.upload_new': 'Upload new file',
+ 'files.selector.loading': 'Loading files...',
+ 'files.selector.error_loading': 'Error loading files:',
+ 'files.upload.title': 'Upload file',
+ 'files.upload.drop_here': 'Drop file here...',
+ 'files.upload.uploading': 'Uploading...',
+ 'files.upload.drag_files': 'Drag files here',
+ 'files.upload.or': 'or',
+ 'files.upload.browse': 'Browse',
+ 'files.upload.selected_file': 'Selected file:',
+ 'files.upload.upload_button': 'Upload',
+ 'files.upload.uploading_button': 'Uploading...',
+ 'files.upload.success': 'File uploaded successfully!',
+ 'files.upload.error': 'An error occurred while uploading.',
+ 'files.upload.unexpected_error': 'An unexpected error occurred while uploading.',
+
+ // Files Page
+ 'files.page.tab.all': 'All Files',
+ 'files.page.tab.uploads': 'My Uploads',
+ 'files.page.tab.created': 'Created Files',
+ 'files.page.tab.shared': 'Shared Files',
+ 'files.page.add_file': 'Add File',
+ 'files.page.loading': 'Loading files...',
+ 'files.page.error': 'Error:',
+};
\ No newline at end of file
diff --git a/src/locales/fr.ts b/src/locales/fr.ts
new file mode 100644
index 0000000..a5b077f
--- /dev/null
+++ b/src/locales/fr.ts
@@ -0,0 +1,263 @@
+export default {
+ // Navigation
+ 'nav.dashboard': 'Centre d\'activité',
+ 'nav.files': 'Fichiers',
+ 'nav.team': 'Espace équipe',
+ 'nav.workflows': 'Workflows',
+ 'nav.connections': 'Connections',
+ 'nav.settings': 'Paramètres',
+
+ // Settings page
+ 'settings.title': 'Paramètres',
+ 'settings.appearance': 'Apparence',
+ 'settings.language': 'Langue',
+ 'settings.about': 'À propos',
+ 'settings.version': 'Version',
+ 'settings.theme': 'Thème',
+ 'settings.theme.description': 'Basculer entre le mode clair et sombre',
+ 'settings.language.description': 'Choisissez votre langue préférée',
+ 'settings.theme.light': 'Clair',
+ 'settings.theme.dark': 'Sombre',
+ 'settings.theme.toggle.light': 'Passer en mode clair',
+ 'settings.theme.toggle.dark': 'Passer en mode sombre',
+
+ // Languages
+ 'language.german': 'Deutsch',
+ 'language.english': 'English',
+ 'language.french': 'Français',
+
+ // Common
+ 'common.loading': 'Chargement...',
+ 'common.error': 'Erreur',
+ 'common.success': 'Succès',
+ 'common.cancel': 'Annuler',
+ 'common.save': 'Enregistrer',
+ 'common.delete': 'Supprimer',
+ 'common.edit': 'Modifier',
+ 'common.close': 'Fermer',
+
+ // Auth
+ 'auth.login': 'Se connecter',
+ 'auth.register': 'S\'inscrire',
+ 'auth.logout': 'Se déconnecter',
+ 'auth.email': 'E-mail',
+ 'auth.password': 'Mot de passe',
+
+ // Dashboard
+ 'dashboard.prompt.template': 'Modèle de prompt',
+ 'dashboard.prompt.settings': 'Paramètres',
+ 'dashboard.chat.area': 'Zone de chat',
+ 'dashboard.chat.history': 'Historique des workflows',
+ 'dashboard.log.title': 'Journal',
+ 'dashboard.log.workflow': 'Workflow',
+ 'dashboard.log.no_workflow': 'Aucun workflow sélectionné',
+ 'dashboard.log.loading': 'Chargement des logs...',
+ 'dashboard.log.error': 'Erreur lors du chargement des logs',
+ 'dashboard.log.no_logs': 'Aucun log disponible pour ce workflow',
+ 'dashboard.log.waiting': 'Workflow en cours... En attente des logs...',
+ 'dashboard.log.fetch_failed': 'Échec du chargement des logs',
+ 'dashboard.log.level.info': 'INFO',
+
+ // Prompt Set
+ 'promptset.loading': 'Chargement des prompts...',
+ 'promptset.error.loading': 'Erreur lors du chargement des prompts',
+ 'promptset.retry': 'Réessayer',
+ 'promptset.new_prompt': 'Nouveau prompt',
+ 'promptset.prompt_count': 'Prompt',
+ 'promptset.prompt_count_plural': 'Prompts',
+ 'promptset.no_prompts': 'Aucun prompt disponible',
+ 'promptset.created': 'Créé',
+ 'promptset.run_tooltip': 'Exécuter le prompt',
+ 'promptset.share_tooltip': 'Partager le prompt',
+ 'promptset.delete_tooltip': 'Supprimer le prompt',
+ 'promptset.confirm_delete': 'Cliquez à nouveau pour confirmer',
+ 'promptset.deleting': 'Suppression...',
+ 'promptset.confirm_click': 'Cliquez pour confirmer',
+ 'promptset.delete_error': 'Erreur lors de la suppression',
+ 'promptset.deleting_message': 'Suppression du prompt...',
+
+ // Connections
+ 'connections.title': 'Connexions',
+ 'connections.connect_google': 'Connecter Google',
+ 'connections.connect_microsoft': 'Connecter Microsoft',
+ 'connections.edit_connection_title': 'Modifier la connexion {authority}',
+ 'connections.update_connection': 'Mettre à jour la connexion',
+ 'connections.service_connections': 'Connexions de service',
+ 'connections.error': 'Erreur',
+ 'connections.connection_error': 'Erreur de connexion',
+ 'connections.disconnect_error': 'Erreur de déconnexion',
+ 'connections.unknown': 'Inconnu',
+ 'connections.not_available': 'N/D',
+ 'connections.invalid_date': 'Date invalide',
+ 'connections.confirm_delete': 'Êtes-vous sûr de vouloir supprimer la connexion {service} ?',
+
+ // Connection Fields
+ 'connections.field.service': 'Service',
+ 'connections.field.status': 'Statut',
+ 'connections.field.external_username': 'Nom d\'utilisateur externe',
+ 'connections.field.external_email': 'E-mail externe',
+ 'connections.field.connected_at': 'Connecté le',
+ 'connections.field.last_checked': 'Dernière vérification',
+ 'connections.field.expires_at': 'Expire le',
+
+ // Connection Services
+ 'connections.service.google': 'Google',
+ 'connections.service.microsoft': 'Microsoft',
+ 'connections.service.local': 'Local',
+
+ // Connection Placeholders
+ 'connections.placeholder.external_username': 'Entrez le nom d\'utilisateur externe',
+ 'connections.placeholder.external_email': 'Entrez l\'adresse e-mail externe',
+
+ // Connection Actions
+ 'connections.action.edit': 'Modifier',
+ 'connections.action.toggle_connection': 'Basculer la connexion',
+ 'connections.action.delete': 'Supprimer',
+
+ // Prompt Modal
+ 'modal.create_prompt': 'Créer un nouveau prompt',
+ 'modal.name_required': 'Le nom est requis',
+ 'modal.content_required': 'Le contenu est requis',
+ 'modal.create_error': 'Erreur lors de la création du prompt',
+ 'modal.name_label': 'Nom',
+ 'modal.content_label': 'Contenu',
+ 'modal.name_placeholder': 'Entrez un nom pour le prompt',
+ 'modal.content_placeholder': 'Entrez le contenu du prompt',
+ 'modal.cancel': 'Annuler',
+ 'modal.creating': 'Création...',
+ 'modal.create': 'Créer le prompt',
+
+ // Share Modal
+ 'share_modal.title': 'Partager le prompt',
+ 'share_modal.select_users': 'Sélectionner les utilisateurs',
+ 'share_modal.select_all': 'Tout sélectionner',
+ 'share_modal.deselect_all': 'Tout désélectionner',
+ 'share_modal.loading_users': 'Chargement des utilisateurs...',
+ 'share_modal.error_loading_users': 'Erreur lors du chargement des utilisateurs',
+ 'share_modal.no_users_available': 'Aucun utilisateur disponible',
+ 'share_modal.no_users_selected': 'Veuillez sélectionner au moins un utilisateur',
+ 'share_modal.one_user_selected': '1 utilisateur sélectionné',
+ 'share_modal.multiple_users_selected': '{count} utilisateurs sélectionnés',
+ 'share_modal.custom_title': 'Titre personnalisé (facultatif)',
+ 'share_modal.title_placeholder': 'Entrez un titre personnalisé',
+ 'share_modal.message': 'Message (facultatif)',
+ 'share_modal.message_placeholder': 'Ajoutez un message pour les destinataires',
+ 'share_modal.share': 'Partager',
+ 'share_modal.sharing': 'Partage en cours...',
+ 'share_modal.share_error': 'Erreur lors du partage du prompt',
+
+ // Prompt Settings
+ 'prompt_settings.title': 'Paramètres de prompt',
+ 'prompt_settings.content_placeholder': 'Le contenu des paramètres sera ajouté dans les futures mises à jour.',
+
+ // Chat Area
+ 'chat.continue_conversation': 'Continuer la conversation...',
+ 'chat.enter_message': 'Entrez votre message...',
+ 'chat.remove_file': 'Supprimer le fichier',
+ 'chat.attach_file': 'Joindre un fichier',
+ 'chat.you': 'Vous',
+ 'chat.click_to_open': 'Cliquez pour ouvrir',
+ 'chat.preview_document': 'Aperçu du document',
+ 'chat.download_document': 'Télécharger le document',
+ 'chat.workflow_failed': 'Échec du workflow.',
+ 'chat.retry_workflow': 'Réessayer',
+ 'chat.sending_followup': 'Envoi du message de suivi...',
+ 'chat.sending_message': 'Envoi du message...',
+ 'chat.error_prefix': 'Erreur:',
+ 'chat.error_loading_messages': 'Erreur lors du chargement des messages:',
+ 'chat.loading_workflow_messages': 'Chargement des messages de workflow...',
+ 'chat.start_conversation': 'Commencez une conversation en entrant un message, en sélectionnant un modèle ou en continuant un workflow précédent...',
+
+ // File Preview
+ 'file_preview.loading': 'Chargement de l\'aperçu...',
+ 'file_preview.error': 'Erreur',
+ 'file_preview.no_preview': 'Aucun aperçu disponible',
+ 'file_preview.close_preview': 'Fermer l\'aperçu',
+ 'file_preview.python': 'Python',
+
+ // Chat History
+ 'chat_history.loading': 'Chargement des workflows...',
+ 'chat_history.error_loading': 'Erreur lors du chargement des workflows:',
+ 'chat_history.try_again': 'Réessayer',
+ 'chat_history.title': 'Historique des workflows',
+ 'chat_history.workflow_count': 'Workflow',
+ 'chat_history.workflow_count_plural': 'Workflows',
+ 'chat_history.empty_state': 'Aucun workflow disponible',
+ 'chat_history.confirm_delete': 'Êtes-vous sûr de vouloir supprimer le workflow "{id}..."?',
+ 'chat_history.no_message_content': 'Aucun contenu de message disponible',
+ 'chat_history.unknown_date': 'Date inconnue',
+ 'chat_history.invalid_date': 'Date invalide',
+ 'chat_history.started': 'Démarré:',
+ 'chat_history.last_activity': 'Dernière activité:',
+ 'chat_history.round': 'Tour',
+ 'chat_history.resume_tooltip': 'Reprendre le workflow',
+ 'chat_history.delete_tooltip': 'Supprimer le workflow',
+ 'chat_history.deleting': 'Suppression du workflow...',
+
+ // Workflow Status
+ 'status.error': 'ERREUR',
+ 'status.failed': 'ÉCHEC',
+ 'status.stopped': 'ARRÊTÉ',
+ 'status.cancelled': 'ANNULÉ',
+ 'status.running': 'EN COURS',
+ 'status.processing': 'TRAITEMENT',
+ 'status.completed': 'TERMINÉ',
+ 'status.pending': 'EN ATTENTE',
+
+ // Files
+ 'files.unknown_size': 'Taille inconnue',
+ 'files.unknown_date': 'Date inconnue',
+ 'files.source.uploaded': 'Téléchargé',
+ 'files.source.ai_created': 'Créé par IA',
+ 'files.source.shared': 'Partagé',
+ 'files.source.unknown': 'Inconnu',
+ 'files.preview_tooltip': 'Aperçu du fichier',
+ 'files.download_tooltip': 'Télécharger le fichier',
+ 'files.delete_tooltip': 'Supprimer le fichier',
+ 'files.delete_confirm_tooltip': 'Cliquez à nouveau pour confirmer la suppression',
+ 'files.downloading': 'Téléchargement...',
+ 'files.deleting': 'Suppression...',
+ 'files.delete_confirm': 'Cliquez pour confirmer...',
+ 'files.no_files': 'Aucun fichier trouvé.',
+ 'files.no_shared_files': 'Aucun fichier partagé trouvé.',
+ 'files.no_ai_files': 'Aucun fichier créé par IA trouvé.',
+ 'files.no_uploaded_files': 'Aucun fichier téléchargé trouvé.',
+ 'files.header.name': 'Nom',
+ 'files.header.type': 'Type',
+ 'files.header.size': 'Taille',
+ 'files.header.date': 'Date',
+ 'files.selector.title': 'Sélectionner des fichiers',
+ 'files.selector.tab.all': 'Tous les fichiers',
+ 'files.selector.tab.uploads': 'Téléchargés',
+ 'files.selector.tab.created': 'Créés par IA',
+ 'files.selector.tab.shared': 'Partagés',
+ 'files.selector.select_all': 'Tout sélectionner',
+ 'files.selector.deselect_all': 'Tout désélectionner',
+ 'files.selector.file_selected': 'Fichier',
+ 'files.selector.files_selected': 'Fichiers',
+ 'files.selector.selected_suffix': 'sélectionné(s)',
+ 'files.selector.upload_new': 'Télécharger un nouveau fichier',
+ 'files.selector.loading': 'Chargement des fichiers...',
+ 'files.selector.error_loading': 'Erreur lors du chargement des fichiers:',
+ 'files.upload.title': 'Télécharger un fichier',
+ 'files.upload.drop_here': 'Déposer le fichier ici...',
+ 'files.upload.uploading': 'Téléchargement...',
+ 'files.upload.drag_files': 'Glisser les fichiers ici',
+ 'files.upload.or': 'ou',
+ 'files.upload.browse': 'Parcourir',
+ 'files.upload.selected_file': 'Fichier sélectionné:',
+ 'files.upload.upload_button': 'Télécharger',
+ 'files.upload.uploading_button': 'Téléchargement...',
+ 'files.upload.success': 'Fichier téléchargé avec succès!',
+ 'files.upload.error': 'Une erreur s\'est produite lors du téléchargement.',
+ 'files.upload.unexpected_error': 'Une erreur inattendue s\'est produite lors du téléchargement.',
+
+ // Files Page
+ 'files.page.tab.all': 'Tous les fichiers',
+ 'files.page.tab.uploads': 'Mes téléchargements',
+ 'files.page.tab.created': 'Fichiers créés',
+ 'files.page.tab.shared': 'Fichiers partagés',
+ 'files.page.add_file': 'Ajouter un fichier',
+ 'files.page.loading': 'Chargement des fichiers...',
+ 'files.page.error': 'Erreur:',
+};
\ No newline at end of file
diff --git a/src/locales/index.ts b/src/locales/index.ts
new file mode 100644
index 0000000..96ceee4
--- /dev/null
+++ b/src/locales/index.ts
@@ -0,0 +1,37 @@
+import { Language, TranslationKeys } from './types';
+
+// Dynamic language loader
+export const loadLanguage = async (language: Language): Promise => {
+ try {
+ let translations: TranslationKeys;
+
+ switch (language) {
+ case 'de':
+ const de = await import('./de');
+ translations = de.default;
+ break;
+ case 'en':
+ const en = await import('./en');
+ translations = en.default;
+ break;
+ case 'fr':
+ const fr = await import('./fr');
+ translations = fr.default;
+ break;
+ default:
+ // Fallback to German if language not found
+ const fallback = await import('./de');
+ translations = fallback.default;
+ }
+
+ return translations;
+ } catch (error) {
+ console.error(`Failed to load language ${language}:`, error);
+ // Fallback to German in case of error
+ const fallback = await import('./de');
+ return fallback.default;
+ }
+};
+
+// Re-export types
+export type { Language, TranslationKeys } from './types';
\ No newline at end of file
diff --git a/src/locales/types.ts b/src/locales/types.ts
new file mode 100644
index 0000000..d208a4c
--- /dev/null
+++ b/src/locales/types.ts
@@ -0,0 +1,12 @@
+// Language type definition
+export type Language = 'de' | 'en' | 'fr';
+
+// Translation keys and their values
+export type TranslationKeys = {
+ [key: string]: string;
+};
+
+// Language loader interface
+export interface LanguageLoader {
+ loadLanguage: (language: Language) => Promise;
+}
\ No newline at end of file
diff --git a/src/machines/sidebarMachine.ts b/src/machines/sidebarMachine.ts
deleted file mode 100644
index a7de3a6..0000000
--- a/src/machines/sidebarMachine.ts
+++ /dev/null
@@ -1,102 +0,0 @@
-import { setup, assign } from 'xstate';
-
-export type SidebarEvent =
- | { type: 'TOGGLE_ITEM'; itemId: string }
- | { type: 'CLOSE_ALL' }
- | { type: 'NAVIGATE'; path: string }
- | { type: 'MINIMIZE_SIDEBAR' }
- | { type: 'EXPAND_SIDEBAR' };
-
-export interface SidebarContext {
- openItemId: string | null;
- activePath: string;
- isMinimized: boolean;
-}
-
-export const sidebarMachine = setup({
- types: {
- context: {} as SidebarContext,
- events: {} as SidebarEvent,
- },
-}).createMachine({
- id: 'sidebar',
- initial: 'collapsed',
- context: {
- openItemId: null,
- activePath: '/',
- isMinimized: false,
- },
- states: {
- collapsed: {
- on: {
- TOGGLE_ITEM: {
- guard: ({ context }) => !context.isMinimized,
- target: 'expanded',
- actions: assign({
- openItemId: ({ event }) => event.itemId,
- }),
- },
- CLOSE_ALL: {
- },
- },
- },
-
- expanded: {
- on: {
- TOGGLE_ITEM: [
- {
- guard: ({ context, event }) => !context.isMinimized && context.openItemId === event.itemId,
- target: 'collapsed',
- actions: assign({
- openItemId: null,
- }),
- },
- {
- guard: ({ context }) => !context.isMinimized,
- target: 'expanded',
- actions: assign({
- openItemId: ({ event }) => event.itemId,
- }),
- },
- ],
- CLOSE_ALL: {
- target: 'collapsed',
- actions: assign({
- openItemId: null,
- }),
- },
- },
- },
- },
-
- on: {
- NAVIGATE: {
- actions: assign({
- activePath: ({ event }) => event.path,
- }),
- },
- MINIMIZE_SIDEBAR: {
- actions: assign({
- isMinimized: true,
- openItemId: null, // Close any open submenu when minimizing
- }),
- },
- EXPAND_SIDEBAR: {
- actions: assign({
- isMinimized: false,
- }),
- },
- },
-});
-
-export const getSidebarState = (context: SidebarContext) => {
- return {
- hasOpenSubmenu: context.openItemId !== null,
- openItemId: context.openItemId,
- isItemOpen: (itemId: string) => context.openItemId === itemId,
- activePath: context.activePath,
- isMinimized: context.isMinimized,
- };
-};
-
-export type SidebarMachineState = ReturnType;
\ No newline at end of file
diff --git a/src/pages/Dateien/Dateien.module.css b/src/pages/Dateien/Dateien.module.css
deleted file mode 100644
index f74d101..0000000
--- a/src/pages/Dateien/Dateien.module.css
+++ /dev/null
@@ -1,123 +0,0 @@
-.dateienContainer {
- margin: 51px 49px 0 36px;
- display: flex;
- padding: 0px 30px 30px 30px;
- flex-direction: column;
- align-self: stretch;
- border-radius: 30px;
- background: var(--color-bg);
- position: relative;
- box-shadow: 0px 2px 6px 0px rgba(194, 194, 194, 0.10);
- max-height: calc(100vh - 100px);
- overflow: hidden;
- font-family: var(--font-family);
-}
-
-.horizontalLineLight {
- width: calc(100% + 60px);
- background-color: var(--color-gray-disabled);
- height: 1px;
- margin-left: -30px;
- margin-bottom: 0;
-
- flex-shrink: 0;
-}
-
-/* Combined Header with Tabs and Add Button */
-.combinedHeader {
- display: flex;
- justify-content: space-between;
- align-items: center;
- flex-shrink: 0;
- min-height: 62px;
-}
-
-.datei_hinzufügen_button {
- border-radius: 30px;
- background: var(--color-secondary);
- color: var(--color-bg);
- border: none;
- outline: none;
- text-align: left;
- padding-left: 20px;
- padding-right: 20px;
- padding-top: 10px;
- padding-bottom: 10px;
- display: flex;
- gap: 10px;
- align-items: center;
- flex-shrink: 0;
- transition: background-color 0.2s ease;
- font-family: var(--font-family);
-}
-
-.datei_hinzufügen_button:hover {
- cursor: pointer;
- background-color: var(--color-secondary-hover);
-}
-
-.add_icon {
- font-size: 16px;
-}
-
-/* Tab Navigation Styles */
-.tabButtonDiv {
- display: flex;
- gap: 12px;
- align-items: center;
- justify-content: flex-start;
- flex: 1;
-}
-
-.tabButtonWrapper {
- position: relative;
- display: flex;
- flex-direction: column;
- align-items: center;
-}
-
-.tabButton {
- background: transparent;
- border: none;
- outline: none;
- padding: 20px 0px;
- font-size: 14px;
- font-weight: 500;
- border-radius: 8px;
- cursor: pointer;
- transition: all 0.2s ease;
- white-space: nowrap;
- position: relative;
- font-family: var(--font-family);
-}
-
-.tabButtonActive {
- color: var(--color-text);
-}
-
-.tabButtonInactive {
- color: var(--color-gray);
-}
-
-.tabButtonInactive:hover {
- color: var(--color-text);
-}
-
-.tabUnderline {
- position: absolute;
- bottom: -2px;
- left: 0;
- height: 1px;
- background-color: var(--color-text);
- border-radius: 1px;
-}
-
-/* Content area */
-.contentArea {
- flex: 1;
- overflow-y: auto;
- min-height: 0;
- height: calc(100vh - 300px);
- display: flex;
- flex-direction: column;
-}
diff --git a/src/pages/Home/Connections.tsx b/src/pages/Home/Connections.tsx
new file mode 100644
index 0000000..17468b4
--- /dev/null
+++ b/src/pages/Home/Connections.tsx
@@ -0,0 +1,98 @@
+import React, { useState } from 'react';
+import styles from './HomeStyles/Connections.module.css';
+import sharedStyles from './HomeStyles/pages.module.css';
+import { IoIosLink } from 'react-icons/io';
+import {
+ ConnectionsTable,
+ ConnectionEditModal,
+ ConnectionsErrorDisplay,
+ useConnectionsLogic,
+ Connection
+} from '../../components/Connections';
+import { useLanguage } from '../../contexts/LanguageContext';
+
+function Connections() {
+ const { t } = useLanguage();
+
+ // Use the custom hook for all business logic
+ const {
+ connections,
+ isLoading,
+ isConnecting,
+ isDisconnecting,
+ error,
+ connectError,
+ disconnectError,
+ editPopupOpen,
+ editingConnection,
+ connectionColumns,
+ connectionEditFields,
+ tableActions,
+ handleCreateConnection,
+ handleSaveConnection,
+ handleCancelEdit
+ } = useConnectionsLogic();
+
+ // Local state for selected connections (if needed)
+ const [selectedConnections, setSelectedConnections] = useState([]);
+
+ return (
+
+
+ {/* Page Header */}
+
+
{t('connections.title')}
+
+ handleCreateConnection('google')}
+ disabled={isLoading || isConnecting || isDisconnecting}
+ >
+
+ {t('connections.connect_google')}
+
+ handleCreateConnection('msft')}
+ disabled={isLoading || isConnecting || isDisconnecting}
+ >
+
+ {t('connections.connect_microsoft')}
+
+
+
+
+
+
+
+ {/* Error Display */}
+
+
+ {/* Connections Table */}
+
+
+
+
+ {/* Edit Connection Modal */}
+
+
+ );
+}
+
+export default Connections;
\ No newline at end of file
diff --git a/src/pages/Dashboard.tsx b/src/pages/Home/Dashboard.tsx
similarity index 73%
rename from src/pages/Dashboard.tsx
rename to src/pages/Home/Dashboard.tsx
index ea16f18..48ba38a 100644
--- a/src/pages/Dashboard.tsx
+++ b/src/pages/Home/Dashboard.tsx
@@ -1,16 +1,12 @@
import React, { useState, useCallback, useMemo } from 'react';
-import DashboardPrompt from '../components/Dashboard/DashboardPrompt/DashboardPrompt';
-import DashboardChat from '../components/Dashboard/DashboardChat/DashboardChat';
-import DashboardLog from '../components/Dashboard/DashboardLog/DashboardLog';
-import { Prompt } from '../hooks/usePrompts';
-import styles from './Dashboard.module.css'
+import { Prompt } from '../../hooks/usePrompts';
+import styles from './HomeStyles/Dashboard.module.css'
+import DashboardChat from '../../components/Dashboard/DashboardChat/DashboardChat';
function Dashboard () {
const [isChatExpanded, setIsChatExpanded] = useState(false);
const [selectedPrompt, setSelectedPrompt] = useState(null);
const [isPromptAreaCollapsed, setIsPromptAreaCollapsed] = useState(false);
- const [currentWorkflowId, setCurrentWorkflowId] = useState(null);
- const [workflowCompleted, setWorkflowCompleted] = useState(false);
const handleChatToggleExpand = () => {
setIsChatExpanded(!isChatExpanded);
@@ -22,12 +18,14 @@ function Dashboard () {
};
const handleWorkflowIdChange = useCallback((workflowId: string | null) => {
- setCurrentWorkflowId(workflowId);
- // Reset completion status when workflow changes
- if (workflowId !== currentWorkflowId) {
- setWorkflowCompleted(false);
- }
- }, [currentWorkflowId]);
+ setCurrentWorkflowId(prevId => {
+ // Reset completion status when workflow changes
+ if (workflowId !== prevId) {
+ setWorkflowCompleted(false);
+ }
+ return workflowId;
+ });
+ }, []);
const handleWorkflowCompletedChange = useCallback((completed: boolean) => {
setWorkflowCompleted(completed);
@@ -64,3 +62,11 @@ function Dashboard () {
}
export default Dashboard;
+
+function setCurrentWorkflowId(arg0: (prevId: any) => string | null) {
+ throw new Error('Function not implemented.');
+}
+
+function setWorkflowCompleted(arg0: boolean) {
+ throw new Error('Function not implemented.');
+}
diff --git a/src/pages/Dateien/Dateien.tsx b/src/pages/Home/Dateien.tsx
similarity index 58%
rename from src/pages/Dateien/Dateien.tsx
rename to src/pages/Home/Dateien.tsx
index 36720a0..b41dbe6 100644
--- a/src/pages/Dateien/Dateien.tsx
+++ b/src/pages/Home/Dateien.tsx
@@ -1,4 +1,5 @@
-import styles from './Dateien.module.css'
+import styles from './HomeStyles/Dateien.module.css'
+import sharedStyles from './HomeStyles/pages.module.css'
import { IoAddCircleOutline } from "react-icons/io5";
import DateienUpload from '../../components/Dateien/DateienHinzufügen/DateienUploadTool';
import DateienAll from '../../components/Dateien/DateienAll';
@@ -73,53 +74,57 @@ function Dateien() {
};
return (
-
- {/* Combined Header with Tabs and Add Button */}
-
-
- {tabs.map((tab) => (
-
-
setActiveTab(tab.key)}
- whileHover={{ scale: 1.02 }}
- whileTap={{ scale: 0.98 }}
- >
- {tab.label}
-
-
- {activeTab === tab.key && (
-
- )}
-
-
- ))}
-
-
- setIsUploadOpen(true)}
- >
-
- {t('files.page.add_file', 'Add File')}
-
-
-
+
+
+
Dateien
+
-
+ {/* Combined Header with Tabs and Add Button */}
+
+
+ {tabs.map((tab) => (
+
+
setActiveTab(tab.key)}
+ whileHover={{ scale: 1.02 }}
+ whileTap={{ scale: 0.98 }}
+ >
+ {tab.label}
+
+
+ {activeTab === tab.key && (
+
+ )}
+
+
+ ))}
+
+
+ setIsUploadOpen(true)}
+ >
+
+ {t('files.page.add_file', 'Add File')}
+
+
+
+
+
)}
+
);
diff --git a/src/pages/Einstellungen/Einstellungen.tsx b/src/pages/Home/Einstellungen.tsx
similarity index 78%
rename from src/pages/Einstellungen/Einstellungen.tsx
rename to src/pages/Home/Einstellungen.tsx
index ff77b4c..e852c65 100644
--- a/src/pages/Einstellungen/Einstellungen.tsx
+++ b/src/pages/Home/Einstellungen.tsx
@@ -1,10 +1,11 @@
import React, { useState, useEffect } from 'react';
-import styles from './Einstellungen.module.css';
+import styles from './HomeStyles/Einstellungen.module.css';
+import sharedStyles from './HomeStyles/pages.module.css';
import { useLanguage, Language } from '../../contexts/LanguageContext';
function Einstellungen() {
const [isDarkMode, setIsDarkMode] = useState(false);
- const { currentLanguage, setLanguage, t } = useLanguage();
+ const { currentLanguage, setLanguage, t, isLoading } = useLanguage();
// Sync component state with current theme on mount
useEffect(() => {
@@ -31,6 +32,16 @@ function Einstellungen() {
localStorage.setItem('theme', newIsDarkMode ? 'dark' : 'light');
};
+ const handleLanguageChange = async (language: Language) => {
+ if (language === currentLanguage) return;
+
+ try {
+ await setLanguage(language);
+ } catch (error) {
+ console.error('Failed to change language:', error);
+ }
+ };
+
const getLanguageLabel = (lang: Language): string => {
switch (lang) {
case 'de': return t('language.german');
@@ -40,15 +51,25 @@ function Einstellungen() {
}
};
+ if (isLoading) {
+ return (
+
+
+
+ {t('common.loading')}
+
+
+
+ );
+ }
+
return (
-
-
-
-
{t('settings.title')}
-
-
-
{t('settings.appearance')}
-
+
+
+
{t('settings.title')}
+
+
+
{t('settings.theme')}
@@ -84,7 +105,7 @@ function Einstellungen() {
setLanguage(e.target.value as Language)}
+ onChange={(e) => handleLanguageChange(e.target.value as Language)}
aria-label={t('settings.language')}
>
{getLanguageLabel('de')}
@@ -105,8 +126,8 @@ function Einstellungen() {
-
- );
+
+);
}
export default Einstellungen;
\ No newline at end of file
diff --git a/src/pages/Home.tsx b/src/pages/Home/Home.tsx
similarity index 92%
rename from src/pages/Home.tsx
rename to src/pages/Home/Home.tsx
index 758890a..f6e2d2f 100644
--- a/src/pages/Home.tsx
+++ b/src/pages/Home/Home.tsx
@@ -1,9 +1,9 @@
import { useEffect } from 'react';
import { Outlet, useLocation } from 'react-router-dom';
-import styles from './Home.module.css'
+import styles from './HomeStyles/Home.module.css'
-import Sidebar from '../components/Sidebar';
+import Sidebar from '../../components/Sidebar';
import { AnimatePresence, motion } from "framer-motion";
diff --git a/src/pages/Home/HomeStyles/Connections.module.css b/src/pages/Home/HomeStyles/Connections.module.css
new file mode 100644
index 0000000..6fe72d7
--- /dev/null
+++ b/src/pages/Home/HomeStyles/Connections.module.css
@@ -0,0 +1,13 @@
+
+.connectionsTable {
+ width: 100%;
+}
+
+.errorMessage {
+ color: var(--color-red);
+ padding: 10px;
+ background-color: var(--color-red-hover);
+ border: 1px solid var(--color-red);
+ border-radius: 25px;
+ margin-bottom: 10px;
+}
diff --git a/src/pages/Dashboard.module.css b/src/pages/Home/HomeStyles/Dashboard.module.css
similarity index 100%
rename from src/pages/Dashboard.module.css
rename to src/pages/Home/HomeStyles/Dashboard.module.css
diff --git a/src/pages/Home/HomeStyles/Dateien.module.css b/src/pages/Home/HomeStyles/Dateien.module.css
new file mode 100644
index 0000000..03544dd
--- /dev/null
+++ b/src/pages/Home/HomeStyles/Dateien.module.css
@@ -0,0 +1,79 @@
+/* Dateien Page Styles
+ *
+ * This page now uses shared styles from pages.module.css for consistency.
+ * Only file management-specific styles should be defined here.
+ */
+
+/* Remove old styles - now using shared styles */
+/* .dateienContainer - now using sharedStyles.pageContainer + sharedStyles.pageCardWithContentPadding */
+/* .horizontalLineLight - now using sharedStyles.horizontalDivider */
+/* .datei_hinzufügen_button - now using sharedStyles.primaryButton */
+/* .add_icon - now using sharedStyles.buttonIcon */
+
+/* Dateien-specific header customization */
+.combinedHeader {
+ /* Additional styling for the header with tabs - extends sharedStyles.pageHeader */
+}
+
+/* Additional button customization if needed */
+.datei_hinzufügen_button {
+ /* Any Dateien-specific button customizations go here */
+}
+
+/* Tab Navigation Styles */
+.tabButtonDiv {
+ display: flex;
+ gap: 12px;
+ align-items: center;
+ justify-content: flex-start;
+ flex: 1;
+}
+
+.tabButtonWrapper {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.tabButton {
+ background: transparent;
+ border: none;
+ outline: none;
+ padding: 20px 0px;
+ font-size: 14px;
+ font-weight: 500;
+ border-radius: 8px;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ white-space: nowrap;
+ position: relative;
+ font-family: var(--font-family);
+}
+
+.tabButtonActive {
+ color: var(--color-text);
+}
+
+.tabButtonInactive {
+ color: var(--color-gray);
+}
+
+.tabButtonInactive:hover {
+ color: var(--color-text);
+}
+
+.tabUnderline {
+ position: absolute;
+ bottom: -2px;
+ left: 0;
+ height: 1px;
+ background-color: var(--color-text);
+ border-radius: 1px;
+}
+
+/* Content area customization */
+.contentArea {
+ /* Any Dateien-specific content area customizations go here */
+ /* Base styling now comes from sharedStyles.contentArea */
+}
diff --git a/src/pages/Einstellungen/Einstellungen.module.css b/src/pages/Home/HomeStyles/Einstellungen.module.css
similarity index 73%
rename from src/pages/Einstellungen/Einstellungen.module.css
rename to src/pages/Home/HomeStyles/Einstellungen.module.css
index 09e970f..8558f69 100644
--- a/src/pages/Einstellungen/Einstellungen.module.css
+++ b/src/pages/Home/HomeStyles/Einstellungen.module.css
@@ -1,42 +1,3 @@
-.einstellungenContainer {
- margin: 51px 49px 0 36px;
- display: flex;
- flex-direction: column;
- align-self: stretch;
- justify-content: top;
- max-height: calc(100vh - 100px);
- overflow: hidden;
- font-family: var(--font-family);
- width: 98%;
-}
-
-.contentWrapper {
- flex: 1;
- overflow-y: auto;
- padding: 0px 0;
-}
-
-.settingsCard {
- display: flex;
- padding: 30px;
- flex-direction: column;
- align-self: stretch;
- border-radius: 30px;
- background: var(--color-bg);
- position: relative;
- box-shadow: 0px 2px 6px 0px rgba(194, 194, 194, 0.10);
- width: 100%;
- margin: 0 auto;
- gap: 30px;
-}
-
-.title {
- font-size: 2rem;
- font-weight: 600;
- color: var(--color-text);
- margin: 0 0 20px 0;
- font-family: var(--font-family);
-}
.settingsSection {
display: flex;
@@ -44,15 +5,6 @@
gap: 20px;
}
-.sectionTitle {
- font-size: 1.25rem;
- font-weight: 500;
- color: var(--color-text);
- margin: 0;
- padding-bottom: 10px;
- border-bottom: 1px solid var(--color-gray-disabled);
- font-family: var(--font-family);
-}
.settingItem {
display: flex;
diff --git a/src/pages/Home.module.css b/src/pages/Home/HomeStyles/Home.module.css
similarity index 100%
rename from src/pages/Home.module.css
rename to src/pages/Home/HomeStyles/Home.module.css
diff --git a/src/pages/Home/HomeStyles/TeamBereich.module.css b/src/pages/Home/HomeStyles/TeamBereich.module.css
new file mode 100644
index 0000000..992083a
--- /dev/null
+++ b/src/pages/Home/HomeStyles/TeamBereich.module.css
@@ -0,0 +1,28 @@
+
+.membersList {
+ list-style: none;
+ padding: 0;
+ margin: 0; /* Custom top margin for spacing after divider */
+ width: 100%;
+ overflow-y: auto;
+}
+
+/* Keep specific height requirement for member list items */
+.membersList li {
+ display: flex;
+ align-items: center;
+ height: 60px; /* Specific height requirement for each member item */
+ padding: 0 16px;
+ border-bottom: 1px solid var(--color-gray-disabled);
+ font-size: 16px;
+ transition: background-color 0.2s ease;
+ color: var(--color-text);
+ font-family: var(--font-family);
+}
+
+.actions {
+ display: flex;
+ gap: 10px;
+ align-items: center;
+ justify-content: center;
+ }
\ No newline at end of file
diff --git a/src/pages/Home/HomeStyles/Workflows.module.css b/src/pages/Home/HomeStyles/Workflows.module.css
new file mode 100644
index 0000000..adcb8ff
--- /dev/null
+++ b/src/pages/Home/HomeStyles/Workflows.module.css
@@ -0,0 +1,16 @@
+/* Workflows Page Styles
+ *
+ * This page now uses shared styles from pages.module.css for consistency.
+ * Only workflow-specific styles should be defined here.
+ */
+
+/* Remove old .workflowsContainer - now using sharedStyles.pageContainer + sharedStyles.pageCard */
+
+/* Workflow-specific styles go here */
+.workflowItem {
+ /* Future workflow item styling */
+}
+
+.workflowActions {
+ /* Future workflow action styling */
+}
diff --git a/src/pages/Home/HomeStyles/pages.module.css b/src/pages/Home/HomeStyles/pages.module.css
new file mode 100644
index 0000000..3286333
--- /dev/null
+++ b/src/pages/Home/HomeStyles/pages.module.css
@@ -0,0 +1,146 @@
+
+.pageContainer {
+ display: flex;
+ flex-direction: column;
+ align-self: top;
+ height: calc(100vh);
+ overflow: hidden;
+ font-family: var(--font-family);
+}
+
+/* Content wrapper for scrollable content */
+.contentWrapper {
+ flex: 1;
+ overflow-y: auto;
+ padding: 0;
+}
+
+/* Card-style container with background and shadow */
+.pageCard {
+ display: flex;
+ padding: 25px;
+ flex-direction: column;
+ align-self: top;
+ background: var(--color-bg);
+ box-shadow: 0px 2px 6px 0px rgba(194, 194, 194, 0.30);
+ gap: 20px;
+ height: 100%;
+}
+
+/* Page headers with consistent spacing */
+.pageHeader {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex-shrink: 0;
+ min-height: 62px;
+ gap: 30px;
+}
+
+/* Page titles */
+.pageTitle {
+ font-size: 1.5rem;
+ font-weight: 400;
+ color: var(--color-text);
+ margin: 0;
+ font-family: var(--font-family);
+
+}
+
+/* Common button styles */
+.primaryButton {
+ border-radius: 30px;
+ background: var(--color-secondary);
+ color: var(--color-bg);
+ border: none;
+ outline: none;
+ padding: 10px 20px;
+ display: flex;
+ gap: 10px;
+ align-items: center;
+ flex-shrink: 0;
+ transition: background-color 0.2s ease;
+ font-family: var(--font-family);
+ cursor: pointer;
+
+}
+
+.primaryButton:hover {
+ background-color: var(--color-secondary-hover);
+}
+
+.secondaryButton {
+ border-radius: 30px;
+ background: var(--color-gray-disabled);
+ color: var(--color-text);
+ border: none;
+ outline: none;
+ padding: 10px 20px;
+ display: flex;
+ gap: 10px;
+ align-items: center;
+ flex-shrink: 0;
+ transition: background-color 0.2s ease;
+ font-family: var(--font-family);
+ cursor: pointer;
+}
+
+.secondaryButton:hover {
+ background-color: var(--color-gray);
+}
+
+/* Common icon styles for buttons */
+.buttonIcon {
+ font-size: 16px;
+}
+
+/* Horizontal divider lines */
+.horizontalDivider {
+ width: calc(100% + 60px);
+ background-color: var(--color-primary);
+ height: 1px;
+ margin-left: -30px;
+ margin-bottom: 0;
+ flex-shrink: 0;
+}
+
+/* Content areas */
+.contentArea {
+ min-height: 0;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+
+}
+
+.scrollableContent {
+ overflow-y: auto;
+ flex: 1;
+ min-height: 0;
+}
+
+
+/* Responsive design for smaller screens */
+@media (max-width: 768px) {
+ .pageContainer {
+ margin: 10px;
+ height: calc(100vh - 20px);
+ max-height: calc(100vh - 20px);
+ }
+
+ .pageCard,
+ .pageCardWithContentPadding {
+ padding: 20px;
+ }
+
+ .pageHeader {
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 15px;
+ min-height: auto;
+ }
+
+ .pageTitle {
+ font-size: 1.5rem;
+ }
+}
\ No newline at end of file
diff --git a/src/pages/Home/TeamBereich.tsx b/src/pages/Home/TeamBereich.tsx
new file mode 100644
index 0000000..b19458e
--- /dev/null
+++ b/src/pages/Home/TeamBereich.tsx
@@ -0,0 +1,63 @@
+import styles from './HomeStyles/TeamBereich.module.css'
+import sharedStyles from './HomeStyles/pages.module.css'
+
+import MitgliederItem from '../../components/Mitglieder/MitgliederItem';
+import { IoPersonAddSharp } from "react-icons/io5";
+import { useOrgUsers } from '../../hooks/useUsers';
+
+function TeamBereich () {
+ const { users, loading, error, refetch } = useOrgUsers();
+
+ if (loading) {
+ return (
+
+
+
Team-Bereich
+
+
Lade Mitglieder...
+
+
+ );
+ }
+
+ if (error) {
+ return (
+
+
+
Team-Bereich
+
+
Fehler beim Laden der Mitglieder: {error}
+
+
+ );
+ }
+
+ return (
+
+
+
Team-Bereich
+
+
+
+ Mitglied hinzufügen
+
+
+ {users.map((user) => (
+
+ ))}
+
+ {users.length === 0 && (
+
Keine Mitglieder gefunden.
+ )}
+
+
+ );
+}
+
+export default TeamBereich;
+
diff --git a/src/pages/Home/TestSharepoint.module.css b/src/pages/Home/TestSharepoint.module.css
new file mode 100644
index 0000000..8e15d39
--- /dev/null
+++ b/src/pages/Home/TestSharepoint.module.css
@@ -0,0 +1,317 @@
+.container {
+ padding: 20px;
+ max-width: 1400px;
+ margin: 0 auto;
+}
+
+.title {
+ font-size: 28px;
+ font-weight: 600;
+ margin-bottom: 20px;
+ color: var(--text-primary);
+}
+
+.section {
+ background: var(--bg-secondary);
+ border-radius: 8px;
+ padding: 20px;
+ margin-bottom: 20px;
+ border: 1px solid var(--border-primary);
+}
+
+.sectionTitle {
+ font-size: 18px;
+ font-weight: 500;
+ margin-bottom: 15px;
+ color: var(--text-primary);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.connectionsGrid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
+ gap: 15px;
+}
+
+.connectionCard {
+ background: var(--bg-primary);
+ border: 1px solid var(--border-secondary);
+ border-radius: 6px;
+ padding: 15px;
+ transition: border-color 0.2s;
+}
+
+.connectionCard:hover {
+ border-color: var(--border-accent);
+}
+
+.connectionCard.active {
+ border-color: var(--success);
+ background: var(--bg-success-subtle);
+}
+
+.connectionInfo {
+ margin-bottom: 10px;
+}
+
+.connectionName {
+ font-weight: 500;
+ color: var(--text-primary);
+ margin-bottom: 4px;
+}
+
+.connectionStatus {
+ font-size: 12px;
+ color: var(--text-secondary);
+}
+
+.connectionActions {
+ display: flex;
+ gap: 8px;
+}
+
+.testArea {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 20px;
+}
+
+.requestPanel,
+.responsePanel {
+ background: var(--bg-primary);
+ border: 1px solid var(--border-secondary);
+ border-radius: 6px;
+ padding: 15px;
+}
+
+.panelTitle {
+ font-size: 16px;
+ font-weight: 500;
+ margin-bottom: 15px;
+ color: var(--text-primary);
+}
+
+.formGroup {
+ margin-bottom: 15px;
+}
+
+.label {
+ display: block;
+ font-size: 14px;
+ font-weight: 500;
+ margin-bottom: 5px;
+ color: var(--text-primary);
+}
+
+.input,
+.textarea,
+.select {
+ width: 100%;
+ padding: 8px 12px;
+ border: 1px solid var(--border-secondary);
+ border-radius: 4px;
+ background: var(--bg-secondary);
+ color: var(--text-primary);
+ font-size: 14px;
+ transition: border-color 0.2s;
+}
+
+.input:focus,
+.textarea:focus,
+.select:focus {
+ outline: none;
+ border-color: var(--border-accent);
+}
+
+.textarea {
+ min-height: 120px;
+ resize: vertical;
+ font-family: 'Courier New', monospace;
+}
+
+.buttonGroup {
+ display: flex;
+ gap: 10px;
+ margin-bottom: 15px;
+}
+
+.button {
+ padding: 8px 16px;
+ border: 1px solid var(--border-secondary);
+ border-radius: 4px;
+ background: var(--bg-primary);
+ color: var(--text-primary);
+ cursor: pointer;
+ font-size: 14px;
+ transition: all 0.2s;
+}
+
+.button:hover {
+ background: var(--bg-secondary);
+ border-color: var(--border-accent);
+}
+
+.button:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
+.button.primary {
+ background: var(--primary);
+ color: white;
+ border-color: var(--primary);
+}
+
+.button.primary:hover {
+ background: var(--primary-dark);
+}
+
+.button.danger {
+ background: var(--error);
+ color: white;
+ border-color: var(--error);
+}
+
+.button.danger:hover {
+ background: var(--error-dark);
+}
+
+.responseArea {
+ background: var(--bg-code);
+ border: 1px solid var(--border-secondary);
+ border-radius: 4px;
+ padding: 15px;
+ font-family: 'Courier New', monospace;
+ font-size: 12px;
+ color: var(--text-primary);
+ white-space: pre-wrap;
+ max-height: 400px;
+ overflow-y: auto;
+}
+
+.responseArea.success {
+ border-color: var(--success);
+ background: var(--bg-success-subtle);
+}
+
+.responseArea.error {
+ border-color: var(--error);
+ background: var(--bg-error-subtle);
+}
+
+.loading {
+ text-align: center;
+ padding: 20px;
+ color: var(--text-secondary);
+}
+
+.errorMessage {
+ background: var(--bg-error-subtle);
+ border: 1px solid var(--error);
+ border-radius: 4px;
+ padding: 10px;
+ color: var(--error);
+ font-size: 14px;
+ margin-bottom: 15px;
+}
+
+.successMessage {
+ background: var(--bg-success-subtle);
+ border: 1px solid var(--success);
+ border-radius: 4px;
+ padding: 10px;
+ color: var(--success);
+ font-size: 14px;
+ margin-bottom: 15px;
+}
+
+.exampleButton {
+ background: var(--bg-accent);
+ color: var(--text-accent);
+ border: 1px solid var(--border-accent);
+}
+
+.exampleButton:hover {
+ background: var(--bg-accent-hover);
+}
+
+.statusBadge {
+ display: inline-block;
+ padding: 2px 6px;
+ border-radius: 3px;
+ font-size: 11px;
+ font-weight: 500;
+ text-transform: uppercase;
+}
+
+.statusBadge.active {
+ background: var(--bg-success-subtle);
+ color: var(--success);
+}
+
+.statusBadge.pending {
+ background: var(--bg-warning-subtle);
+ color: var(--warning);
+}
+
+.statusBadge.expired {
+ background: var(--bg-error-subtle);
+ color: var(--error);
+}
+
+.statusBadge.revoked {
+ background: var(--bg-error-subtle);
+ color: var(--error);
+}
+
+.tabs {
+ display: flex;
+ border-bottom: 1px solid var(--border-secondary);
+ margin-bottom: 15px;
+}
+
+.tab {
+ padding: 10px 20px;
+ border: none;
+ background: none;
+ color: var(--text-secondary);
+ cursor: pointer;
+ border-bottom: 2px solid transparent;
+ transition: all 0.2s;
+}
+
+.tab:hover {
+ color: var(--text-primary);
+}
+
+.tab.active {
+ color: var(--primary);
+ border-bottom-color: var(--primary);
+}
+
+.tabContent {
+ min-height: 300px;
+}
+
+.helpText {
+ font-size: 12px;
+ color: var(--text-secondary);
+ margin-top: 5px;
+ line-height: 1.4;
+}
+
+.requestPreview {
+ background: var(--bg-code);
+ border: 1px solid var(--border-secondary);
+ border-radius: 4px;
+ padding: 10px;
+ font-family: 'Courier New', monospace;
+ font-size: 12px;
+ color: var(--text-primary);
+ white-space: pre-wrap;
+ max-height: 200px;
+ overflow-y: auto;
+ margin-top: 10px;
+}
\ No newline at end of file
diff --git a/src/pages/Home/TestSharepoint.tsx b/src/pages/Home/TestSharepoint.tsx
new file mode 100644
index 0000000..6f9cb4b
--- /dev/null
+++ b/src/pages/Home/TestSharepoint.tsx
@@ -0,0 +1,602 @@
+import { useState, useEffect } from 'react';
+import {
+ useSharePointTest,
+ SharePointConnection,
+ SharePointListRequest,
+ SharePointFindRequest,
+ SharePointReadRequest,
+ SharePointUploadRequest,
+ SharePointResponse
+} from '../../hooks/useSharePointTest';
+import styles from './TestSharepoint.module.css';
+
+type TestOperation = 'list' | 'find' | 'read' | 'upload';
+
+interface FormData {
+ connectionReference: string;
+ siteUrl: string;
+ folderPaths: string[];
+ query: string;
+ searchScope: string;
+ documentList: string;
+ documentPaths: string[];
+ fileNames: string[];
+ includeMetadata: boolean;
+ includeSubfolders: boolean;
+}
+
+function TestSharepoint() {
+ const {
+ getConnections,
+ testConnection,
+ listDocuments,
+ findDocuments,
+ readDocuments,
+ uploadDocuments,
+ getExamples,
+ debugTokens,
+ debugTokenDetails,
+ discoverSites,
+ isLoading,
+ error,
+ lastResponse
+ } = useSharePointTest();
+
+ // State
+ const [connections, setConnections] = useState
([]);
+ const [selectedConnection, setSelectedConnection] = useState('');
+ const [activeTab, setActiveTab] = useState('list');
+ const [examples, setExamples] = useState({});
+ const [testResults, setTestResults] = useState({});
+ const [tokenDebugInfo, setTokenDebugInfo] = useState(null);
+
+ // Form data
+ const [formData, setFormData] = useState({
+ connectionReference: '',
+ siteUrl: 'https://your-tenant.sharepoint.com/sites/your-site',
+ folderPaths: ['/'], // Start at root folder
+ query: 'quarterly report 2024',
+ searchScope: 'all',
+ documentList: 'document_list_reference_from_chat',
+ documentPaths: ['/Shared Documents/file1.docx', '/Documents/file2.pdf'],
+ fileNames: ['uploaded_file1.docx', 'uploaded_file2.pdf'],
+ includeMetadata: true,
+ includeSubfolders: false // Default to false for better navigation UX
+ });
+
+ // Load connections and examples on mount
+ useEffect(() => {
+ loadConnections();
+ loadExamples();
+ }, []);
+
+ // Update connection reference when selected connection changes
+ useEffect(() => {
+ setFormData(prev => ({ ...prev, connectionReference: selectedConnection }));
+ }, [selectedConnection]);
+
+ const loadConnections = async () => {
+ try {
+ const conns = await getConnections();
+ setConnections(conns);
+ if (conns.length > 0) {
+ setSelectedConnection(conns[0].id);
+ }
+ } catch (error) {
+ console.error('Failed to load connections:', error);
+ }
+ };
+
+ const loadExamples = async () => {
+ try {
+ const exampleData = await getExamples();
+ setExamples(exampleData);
+ } catch (error) {
+ console.error('Failed to load examples:', error);
+ }
+ };
+
+ const handleTestConnection = async (connectionId: string) => {
+ try {
+ const result = await testConnection(connectionId);
+ setTestResults((prev: any) => ({ ...prev, [connectionId]: result }));
+ } catch (error) {
+ console.error('Connection test failed:', error);
+ }
+ };
+
+ const handleDebugTokens = async () => {
+ try {
+ const result = await debugTokens();
+ setTokenDebugInfo(result);
+ } catch (error) {
+ console.error('Token debug failed:', error);
+ }
+ };
+
+ const handleDebugTokenDetails = async () => {
+ try {
+ const result = await debugTokenDetails();
+ setTokenDebugInfo(result);
+ } catch (error) {
+ console.error('Token details debug failed:', error);
+ }
+ };
+
+ const handleFormChange = (field: keyof FormData, value: any) => {
+ setFormData(prev => ({ ...prev, [field]: value }));
+ };
+
+ const handleArrayInputChange = (field: 'folderPaths' | 'documentPaths' | 'fileNames', value: string) => {
+ const array = value.split('\n').filter(item => item.trim() !== '');
+ setFormData(prev => ({ ...prev, [field]: array }));
+ };
+
+ const loadExample = (operation: TestOperation) => {
+ const exampleKey = operation === 'list' ? 'listDocuments' :
+ operation === 'find' ? 'findDocuments' :
+ operation === 'read' ? 'readDocuments' : 'uploadDocuments';
+
+ if (examples[exampleKey]) {
+ const example = examples[exampleKey];
+
+ setFormData(prev => ({
+ ...prev,
+ connectionReference: selectedConnection || prev.connectionReference,
+ siteUrl: example.siteUrl || prev.siteUrl,
+ folderPaths: example.folderPaths || prev.folderPaths,
+ query: example.query || prev.query,
+ searchScope: example.searchScope || prev.searchScope,
+ documentList: example.documentList || prev.documentList,
+ documentPaths: example.documentPaths || prev.documentPaths,
+ fileNames: example.fileNames || prev.fileNames,
+ includeMetadata: example.includeMetadata !== undefined ? example.includeMetadata : prev.includeMetadata,
+ includeSubfolders: example.includeSubfolders !== undefined ? example.includeSubfolders : prev.includeSubfolders
+ }));
+ }
+ };
+
+ const executeTest = async () => {
+ if (!selectedConnection) {
+ alert('Please select a connection first');
+ return;
+ }
+
+ // Find the selected connection to build proper reference
+ const selectedConn = connections.find(conn => conn.id === selectedConnection);
+ if (!selectedConn) {
+ alert('Selected connection not found');
+ return;
+ }
+
+ // Build connection reference in expected format: connection:{authority}:{username}:{id}
+ const connectionReference = `connection:${selectedConn.authority}:${selectedConn.externalUsername}:${selectedConn.id}`;
+
+ try {
+ let result: SharePointResponse;
+
+ switch (activeTab) {
+ case 'list':
+ const listRequest: SharePointListRequest = {
+ connectionReference: connectionReference,
+ siteUrl: formData.siteUrl,
+ folderPaths: formData.folderPaths,
+ includeSubfolders: formData.includeSubfolders,
+ expectedDocumentFormats: [{ extension: '.json', mimeType: 'application/json' }]
+ };
+ result = await listDocuments(listRequest);
+ break;
+
+ case 'find':
+ const findRequest: SharePointFindRequest = {
+ connectionReference: connectionReference,
+ siteUrl: formData.siteUrl,
+ query: formData.query,
+ searchScope: formData.searchScope,
+ expectedDocumentFormats: [{ extension: '.json', mimeType: 'application/json' }]
+ };
+ result = await findDocuments(findRequest);
+ break;
+
+ case 'read':
+ const readRequest: SharePointReadRequest = {
+ documentList: formData.documentList,
+ connectionReference: connectionReference,
+ siteUrl: formData.siteUrl,
+ documentPaths: formData.documentPaths,
+ includeMetadata: formData.includeMetadata,
+ expectedDocumentFormats: [{ extension: '.json', mimeType: 'application/json' }]
+ };
+ result = await readDocuments(readRequest);
+ break;
+
+ case 'upload':
+ const uploadRequest: SharePointUploadRequest = {
+ connectionReference: connectionReference,
+ siteUrl: formData.siteUrl,
+ documentPaths: formData.folderPaths,
+ documentList: formData.documentList,
+ fileNames: formData.fileNames,
+ expectedDocumentFormats: [{ extension: '.json', mimeType: 'application/json' }]
+ };
+ result = await uploadDocuments(uploadRequest);
+ break;
+
+ default:
+ throw new Error('Invalid operation');
+ }
+
+ console.log('Test result:', result);
+ } catch (error) {
+ console.error('Test execution failed:', error);
+ }
+ };
+
+ const renderConnectionCard = (connection: SharePointConnection) => {
+ const testResult = testResults[connection.id];
+
+ return (
+ setSelectedConnection(connection.id)}
+ >
+
+
+ {connection.externalUsername || connection.id}
+
+
+
+ {connection.status}
+
+ {connection.externalEmail && (
+ {connection.externalEmail}
+ )}
+
+
+
+ {
+ e.stopPropagation();
+ handleTestConnection(connection.id);
+ }}
+ disabled={isLoading}
+ >
+ Test
+
+ {testResult && (
+
+ {testResult.success ? '✓' : '✗'}
+
+ )}
+
+
+ );
+ };
+
+ const renderTestForm = () => {
+ return (
+
+
Request Configuration
+
+
+ Connection
+ setSelectedConnection(e.target.value)}
+ >
+ Select a connection
+ {connections.map(conn => (
+
+ {conn.externalUsername || conn.id} ({conn.status})
+
+ ))}
+
+
+
+
+ SharePoint Site URL
+ handleFormChange('siteUrl', e.target.value)}
+ placeholder="https://your-tenant.sharepoint.com/sites/your-site"
+ />
+
+
+ {activeTab === 'list' && (
+ <>
+
+ Folder Paths (one per line)
+
+
+
+ handleFormChange('includeSubfolders', e.target.checked)}
+ />
+ Include Subfolders
+
+
+ >
+ )}
+
+ {activeTab === 'find' && (
+ <>
+
+ Search Query
+ handleFormChange('query', e.target.value)}
+ placeholder="quarterly report 2024"
+ />
+
+
+ Search Scope
+ handleFormChange('searchScope', e.target.value)}
+ >
+ All
+ Documents Only
+ Pages Only
+
+
+ >
+ )}
+
+ {activeTab === 'read' && (
+ <>
+
+
Document List Reference
+
handleFormChange('documentList', e.target.value)}
+ placeholder="document_list_reference_from_chat"
+ />
+
+ This should be a reference from a chat session or document management system
+
+
+
+ Document Paths (one per line)
+
+
+
+ handleFormChange('includeMetadata', e.target.checked)}
+ />
+ Include Metadata
+
+
+ >
+ )}
+
+ {activeTab === 'upload' && (
+ <>
+
+ Document List Reference
+ handleFormChange('documentList', e.target.value)}
+ placeholder="document_list_reference_from_chat"
+ />
+
+
+ Upload Destination Paths (one per line)
+
+
+ File Names (one per line)
+
+ >
+ )}
+
+
+
+ {isLoading ? 'Testing...' : `Test ${activeTab.charAt(0).toUpperCase() + activeTab.slice(1)}`}
+
+ loadExample(activeTab)}
+ >
+ Load Example
+
+
+
+
+ Request Preview:
+ {JSON.stringify({
+ endpoint: `/api/test-sharepoint/${activeTab === 'list' ? 'list-documents' :
+ activeTab === 'find' ? 'find-documents' :
+ activeTab === 'read' ? 'read-documents' : 'upload-documents'}`,
+ method: 'POST',
+ body: activeTab === 'list' ? {
+ connectionReference: selectedConnection ?
+ `connection:${connections.find(c => c.id === selectedConnection)?.authority}:${connections.find(c => c.id === selectedConnection)?.externalUsername}:${selectedConnection}` :
+ 'No connection selected',
+ siteUrl: formData.siteUrl,
+ folderPaths: formData.folderPaths,
+ includeSubfolders: formData.includeSubfolders
+ } : activeTab === 'find' ? {
+ connectionReference: selectedConnection ?
+ `connection:${connections.find(c => c.id === selectedConnection)?.authority}:${connections.find(c => c.id === selectedConnection)?.externalUsername}:${selectedConnection}` :
+ 'No connection selected',
+ siteUrl: formData.siteUrl,
+ query: formData.query,
+ searchScope: formData.searchScope
+ } : activeTab === 'read' ? {
+ documentList: formData.documentList,
+ connectionReference: selectedConnection ?
+ `connection:${connections.find(c => c.id === selectedConnection)?.authority}:${connections.find(c => c.id === selectedConnection)?.externalUsername}:${selectedConnection}` :
+ 'No connection selected',
+ siteUrl: formData.siteUrl,
+ documentPaths: formData.documentPaths,
+ includeMetadata: formData.includeMetadata
+ } : {
+ connectionReference: selectedConnection ?
+ `connection:${connections.find(c => c.id === selectedConnection)?.authority}:${connections.find(c => c.id === selectedConnection)?.externalUsername}:${selectedConnection}` :
+ 'No connection selected',
+ siteUrl: formData.siteUrl,
+ documentPaths: formData.folderPaths,
+ documentList: formData.documentList,
+ fileNames: formData.fileNames
+ }
+ }, null, 2)}
+
+
+ );
+ };
+
+ const renderResponse = () => {
+ return (
+
+
Response
+
+ {error && (
+
+ Error: {error}
+
+ )}
+
+ {lastResponse && (
+
+ {JSON.stringify(lastResponse, null, 2)}
+
+ )}
+
+ {!lastResponse && !error && (
+
+ No response yet. Execute a test to see results here.
+
+ )}
+
+ );
+ };
+
+ return (
+
+
SharePoint Method Testing
+
+
+
+ Microsoft Connections ({connections.length})
+
+
+
+
+ Debug Authentication Tokens
+
+
+ Debug Token Details
+
+
+
+ {tokenDebugInfo && (
+
+
Token Debug Info:
+
{JSON.stringify(tokenDebugInfo, null, 2)}
+
+ )}
+
+ {connections.length === 0 ? (
+
+ {isLoading ? 'Loading connections...' : 'No Microsoft connections found. Please create a connection first.'}
+
+ ) : (
+
+ {connections.map(renderConnectionCard)}
+
+ )}
+
+
+
+
SharePoint Operations Testing
+
+
+ setActiveTab('list')}
+ >
+ List Documents
+
+ setActiveTab('find')}
+ >
+ Find Documents
+
+ setActiveTab('read')}
+ >
+ Read Documents
+
+ setActiveTab('upload')}
+ >
+ Upload Documents
+
+
+
+
+
+ {renderTestForm()}
+ {renderResponse()}
+
+
+
+
+ );
+}
+
+export default TestSharepoint;
\ No newline at end of file
diff --git a/src/pages/Home/Workflows.tsx b/src/pages/Home/Workflows.tsx
new file mode 100644
index 0000000..85adc7c
--- /dev/null
+++ b/src/pages/Home/Workflows.tsx
@@ -0,0 +1,20 @@
+import styles from './HomeStyles/Workflows.module.css'
+import sharedStyles from './HomeStyles/pages.module.css'
+
+function Workflows () {
+ return (
+
+
+
Workflows
+
+
+
+ {/* Workflow content will go here */}
+
Workflow management coming soon...
+
+
+
+ );
+}
+
+export default Workflows;
diff --git a/src/pages/Login.module.css b/src/pages/Login.module.css
index 854b927..8489b8b 100644
--- a/src/pages/Login.module.css
+++ b/src/pages/Login.module.css
@@ -1,27 +1,42 @@
.container {
display: flex;
min-height: 100vh;
- background-color: var(--color-bg);
+
+ font-family: "DM Sans", sans-serif;
+ color: #181818;
}
-.leftPanel {
+.mainContent {
flex: 1;
display: flex;
flex-direction: column;
padding: 3rem;
- background-color: var(--color-bg);
+ background-color: #181818;
}
-.rightPanel {
+.loginSection {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
flex: 1;
- background-color: var(--color-bg);
+}
+
+.logoText {
+
+ font-size: 35px;
display: flex;
align-items: center;
- justify-content: center;
+ letter-spacing: -0.5px;
+ font-weight: 200;
}
-.logo {
- margin-bottom: 2rem;
+.logoPower {
+ color: #E5E7EB;
+}
+
+.logoOn {
+ color: #F25843;
+ font-weight: 700;
}
.logo img {
@@ -29,17 +44,24 @@
}
.loginBox {
- max-width: 400px;
- margin: auto;
- width: 100%;
+
+
+ background-color: #181818;
+ width: 25%;
+ height: auto;
+
+ margin-top: 5%;
+ padding: 2rem;
+
+ border-radius: 25px;
+ border: 1px solid rgba(199, 197, 178, 0.15); /* washed-out color */
+ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.02),
+ 0 0 10px rgba(0, 0, 0, 0.1);
}
.title {
- font-size: 2rem;
- font-weight: 600;
- margin-bottom: 2rem;
- color: var(--color-text);
- font-family: var(--font-family);
+ font-family: "DM Sans", sans-serif;
+ color: #E5E7EB;
}
.loginForm {
@@ -48,64 +70,142 @@
gap: 1rem;
}
+.floatingLabelInput {
+ position: relative;
+}
+
+.label {
+ position: absolute;
+ left: 16px;
+ top: 50%;
+ transform: translateY(-50%);
+ color: #C7C5B2;
+ font-size: 1rem;
+ pointer-events: none;
+ transition: all 0.3s ease;
+ background-color: transparent;
+ font-family: var(--font-family);
+}
+
+.focusedLabel {
+ position: absolute;
+ left: 12px;
+ top: -8px;
+ transform: translateY(0);
+ color: #F25843;
+ font-size: 0.85rem;
+ pointer-events: none;
+ transition: all 0.3s ease;
+ background-color: #181818;
+ padding: 0 4px;
+ font-family: var(--font-family);
+ font-weight: 500;
+}
+
.input {
width: 100%;
+ height: 50px;
padding: 12px 16px;
border: 1px solid var(--color-gray-disabled);
- border-radius: 8px;
+ border-radius: 25px;
+
font-size: 1rem;
transition: all 0.2s ease;
- background-color: var(--color-bg);
- color: var(--color-text);
+ background-color: #181818;
+ color: #C7C5B2;
font-family: var(--font-family);
}
.input:focus {
outline: none;
- border-color: var(--color-secondary);
- box-shadow: 0 0 0 2px rgba(63, 81, 181, 0.1);
+ border-color: #F25843;
+ box-shadow: 0 0 0 2px rgba(242, 88, 67, 0.1);
}
.input::placeholder {
- color: var(--color-gray);
+ color: transparent;
+}
+
+/* Fix browser autocomplete styling */
+.input:-webkit-autofill,
+.input:-webkit-autofill:hover,
+.input:-webkit-autofill:focus,
+.input:-webkit-autofill:active {
+ -webkit-box-shadow: 0 0 0 30px #181818 inset !important;
+ -webkit-text-fill-color: #E5E7EB !important;
+ background-color: #181818 !important;
+ transition: background-color 5000s ease-in-out 0s;
+}
+
+/* Ensure label background matches when autofilled */
+.input:-webkit-autofill + .label,
+.input:-webkit-autofill + .focusedLabel {
+ background-color: #181818 !important;
+}
+
+.disclaimer {
+ font-size: 0.8rem;
+ color: #E5E7EB;
+ text-align: center;
}
.button {
width: 100%;
+ height: 50px;
padding: 12px 20px;
- border-radius: 8px;
+ border-radius: 25px;
+
font-size: 1rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
border: none;
text-align: center;
- font-family: var(--font-family);
}
-.primaryButton {
- background-color: var(--color-secondary);
- color: var(--color-bg);
+.buttonContent {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
}
-.primaryButton:hover {
+.microsoftIcon {
+ width: 18px;
+ height: 18px;
+}
+
+.loginButton {
+ background-color: #F25843;
+ color: #E5E7EB;
+}
+
+.loginButton:hover {
background-color: var(--color-secondary-hover);
}
.microsoftButton {
- background-color: var(--color-text);
- color: var(--color-bg);
+ background-color: #C7C5B2;
+ color: #181818;
}
.microsoftButton:hover {
- background-color: var(--color-gray);
+ background-color: #D9D7C6;
+}
+
+.googleButton {
+ background-color: #C7C5B2;
+ color: #181818;
+}
+
+.googleButton:hover {
+ background-color: #D9D7C6;
}
.divider {
display: flex;
align-items: center;
text-align: center;
- margin: 1rem 0;
}
.divider::before,
@@ -117,9 +217,8 @@
.divider span {
padding: 0 1rem;
- color: var(--color-gray);
- font-size: 0.9rem;
- font-family: var(--font-family);
+ color: #E5E7EB;
+ font-size: 0.8rem;
}
.registerLink {
@@ -127,13 +226,11 @@
align-items: center;
justify-content: center;
gap: 0.5rem;
- margin-top: 1rem;
}
.registerLink span {
- color: var(--color-gray);
- font-size: 0.9rem;
- font-family: var(--font-family);
+ color: #E5E7EB;
+ font-size: 0.8rem;
}
.textButton {
@@ -156,24 +253,12 @@ button:disabled {
cursor: not-allowed;
}
-.rightContent {
- max-width: 80%;
- padding: 2rem;
-}
-
-.rightContent img {
- width: 100%;
- height: auto;
- max-width: 500px;
-}
-
.error {
color: var(--color-red);
background-color: var(--color-red-disabled);
border: 1px solid var(--color-red);
border-radius: 8px;
padding: 12px;
- margin-bottom: 1rem;
font-size: 0.9rem;
text-align: center;
font-family: var(--font-family);
diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx
index aa176a3..149d63e 100644
--- a/src/pages/Login.tsx
+++ b/src/pages/Login.tsx
@@ -1,37 +1,51 @@
-import { useMsal } from '@azure/msal-react';
-import { loginRequest } from '../auth/authConfig';
import { useNavigate, useLocation } from 'react-router-dom';
import { useState, useEffect } from 'react';
-import styles from './Login.module.css';
-import agentDiagram from '/logos/Frame 43.png';
-import logo from '/logos/PowerOn.png';
+import { FaGoogle, FaMicrosoft } from 'react-icons/fa';
+
import { useAuth, useMsalAuth } from '../hooks/useAuthentication';
+import styles from './Login.module.css';
+
+
function Login() {
- const { instance, accounts, inProgress } = useMsal();
const navigate = useNavigate();
const location = useLocation();
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
+ const [usernameFocused, setUsernameFocused] = useState(false);
+ const [passwordFocused, setPasswordFocused] = useState(false);
const { login, error: loginError, isLoading: isLoginLoading } = useAuth();
const { loginWithMsal, error: msalError, isLoading: isMsalLoading } = useMsalAuth();
// Get the page the user was trying to visit
const from = location.state?.from?.pathname || "/";
- // Debug information about accounts
+ // Set page title
useEffect(() => {
- if (accounts.length > 0) {
- console.log("MSAL accounts found:", accounts.map(acc => ({
- username: acc.username,
- name: acc.name,
- idTokenClaims: acc.idTokenClaims
- })));
- } else {
- console.log("No MSAL accounts found");
- }
- }, [accounts]);
+ document.title = "PowerOn AI Platform - Login";
+ }, []);
+ // Check for autofilled inputs
+ useEffect(() => {
+ const checkAutofill = () => {
+ const usernameInput = document.querySelector('input[type="text"]') as HTMLInputElement;
+ const passwordInput = document.querySelector('input[type="password"]') as HTMLInputElement;
+
+ if (usernameInput && usernameInput.value) {
+ setUsername(usernameInput.value);
+ }
+ if (passwordInput && passwordInput.value) {
+ setPassword(passwordInput.value);
+ }
+ };
+
+ // Check immediately and after a short delay
+ checkAutofill();
+ const timer = setTimeout(checkAutofill, 100);
+
+ return () => clearTimeout(timer);
+ }, []);
+
const handleMsalLogin = async () => {
try {
console.log("Attempting MSAL login...");
@@ -54,66 +68,93 @@ function Login() {
return (
-
+
-
-
-
-
Sign In or Register Your Organisation
-
-
- {(loginError || msalError) && (
-
{loginError || msalError}
- )}
-
setUsername(e.target.value)}
- className={styles.input}
- />
-
setPassword(e.target.value)}
- className={styles.input}
- />
-
- {isLoginLoading ? "Signing in..." : "Sign In"}
-
-
-
- or continue with
-
-
-
- {isMsalLoading ? "Signing in..." : "Sign in with Microsoft"}
-
-
-
- Don't have an account?
- navigate("/register")}
- >
- Register
-
-
+
+ Power
+ On
-
-
-
-
+
+
+
+ {(loginError || msalError) && (
+
{loginError || msalError}
+ )}
+
+ setUsername(e.target.value)}
+ onFocus={() => setUsernameFocused(true)}
+ onBlur={() => setUsernameFocused(false)}
+ className={`${styles.input} ${usernameFocused || username ? styles.focused : ''}`}
+ />
+ Benutzername
+
+
+ setPassword(e.target.value)}
+ onFocus={() => setPasswordFocused(true)}
+ onBlur={() => setPasswordFocused(false)}
+ className={`${styles.input} ${passwordFocused || password ? styles.focused : ''}`}
+ />
+ Passwort
+
+
+
+ Mit der Anmeldung stimmen Sie unseren Datenschutzbestimmungen zur KI-Nutzung zu.
+
+
+
+ {isLoginLoading ? "wird geladen..." : "Anmelden"}
+
+
+
+ oder
+
+
+
+
+
+ {isMsalLoading ? "Signing in..." : "Mit Microsoft anmelden"}
+
+
+
+
console.log("Google button clicked")}
+ disabled={false}
+ >
+
+
+ Mit Google anmelden
+
+
+
+
+ Du hast noch keinen Konto?
+ navigate("/register")}
+ >
+ Registrieren
+
+
+
+
diff --git a/src/pages/Register.module.css b/src/pages/Register.module.css
index ecb11c2..cc4e681 100644
--- a/src/pages/Register.module.css
+++ b/src/pages/Register.module.css
@@ -1,71 +1,114 @@
.container {
display: flex;
min-height: 100vh;
- background-color: var(--color-bg);
+
+ font-family: "DM Sans", sans-serif;
+ color: #181818;
}
-.leftPanel {
+.mainContent {
flex: 1;
display: flex;
flex-direction: column;
padding: 3rem;
- background-color: var(--color-bg);
+ background-color: #181818;
}
-.rightPanel {
+.loginSection {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
flex: 1;
- background-color: var(--color-bg);
+}
+
+.logoText {
+
+ font-size: 35px;
display: flex;
align-items: center;
- justify-content: center;
+ letter-spacing: -0.5px;
+ font-weight: 200;
}
-.logo {
- margin-bottom: 2rem;
+.logoPower {
+ color: #E5E7EB;
+}
+
+.logoOn {
+ color: #F25843;
+ font-weight: 700;
}
.logo img {
height: 40px;
}
-.registerBox {
- max-width: 500px;
- margin: auto;
- width: 100%;
+.loginBox {
+
+
+ background-color: #181818;
+ width: 25%;
+ height: auto;
+
+ margin-top: 5%;
+ padding: 2rem;
+
+ border-radius: 25px;
+ border: 1px solid rgba(199, 197, 178, 0.15); /* washed-out color */
+ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.02),
+ 0 0 10px rgba(0, 0, 0, 0.1);
}
.title {
- font-size: 2rem;
- font-weight: 600;
- margin-bottom: 2rem;
- color: var(--color-text);
+ font-family: "DM Sans", sans-serif;
+ color: #E5E7EB;
+}
+
+.loginForm {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.floatingLabelInput {
+ position: relative;
+}
+
+.label {
+ position: absolute;
+ left: 16px;
+ top: 50%;
+ transform: translateY(-50%);
+ color: #C7C5B2;
+ font-size: 1rem;
+ pointer-events: none;
+ transition: all 0.3s ease;
+ background-color: transparent;
font-family: var(--font-family);
}
-.registerForm {
- display: flex;
- flex-direction: column;
- gap: 1.25rem;
-}
-
-.inputGroup {
- display: flex;
- flex-direction: column;
- gap: 0.5rem;
-}
-
-.inputGroup label {
- font-size: 0.9rem;
+.focusedLabel {
+ position: absolute;
+ left: 12px;
+ top: -8px;
+ transform: translateY(0);
+ color: #F25843;
+ font-size: 0.85rem;
+ pointer-events: none;
+ transition: all 0.3s ease;
+ background-color: #181818;
+ padding: 0 4px;
+ font-family: var(--font-family);
font-weight: 500;
- color: var(--color-text);
- font-family: var(--font-family);
}
.input {
width: 100%;
+ height: 50px;
padding: 12px 16px;
border: 1px solid var(--color-gray-disabled);
- border-radius: 8px;
+ border-radius: 25px;
+
font-size: 1rem;
transition: all 0.2s ease;
background-color: var(--color-bg);
@@ -75,67 +118,82 @@
.input:focus {
outline: none;
- border-color: var(--color-secondary);
- box-shadow: 0 0 0 2px rgba(63, 81, 181, 0.1);
+ border-color: #F25843;
+ box-shadow: 0 0 0 2px rgba(242, 88, 67, 0.1);
+}
+
+.usernameError {
+ border-color: #F25843 !important;
+ box-shadow: 0 0 0 2px rgba(242, 88, 67, 0.2) !important;
}
.input::placeholder {
- color: var(--color-gray);
+ color: transparent;
+}
+
+/* Fix browser autocomplete styling */
+.input:-webkit-autofill,
+.input:-webkit-autofill:hover,
+.input:-webkit-autofill:focus,
+.input:-webkit-autofill:active {
+ -webkit-box-shadow: 0 0 0 30px #181818 inset !important;
+ -webkit-text-fill-color: #E5E7EB !important;
+ background-color: #181818 !important;
+ transition: background-color 5000s ease-in-out 0s;
+}
+
+/* Ensure label background matches when autofilled */
+.input:-webkit-autofill + .label,
+.input:-webkit-autofill + .focusedLabel {
+ background-color: #181818 !important;
+}
+
+.disclaimer {
+ font-size: 0.8rem;
+ color: #E5E7EB;
+ text-align: center;
}
.button {
width: 100%;
+ height: 50px;
padding: 12px 20px;
- border-radius: 8px;
+ border-radius: 25px;
+
font-size: 1rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
border: none;
text-align: center;
- margin-top: 1rem;
- font-family: var(--font-family);
}
-.primaryButton {
- background-color: var(--color-secondary);
- color: var(--color-bg);
+.buttonContent {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
}
-.primaryButton:hover {
+.loginButton {
+ background-color: #F25843;
+ color: #E5E7EB;
+}
+
+.loginButton:hover {
background-color: var(--color-secondary-hover);
}
-.primaryButton:disabled {
- background-color: var(--color-gray-disabled);
- cursor: not-allowed;
-}
-
-.error {
- color: var(--color-red);
- background-color: var(--color-red-disabled);
- border: 1px solid var(--color-red);
- border-radius: 8px;
- padding: 12px;
- font-size: 0.9rem;
- text-align: center;
- font-family: var(--font-family);
-}
-
-.loginLink {
+.registerLink {
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
- margin-top: 1.5rem;
- padding-top: 1.5rem;
- border-top: 1px solid var(--color-gray-disabled);
}
-.loginLink span {
- color: var(--color-gray);
- font-size: 0.9rem;
- font-family: var(--font-family);
+.registerLink span {
+ color: #E5E7EB;
+ font-size: 0.8rem;
}
.textButton {
@@ -153,72 +211,19 @@
text-decoration: underline;
}
-.rightContent {
- max-width: 80%;
- padding: 2rem;
+button:disabled {
+ opacity: 0.7;
+ cursor: not-allowed;
}
-.rightContent img {
- width: 100%;
- height: auto;
- max-width: 500px;
-}
-
-/* Required field indicator */
-label[htmlFor]::after {
- content: ' *';
- color: var(--color-red);
-}
-
-.msalButton {
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 10px;
- width: 100%;
- padding: 10px;
- background-color: var(--color-bg);
- border: 1px solid var(--color-gray-disabled);
- border-radius: 4px;
- font-size: 16px;
- cursor: pointer;
- transition: background-color 0.2s;
- margin-bottom: 20px;
- color: var(--color-text);
- font-family: var(--font-family);
-}
-
-.msalButton:hover {
- background-color: var(--color-surface);
-}
-
-.msalButton:disabled {
- background-color: var(--color-surface);
- cursor: not-allowed;
-}
-
-.msalLogo {
- width: 20px;
- height: 20px;
-}
-
-.divider {
- display: flex;
- align-items: center;
- text-align: center;
- margin: 20px 0;
-}
-
-.divider::before,
-.divider::after {
- content: '';
- flex: 1;
- border-bottom: 1px solid var(--color-gray-disabled);
-}
-
-.divider span {
- padding: 0 1rem;
- color: var(--color-gray);
- font-size: 0.9rem;
- font-family: var(--font-family);
+.error {
+ color: var(--color-secondary);
+ background-color: var(--color-secondary-disabled);
+ border: 1px solid var(--color-secondary);
+ border-radius: 25px;
+ padding: 12px;
+ font-size: 0.9rem;
+ text-align: center;
+ font-family: var(--font-family);
+ margin-bottom: 10px;
}
diff --git a/src/pages/Register.tsx b/src/pages/Register.tsx
index c77d10b..787365a 100644
--- a/src/pages/Register.tsx
+++ b/src/pages/Register.tsx
@@ -1,9 +1,8 @@
-import { useState } from 'react';
+import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
+import { FaMicrosoft } from 'react-icons/fa';
import styles from './Register.module.css';
-import logo from '/logos/PowerOn.png';
-import agentDiagram from '/logos/Frame 43.png';
-import { useRegister, useMsalRegister } from '../hooks/useAuthentication';
+import { useRegister, useMsalRegister, useUsernameAvailability } from '../hooks/useAuthentication';
interface RegisterFormData {
username: string;
@@ -17,6 +16,7 @@ function Register() {
const navigate = useNavigate();
const { register, error: registerError, isLoading } = useRegister();
const { registerWithMsal, error: msalError, isLoading: msalLoading } = useMsalRegister();
+ const { checkAvailability, isChecking, error: availabilityError } = useUsernameAvailability();
const [formData, setFormData] = useState
({
username: '',
password: '',
@@ -25,6 +25,17 @@ function Register() {
fullName: ''
});
const [validationError, setValidationError] = useState(null);
+ const [usernameFocused, setUsernameFocused] = useState(false);
+ const [passwordFocused, setPasswordFocused] = useState(false);
+ const [confirmPasswordFocused, setConfirmPasswordFocused] = useState(false);
+ const [emailFocused, setEmailFocused] = useState(false);
+ const [fullNameFocused, setFullNameFocused] = useState(false);
+ const [usernameHighlight, setUsernameHighlight] = useState(false);
+
+ // Set page title
+ useEffect(() => {
+ document.title = "PowerOn AI Platform - Registrieren";
+ }, []);
const handleInputChange = (e: React.ChangeEvent) => {
const { name, value } = e.target;
@@ -33,6 +44,10 @@ function Register() {
[name]: value
}));
setValidationError(null);
+ // Reset username highlight when user starts typing in username field
+ if (name === 'username') {
+ setUsernameHighlight(false);
+ }
};
const validateForm = (): boolean => {
@@ -62,6 +77,22 @@ function Register() {
}
try {
+ // First check username availability
+ const availabilityResult = await checkAvailability(formData.username, 'local');
+
+ if (!availabilityResult.available) {
+ // Check if the error message is about username being taken
+ const errorMessage = availabilityResult.message || 'Username is not available';
+ if (errorMessage === 'Username is already taken') {
+ setValidationError('Benutzername ist bereits vergeben');
+ setUsernameHighlight(true);
+ } else {
+ setValidationError('Benutzername ist nicht verfügbar');
+ }
+ return;
+ }
+
+ // Username is available, proceed with registration
const { confirmPassword, ...registrationData } = formData;
await register(registrationData);
navigate('/login', {
@@ -75,140 +106,126 @@ function Register() {
}
};
- const handleMsalRegister = async () => {
- try {
- await registerWithMsal();
- navigate('/login', {
- state: {
- registered: true,
- message: 'Microsoft Registration erfolgreich. Bitte melden Sie sich an.'
- }
- });
- } catch (err) {
- console.error('Microsoft registration failed:', err);
- }
+ // Helper function to safely get error message
+ const getErrorMessage = () => {
+ if (validationError) return validationError;
+ if (registerError) return typeof registerError === 'string' ? registerError : 'Registration failed';
+ if (msalError) return typeof msalError === 'string' ? msalError : 'Microsoft registration failed';
+ if (availabilityError) return typeof availabilityError === 'string' ? availabilityError : 'Username availability check failed';
+ return null;
};
return (
-
+
-
navigate('/')} style={{ cursor: 'pointer' }} />
-
-
-
Organisation registrieren
-
- {/* Microsoft Register Button */}
-
-
- {msalLoading ? "Registrierung läuft..." : "Mit Microsoft registrieren"}
-
-
-
-
oder
+
+ Power
+ On
-
-
-
-
-
-
+
+
+
+ {getErrorMessage() && (
+
{getErrorMessage()}
+ )}
+
+
+ setUsernameFocused(true)}
+ onBlur={() => setUsernameFocused(false)}
+ className={`${styles.input} ${usernameFocused || formData.username ? styles.focused : ''} ${usernameHighlight ? styles.usernameError : ''}`}
+ />
+ Benutzername
+
+
+
+ setEmailFocused(true)}
+ onBlur={() => setEmailFocused(false)}
+ className={`${styles.input} ${emailFocused || formData.email ? styles.focused : ''}`}
+ />
+ E-Mail
+
+
+
+ setFullNameFocused(true)}
+ onBlur={() => setFullNameFocused(false)}
+ className={`${styles.input} ${fullNameFocused || formData.fullName ? styles.focused : ''}`}
+ />
+ Vollständiger Name
+
+
+
+ setPasswordFocused(true)}
+ onBlur={() => setPasswordFocused(false)}
+ className={`${styles.input} ${passwordFocused || formData.password ? styles.focused : ''}`}
+ />
+ Passwort
+
+
+
+ setConfirmPasswordFocused(true)}
+ onBlur={() => setConfirmPasswordFocused(false)}
+ className={`${styles.input} ${confirmPasswordFocused || formData.confirmPassword ? styles.focused : ''}`}
+ />
+ Passwort bestätigen
+
+
+
+
+ Mit der Registrierung stimmen Sie unseren Datenschutzbestimmungen zur KI-Nutzung zu.
+
+
+
+
+ {isLoading ? "Registrierung läuft..." : isChecking ? "Benutzername wird geprüft..." : "Registrieren"}
+
+
+
+ Bereits registriert?
+ navigate("/login")}
+ >
+ Jetzt anmelden
+
+
+
+
diff --git a/src/pages/TeamBereich/TeamBereich.module.css b/src/pages/TeamBereich/TeamBereich.module.css
deleted file mode 100644
index 24e02f6..0000000
--- a/src/pages/TeamBereich/TeamBereich.module.css
+++ /dev/null
@@ -1,92 +0,0 @@
-.mitgliederContainer {
- margin: 51px 49px 0 36px;
- display: flex;
- padding: 0px 30px 30px 30px;
- flex-direction: column;
- align-self: stretch;
- border-radius: 30px;
- border: 1px solid var(--color-gray-disabled);
- background: var(--color-bg);
- position: relative;
- box-shadow: 0px 2px 6px 0px rgba(194, 194, 194, 0.10);
- max-height: calc(100vh - 100px);
- overflow: hidden;
- font-family: var(--font-family);
-}
-
-.horizontalLineLight {
- width: 100%;
- background-color: var(--color-gray-disabled);
- height: 1px;
- margin-top: 90px;
- margin-left: -30px;
- position: absolute;
-}
-
-.header{
- display: flex;
- gap: 30px;
- align-items: flex-start;
- height: 62px;
- color: var(--color-text);
- padding-top: 30px;
- padding-bottom: 30px;
- font-family: var(--font-family);
-}
-
-.mitglieder_hinzufügen_button {
-
- border-radius: 30px;
- background: var(--color-gray-disabled);
- color: var(--color-text);
- border: none;
- outline: none;
- text-align: left;
- padding-left: 20px;
- padding-right: 20px;
- padding-top: 10px;
- padding-bottom: 10px;
-
- display: flex;
- gap: 10px;
- align-items: center;
- font-family: var(--font-family);
- transition: background-color 0.2s ease;
-}
-
-.mitglieder_hinzufügen_button:hover {
- cursor: pointer;
- background-color: var(--color-gray);
-}
-
-.add_icon {
- font-size: 16px;
-}
-
-.membersList {
- list-style: none;
- padding: 0;
- margin-top: 30px;
- width: 100%;
- overflow-y: auto; /* Enable vertical scrolling */
- /* Space for the header line */
-}
-
-.membersList li {
- display: flex;
- align-items: center;
- height: 60px; /* Specific height for each item */
- padding: 0 16px;
- border-bottom: 1px solid var(--color-gray-disabled);
- font-size: 16px;
- transition: background-color 0.2s ease;
- color: var(--color-text);
- font-family: var(--font-family);
- }
-
-.actions {
- display: flex;
- gap: 10px;
- align-items: center;
- justify-content: center;
- }
\ No newline at end of file
diff --git a/src/pages/TeamBereich/TeamBereich.tsx b/src/pages/TeamBereich/TeamBereich.tsx
deleted file mode 100644
index 19294a9..0000000
--- a/src/pages/TeamBereich/TeamBereich.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-import styles from './TeamBereich.module.css'
-
-import MitgliederItem from '../../components/Mitglieder/MitgliederItem';
-import { IoPersonAddSharp } from "react-icons/io5";
-import { useOrgUsers } from '../../hooks/useUsers';
-
-function TeamBereich () {
- const { users, loading, error, refetch } = useOrgUsers();
-
- if (loading) {
- return (
-
-
-
Team-Bereich
-
-
Lade Mitglieder...
-
- );
- }
-
- if (error) {
- return (
-
-
-
Team-Bereich
-
-
Fehler beim Laden der Mitglieder: {error}
-
- );
- }
-
- return (
-
-
-
Team-Bereich
-
-
- Mitglied hinzufügen
-
-
-
-
- {users.map((user) => (
-
- ))}
-
- {users.length === 0 && (
-
Keine Mitglieder gefunden.
- )}
-
- );
-}
-
-export default TeamBereich;
-