diff --git a/package-lock.json b/package-lock.json index 4ef4250..a0e602b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,8 @@ "name": "frontend", "version": "0.0.0", "dependencies": { - "@azure/msal-browser": "^4.8.0", - "@azure/msal-react": "^3.0.7", + "@azure/msal-browser": "^4.12.0", + "@azure/msal-react": "^3.0.12", "axios": "^1.8.3", "dotenv": "^16.0.3", "framer-motion": "^12.7.3", @@ -19,16 +19,16 @@ "jwt-decode": "^4.0.0", "motion": "^12.7.3", "pg": "^8.8.0", - "react": "^18.3.1", - "react-dom": "^18.3.1", + "react": "^19.1.0", + "react-dom": "^19.1.0", "react-dropzone": "^14.3.8", "react-icons": "^5.5.0", "react-router-dom": "^7.5.0" }, "devDependencies": { "@eslint/js": "^9.21.0", - "@types/react": "^19.0.10", - "@types/react-dom": "^19.0.4", + "@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", @@ -51,75 +51,75 @@ } }, "node_modules/@azure/msal-browser": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.8.0.tgz", - "integrity": "sha512-z7kJlMW3IAETyq82LDKJqr++IeOvU728q9lkuTFjEIPUWxnB1OlmuPCF32fYurxOnOnJeFEZxjbEzq8xyP0aag==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.12.0.tgz", + "integrity": "sha512-WD1lmVWchg7wn1mI7Tr4v7QPyTwK+8Nuyje3jRpOFENLRLEBsdK8VVdTw3C+TypZmYn4cOAdj3zREnuFXgvfIA==", "dependencies": { - "@azure/msal-common": "15.3.0" + "@azure/msal-common": "15.6.0" }, "engines": { "node": ">=0.8.0" } }, "node_modules/@azure/msal-common": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.3.0.tgz", - "integrity": "sha512-lh+eZfibGwtQxFnx+mj6cYWn0pwA8tDnn8CBs9P21nC7Uw5YWRwfXaXdVQSMENZ5ojRqR+NzRaucEo4qUvs3pA==", + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.6.0.tgz", + "integrity": "sha512-EotmBz42apYGjqiIV9rDUdptaMptpTn4TdGf3JfjLvFvinSe9BJ6ywU92K9ky+t/b0ghbeTSe9RfqlgLh8f2jA==", "engines": { "node": ">=0.8.0" } }, "node_modules/@azure/msal-react": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@azure/msal-react/-/msal-react-3.0.7.tgz", - "integrity": "sha512-77S3eVslJMAXNiLmdrJkJ/gJupjeTdUQinYfc8EzgvLuU5QuLng7Lb5qgSz9DuZfYhC2rbOqvrz4x7o0YBXlBA==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@azure/msal-react/-/msal-react-3.0.12.tgz", + "integrity": "sha512-Rnw1hcx/ILYmbhcPZbhQNdBpf0jE3P0nMiwLKRMqgjnACqOiHQ5+ZZzEIXwEPiva9TPSrW34yvNBTLx8k/5pVg==", "engines": { "node": ">=10" }, "peerDependencies": { - "@azure/msal-browser": "^4.8.0", - "react": "^16.8.0 || ^17 || ^18" + "@azure/msal-browser": "^4.12.0", + "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "node_modules/@babel/code-frame": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", + "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", - "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.3.tgz", + "integrity": "sha512-V42wFfx1ymFte+ecf6iXghnnP8kWTO+ZLXIyZq+1LAXHHvTZdVxicn4yiVYdYMGaCO3tmqub11AorKkv+iodqw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.26.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", - "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.3.tgz", + "integrity": "sha512-hyrN8ivxfvJ4i0fIJuV4EOlV0WDMz5Ui4StRTgVaAvWeiRCilXgwVvxJKtFQ3TKtHgJscB2YiXKGNJuVwhQMtA==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.10", - "@babel/helper-compilation-targets": "^7.26.5", - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.10", - "@babel/parser": "^7.26.10", - "@babel/template": "^7.26.9", - "@babel/traverse": "^7.26.10", - "@babel/types": "^7.26.10", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.27.3", + "@babel/helpers": "^7.27.3", + "@babel/parser": "^7.27.3", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.27.3", + "@babel/types": "^7.27.3", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -135,13 +135,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.26.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.10.tgz", - "integrity": "sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==", + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.3.tgz", + "integrity": "sha512-xnlJYj5zepml8NXtjkG0WquFUv8RskFqyFcVgTBp5k+NaA/8uw/K+OSVf8AMGw5e9HKP2ETd5xpK5MLZQD6b4Q==", "dev": true, "dependencies": { - "@babel/parser": "^7.26.10", - "@babel/types": "^7.26.10", + "@babel/parser": "^7.27.3", + "@babel/types": "^7.27.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -151,13 +151,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", - "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.26.5", - "@babel/helper-validator-option": "^7.25.9", + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -167,27 +167,27 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", - "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "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, "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", - "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", + "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.3" }, "engines": { "node": ">=6.9.0" @@ -197,61 +197,61 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", - "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", - "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.26.10", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz", - "integrity": "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==", + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.3.tgz", + "integrity": "sha512-h/eKy9agOya1IGuLaZ9tEUgz+uIRXcbtOhRtUyyMf8JFmn1iT13vnl/IGVWSkdOCG/pC57U4S1jnAabAavTMwg==", "dev": true, "dependencies": { - "@babel/template": "^7.26.9", - "@babel/types": "^7.26.10" + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.3" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz", - "integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==", + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.3.tgz", + "integrity": "sha512-xyYxRj6+tLNDTWi0KCBcZ9V7yg3/lwL9DWh9Uwh/RIVlIfFidggcgxKX3GCXwCiswwcGRawBKbEg2LG/Y8eJhw==", "dev": true, "dependencies": { - "@babel/types": "^7.26.10" + "@babel/types": "^7.27.3" }, "bin": { "parser": "bin/babel-parser.js" @@ -261,12 +261,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", - "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", + "version": "7.27.1", + "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, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -276,12 +276,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", - "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", + "version": "7.27.1", + "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, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -291,30 +291,30 @@ } }, "node_modules/@babel/template": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", - "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/parser": "^7.26.9", - "@babel/types": "^7.26.9" + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.26.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.10.tgz", - "integrity": "sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==", + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.3.tgz", + "integrity": "sha512-lId/IfN/Ye1CIu8xG7oKBHXd2iNb2aW1ilPszzGcJug6M8RCKfVNcYhpI5+bMvFYjK7lXIM0R+a+6r8xhHp2FQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.10", - "@babel/parser": "^7.26.10", - "@babel/template": "^7.26.9", - "@babel/types": "^7.26.10", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.3", + "@babel/parser": "^7.27.3", + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.3", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -332,22 +332,22 @@ } }, "node_modules/@babel/types": { - "version": "7.26.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz", - "integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==", + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.3.tgz", + "integrity": "sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", - "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", + "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==", "cpu": [ "ppc64" ], @@ -361,9 +361,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz", - "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz", + "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==", "cpu": [ "arm" ], @@ -377,9 +377,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", - "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz", + "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==", "cpu": [ "arm64" ], @@ -393,9 +393,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz", - "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", + "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==", "cpu": [ "x64" ], @@ -409,9 +409,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", - "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", + "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==", "cpu": [ "arm64" ], @@ -425,9 +425,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", - "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", + "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==", "cpu": [ "x64" ], @@ -441,9 +441,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", - "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz", + "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==", "cpu": [ "arm64" ], @@ -457,9 +457,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", - "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz", + "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==", "cpu": [ "x64" ], @@ -473,9 +473,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", - "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz", + "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==", "cpu": [ "arm" ], @@ -489,9 +489,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", - "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz", + "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==", "cpu": [ "arm64" ], @@ -505,9 +505,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", - "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz", + "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==", "cpu": [ "ia32" ], @@ -521,9 +521,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", - "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz", + "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==", "cpu": [ "loong64" ], @@ -537,9 +537,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", - "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz", + "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==", "cpu": [ "mips64el" ], @@ -553,9 +553,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", - "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz", + "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==", "cpu": [ "ppc64" ], @@ -569,9 +569,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", - "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", + "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==", "cpu": [ "riscv64" ], @@ -585,9 +585,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", - "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz", + "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==", "cpu": [ "s390x" ], @@ -601,9 +601,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", - "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz", + "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==", "cpu": [ "x64" ], @@ -617,9 +617,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", - "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", + "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" ], @@ -633,9 +633,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", - "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz", + "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==", "cpu": [ "x64" ], @@ -649,9 +649,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", - "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", + "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" ], @@ -665,9 +665,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", - "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", + "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==", "cpu": [ "x64" ], @@ -681,9 +681,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", - "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", + "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==", "cpu": [ "x64" ], @@ -697,9 +697,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", - "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz", + "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==", "cpu": [ "arm64" ], @@ -713,9 +713,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", - "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz", + "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==", "cpu": [ "ia32" ], @@ -729,9 +729,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", - "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz", + "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==", "cpu": [ "x64" ], @@ -745,9 +745,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz", - "integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", "dev": true, "dependencies": { "eslint-visitor-keys": "^3.4.3" @@ -784,9 +784,9 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", - "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", + "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", "dev": true, "dependencies": { "@eslint/object-schema": "^2.1.6", @@ -798,18 +798,18 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.0.tgz", - "integrity": "sha512-yJLLmLexii32mGrhW29qvU3QBVTu0GUmEf/J4XsBtVhp4JkIUFN/BjWqTF63yRvGApIDpZm5fa97LtYtINmfeQ==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.2.tgz", + "integrity": "sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/core": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", - "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", + "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.15" @@ -854,12 +854,15 @@ } }, "node_modules/@eslint/js": { - "version": "9.23.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.23.0.tgz", - "integrity": "sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==", + "version": "9.27.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.27.0.tgz", + "integrity": "sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" } }, "node_modules/@eslint/object-schema": { @@ -872,12 +875,12 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", - "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.1.tgz", + "integrity": "sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==", "dev": true, "dependencies": { - "@eslint/core": "^0.12.0", + "@eslint/core": "^0.14.0", "levn": "^0.4.1" }, "engines": { @@ -933,9 +936,9 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", - "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, "engines": { "node": ">=18.18" @@ -993,10 +996,16 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.9", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.9.tgz", + "integrity": "sha512-e9MeMtVWo186sgvFFJOPGy7/d2j2mZhLJIdVW0C/xDluuOvymEATqz6zKsP0ZmXGzQtqlyjz5sC1sYQUoJG98w==", + "dev": true + }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.37.0.tgz", - "integrity": "sha512-l7StVw6WAa8l3vA1ov80jyetOAEo1FtHvZDbzXDO/02Sq/QVvqlHkYoFwDJPIMj0GKiistsBudfx5tGFnwYWDQ==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.41.1.tgz", + "integrity": "sha512-NELNvyEWZ6R9QMkiytB4/L4zSEaBC03KIXEghptLGLZWJ6VPrL63ooZQCOnlx36aQPGhzuOMwDerC1Eb2VmrLw==", "cpu": [ "arm" ], @@ -1007,9 +1016,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.37.0.tgz", - "integrity": "sha512-6U3SlVyMxezt8Y+/iEBcbp945uZjJwjZimu76xoG7tO1av9VO691z8PkhzQ85ith2I8R2RddEPeSfcbyPfD4hA==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.41.1.tgz", + "integrity": "sha512-DXdQe1BJ6TK47ukAoZLehRHhfKnKg9BjnQYUu9gzhI8Mwa1d2fzxA1aw2JixHVl403bwp1+/o/NhhHtxWJBgEA==", "cpu": [ "arm64" ], @@ -1020,9 +1029,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.37.0.tgz", - "integrity": "sha512-+iTQ5YHuGmPt10NTzEyMPbayiNTcOZDWsbxZYR1ZnmLnZxG17ivrPSWFO9j6GalY0+gV3Jtwrrs12DBscxnlYA==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.41.1.tgz", + "integrity": "sha512-5afxvwszzdulsU2w8JKWwY8/sJOLPzf0e1bFuvcW5h9zsEg+RQAojdW0ux2zyYAz7R8HvvzKCjLNJhVq965U7w==", "cpu": [ "arm64" ], @@ -1033,9 +1042,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.37.0.tgz", - "integrity": "sha512-m8W2UbxLDcmRKVjgl5J/k4B8d7qX2EcJve3Sut7YGrQoPtCIQGPH5AMzuFvYRWZi0FVS0zEY4c8uttPfX6bwYQ==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.41.1.tgz", + "integrity": "sha512-egpJACny8QOdHNNMZKf8xY0Is6gIMz+tuqXlusxquWu3F833DcMwmGM7WlvCO9sB3OsPjdC4U0wHw5FabzCGZg==", "cpu": [ "x64" ], @@ -1046,9 +1055,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.37.0.tgz", - "integrity": "sha512-FOMXGmH15OmtQWEt174v9P1JqqhlgYge/bUjIbiVD1nI1NeJ30HYT9SJlZMqdo1uQFyt9cz748F1BHghWaDnVA==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.41.1.tgz", + "integrity": "sha512-DBVMZH5vbjgRk3r0OzgjS38z+atlupJ7xfKIDJdZZL6sM6wjfDNo64aowcLPKIx7LMQi8vybB56uh1Ftck/Atg==", "cpu": [ "arm64" ], @@ -1059,9 +1068,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.37.0.tgz", - "integrity": "sha512-SZMxNttjPKvV14Hjck5t70xS3l63sbVwl98g3FlVVx2YIDmfUIy29jQrsw06ewEYQ8lQSuY9mpAPlmgRD2iSsA==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.41.1.tgz", + "integrity": "sha512-3FkydeohozEskBxNWEIbPfOE0aqQgB6ttTkJ159uWOFn42VLyfAiyD9UK5mhu+ItWzft60DycIN1Xdgiy8o/SA==", "cpu": [ "x64" ], @@ -1072,9 +1081,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.37.0.tgz", - "integrity": "sha512-hhAALKJPidCwZcj+g+iN+38SIOkhK2a9bqtJR+EtyxrKKSt1ynCBeqrQy31z0oWU6thRZzdx53hVgEbRkuI19w==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.41.1.tgz", + "integrity": "sha512-wC53ZNDgt0pqx5xCAgNunkTzFE8GTgdZ9EwYGVcg+jEjJdZGtq9xPjDnFgfFozQI/Xm1mh+D9YlYtl+ueswNEg==", "cpu": [ "arm" ], @@ -1085,9 +1094,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.37.0.tgz", - "integrity": "sha512-jUb/kmn/Gd8epbHKEqkRAxq5c2EwRt0DqhSGWjPFxLeFvldFdHQs/n8lQ9x85oAeVb6bHcS8irhTJX2FCOd8Ag==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.41.1.tgz", + "integrity": "sha512-jwKCca1gbZkZLhLRtsrka5N8sFAaxrGz/7wRJ8Wwvq3jug7toO21vWlViihG85ei7uJTpzbXZRcORotE+xyrLA==", "cpu": [ "arm" ], @@ -1098,9 +1107,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.37.0.tgz", - "integrity": "sha512-oNrJxcQT9IcbcmKlkF+Yz2tmOxZgG9D9GRq+1OE6XCQwCVwxixYAa38Z8qqPzQvzt1FCfmrHX03E0pWoXm1DqA==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.41.1.tgz", + "integrity": "sha512-g0UBcNknsmmNQ8V2d/zD2P7WWfJKU0F1nu0k5pW4rvdb+BIqMm8ToluW/eeRmxCared5dD76lS04uL4UaNgpNA==", "cpu": [ "arm64" ], @@ -1111,9 +1120,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.37.0.tgz", - "integrity": "sha512-pfxLBMls+28Ey2enpX3JvjEjaJMBX5XlPCZNGxj4kdJyHduPBXtxYeb8alo0a7bqOoWZW2uKynhHxF/MWoHaGQ==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.41.1.tgz", + "integrity": "sha512-XZpeGB5TKEZWzIrj7sXr+BEaSgo/ma/kCgrZgL0oo5qdB1JlTzIYQKel/RmhT6vMAvOdM2teYlAaOGJpJ9lahg==", "cpu": [ "arm64" ], @@ -1124,9 +1133,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.37.0.tgz", - "integrity": "sha512-yCE0NnutTC/7IGUq/PUHmoeZbIwq3KRh02e9SfFh7Vmc1Z7atuJRYWhRME5fKgT8aS20mwi1RyChA23qSyRGpA==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.41.1.tgz", + "integrity": "sha512-bkCfDJ4qzWfFRCNt5RVV4DOw6KEgFTUZi2r2RuYhGWC8WhCA8lCAJhDeAmrM/fdiAH54m0mA0Vk2FGRPyzI+tw==", "cpu": [ "loong64" ], @@ -1137,9 +1146,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.37.0.tgz", - "integrity": "sha512-NxcICptHk06E2Lh3a4Pu+2PEdZ6ahNHuK7o6Np9zcWkrBMuv21j10SQDJW3C9Yf/A/P7cutWoC/DptNLVsZ0VQ==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.41.1.tgz", + "integrity": "sha512-3mr3Xm+gvMX+/8EKogIZSIEF0WUu0HL9di+YWlJpO8CQBnoLAEL/roTCxuLncEdgcfJcvA4UMOf+2dnjl4Ut1A==", "cpu": [ "ppc64" ], @@ -1150,9 +1159,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.37.0.tgz", - "integrity": "sha512-PpWwHMPCVpFZLTfLq7EWJWvrmEuLdGn1GMYcm5MV7PaRgwCEYJAwiN94uBuZev0/J/hFIIJCsYw4nLmXA9J7Pw==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.41.1.tgz", + "integrity": "sha512-3rwCIh6MQ1LGrvKJitQjZFuQnT2wxfU+ivhNBzmxXTXPllewOF7JR1s2vMX/tWtUYFgphygxjqMl76q4aMotGw==", "cpu": [ "riscv64" ], @@ -1163,9 +1172,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.37.0.tgz", - "integrity": "sha512-DTNwl6a3CfhGTAOYZ4KtYbdS8b+275LSLqJVJIrPa5/JuIufWWZ/QFvkxp52gpmguN95eujrM68ZG+zVxa8zHA==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.41.1.tgz", + "integrity": "sha512-LdIUOb3gvfmpkgFZuccNa2uYiqtgZAz3PTzjuM5bH3nvuy9ty6RGc/Q0+HDFrHrizJGVpjnTZ1yS5TNNjFlklw==", "cpu": [ "riscv64" ], @@ -1176,9 +1185,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.37.0.tgz", - "integrity": "sha512-hZDDU5fgWvDdHFuExN1gBOhCuzo/8TMpidfOR+1cPZJflcEzXdCy1LjnklQdW8/Et9sryOPJAKAQRw8Jq7Tg+A==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.41.1.tgz", + "integrity": "sha512-oIE6M8WC9ma6xYqjvPhzZYk6NbobIURvP/lEbh7FWplcMO6gn7MM2yHKA1eC/GvYwzNKK/1LYgqzdkZ8YFxR8g==", "cpu": [ "s390x" ], @@ -1189,9 +1198,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.37.0.tgz", - "integrity": "sha512-pKivGpgJM5g8dwj0ywBwe/HeVAUSuVVJhUTa/URXjxvoyTT/AxsLTAbkHkDHG7qQxLoW2s3apEIl26uUe08LVQ==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.41.1.tgz", + "integrity": "sha512-cWBOvayNvA+SyeQMp79BHPK8ws6sHSsYnK5zDcsC3Hsxr1dgTABKjMnMslPq1DvZIp6uO7kIWhiGwaTdR4Og9A==", "cpu": [ "x64" ], @@ -1202,9 +1211,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.37.0.tgz", - "integrity": "sha512-E2lPrLKE8sQbY/2bEkVTGDEk4/49UYRVWgj90MY8yPjpnGBQ+Xi1Qnr7b7UIWw1NOggdFQFOLZ8+5CzCiz143w==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.41.1.tgz", + "integrity": "sha512-y5CbN44M+pUCdGDlZFzGGBSKCA4A/J2ZH4edTYSSxFg7ce1Xt3GtydbVKWLlzL+INfFIZAEg1ZV6hh9+QQf9YQ==", "cpu": [ "x64" ], @@ -1215,9 +1224,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.37.0.tgz", - "integrity": "sha512-Jm7biMazjNzTU4PrQtr7VS8ibeys9Pn29/1bm4ph7CP2kf21950LgN+BaE2mJ1QujnvOc6p54eWWiVvn05SOBg==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.41.1.tgz", + "integrity": "sha512-lZkCxIrjlJlMt1dLO/FbpZbzt6J/A8p4DnqzSa4PWqPEUUUnzXLeki/iyPLfV0BmHItlYgHUqJe+3KiyydmiNQ==", "cpu": [ "arm64" ], @@ -1228,9 +1237,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.37.0.tgz", - "integrity": "sha512-e3/1SFm1OjefWICB2Ucstg2dxYDkDTZGDYgwufcbsxTHyqQps1UQf33dFEChBNmeSsTOyrjw2JJq0zbG5GF6RA==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.41.1.tgz", + "integrity": "sha512-+psFT9+pIh2iuGsxFYYa/LhS5MFKmuivRsx9iPJWNSGbh2XVEjk90fmpUEjCnILPEPJnikAU6SFDiEUyOv90Pg==", "cpu": [ "ia32" ], @@ -1241,9 +1250,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.37.0.tgz", - "integrity": "sha512-LWbXUBwn/bcLx2sSsqy7pK5o+Nr+VCoRoAohfJ5C/aBio9nfJmGQqHAhU6pwxV/RmyTk5AqdySma7uwWGlmeuA==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.41.1.tgz", + "integrity": "sha512-Wq2zpapRYLfi4aKxf2Xff0tN+7slj2d4R87WEzqw7ZLsVvO5zwYCIuEGSZYiK41+GlwUo1HiR+GdkLEJnCKTCw==", "cpu": [ "x64" ], @@ -1267,9 +1276,9 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", "dev": true, "dependencies": { "@babel/types": "^7.0.0" @@ -1286,9 +1295,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz", + "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", "dev": true, "dependencies": { "@babel/types": "^7.20.7" @@ -1307,34 +1316,35 @@ "dev": true }, "node_modules/@types/react": { - "version": "19.0.12", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.12.tgz", - "integrity": "sha512-V6Ar115dBDrjbtXSrS+/Oruobc+qVbbUxDFC1RSbRqLt5SYvxxyIDrSC85RWml54g+jfNeEMZhEj7wW07ONQhA==", + "version": "19.1.6", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.6.tgz", + "integrity": "sha512-JeG0rEWak0N6Itr6QUx+X60uQmN+5t3j9r/OVDtWzFXKaj6kD1BwJzOksD0FF6iWxZlbE1kB0q9vtnU2ekqa1Q==", "dev": true, "dependencies": { "csstype": "^3.0.2" } }, "node_modules/@types/react-dom": { - "version": "19.0.4", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.0.4.tgz", - "integrity": "sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==", + "version": "19.1.5", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.5.tgz", + "integrity": "sha512-CMCjrWucUBZvohgZxkjd6S9h0nZxXjzus6yDfUb+xLxYM7VvjKNH1tQrE9GWLql1XoOP4/Ds3bwFqShHUYraGg==", "dev": true, "peerDependencies": { "@types/react": "^19.0.0" } }, "node_modules/@vitejs/plugin-react": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", - "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.5.0.tgz", + "integrity": "sha512-JuLWaEqypaJmOJPLWwO335Ig6jSgC1FTONCWAxnqcQthLTK/Yc9aH6hr9z/87xciejbQcnP3GnA1FWUSWeXaeg==", "dev": true, "dependencies": { - "@babel/core": "^7.26.0", + "@babel/core": "^7.26.10", "@babel/plugin-transform-react-jsx-self": "^7.25.9", "@babel/plugin-transform-react-jsx-source": "^7.25.9", + "@rolldown/pluginutils": "1.0.0-beta.9", "@types/babel__core": "^7.20.5", - "react-refresh": "^0.14.2" + "react-refresh": "^0.17.0" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -1415,9 +1425,9 @@ } }, "node_modules/axios": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", - "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", + "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -1441,9 +1451,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "version": "4.24.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.5.tgz", + "integrity": "sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==", "dev": true, "funding": [ { @@ -1460,10 +1470,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", + "caniuse-lite": "^1.0.30001716", + "electron-to-chromium": "^1.5.149", "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.1" + "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" @@ -1499,9 +1509,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001707", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001707.tgz", - "integrity": "sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==", + "version": "1.0.30001718", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz", + "integrity": "sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==", "dev": true, "funding": [ { @@ -1604,9 +1614,9 @@ "dev": true }, "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "dev": true, "dependencies": { "ms": "^2.1.3" @@ -1635,9 +1645,9 @@ } }, "node_modules/dotenv": { - "version": "16.4.7", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", - "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz", + "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==", "engines": { "node": ">=12" }, @@ -1667,9 +1677,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.123", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.123.tgz", - "integrity": "sha512-refir3NlutEZqlKaBLK0tzlVLe5P2wDKS7UQt/3SpibizgsRAPOsqQC3ffw1nlv3ze5gjRQZYHoPymgVZkplFA==", + "version": "1.5.158", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.158.tgz", + "integrity": "sha512-9vcp2xHhkvraY6AHw2WMi+GDSLPX42qe2xjYaVoZqFRJiOcilVQFq9mZmpuHEQpzlgGDelKlV7ZiGcmMsc8WxQ==", "dev": true }, "node_modules/es-define-property": { @@ -1714,9 +1724,9 @@ } }, "node_modules/esbuild": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", - "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", + "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==", "dev": true, "hasInstallScript": true, "bin": { @@ -1726,31 +1736,31 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.1", - "@esbuild/android-arm": "0.25.1", - "@esbuild/android-arm64": "0.25.1", - "@esbuild/android-x64": "0.25.1", - "@esbuild/darwin-arm64": "0.25.1", - "@esbuild/darwin-x64": "0.25.1", - "@esbuild/freebsd-arm64": "0.25.1", - "@esbuild/freebsd-x64": "0.25.1", - "@esbuild/linux-arm": "0.25.1", - "@esbuild/linux-arm64": "0.25.1", - "@esbuild/linux-ia32": "0.25.1", - "@esbuild/linux-loong64": "0.25.1", - "@esbuild/linux-mips64el": "0.25.1", - "@esbuild/linux-ppc64": "0.25.1", - "@esbuild/linux-riscv64": "0.25.1", - "@esbuild/linux-s390x": "0.25.1", - "@esbuild/linux-x64": "0.25.1", - "@esbuild/netbsd-arm64": "0.25.1", - "@esbuild/netbsd-x64": "0.25.1", - "@esbuild/openbsd-arm64": "0.25.1", - "@esbuild/openbsd-x64": "0.25.1", - "@esbuild/sunos-x64": "0.25.1", - "@esbuild/win32-arm64": "0.25.1", - "@esbuild/win32-ia32": "0.25.1", - "@esbuild/win32-x64": "0.25.1" + "@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" } }, "node_modules/escalade": { @@ -1775,19 +1785,19 @@ } }, "node_modules/eslint": { - "version": "9.23.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.23.0.tgz", - "integrity": "sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==", + "version": "9.27.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.27.0.tgz", + "integrity": "sha512-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.19.2", - "@eslint/config-helpers": "^0.2.0", - "@eslint/core": "^0.12.0", + "@eslint/config-array": "^0.20.0", + "@eslint/config-helpers": "^0.2.1", + "@eslint/core": "^0.14.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.23.0", - "@eslint/plugin-kit": "^0.2.7", + "@eslint/js": "9.27.0", + "@eslint/plugin-kit": "^0.3.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", @@ -1847,9 +1857,9 @@ } }, "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.19.tgz", - "integrity": "sha512-eyy8pcr/YxSYjBoqIFSrlbn9i/xvxUFa8CjzAYo9cFjgGXqq1hyjihcpZvxRLalpaWmueWR81xn7vuKmAFijDQ==", + "version": "0.4.20", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.20.tgz", + "integrity": "sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==", "dev": true, "peerDependencies": { "eslint": ">=8.40" @@ -2066,12 +2076,12 @@ } }, "node_modules/framer-motion": { - "version": "12.7.3", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.7.3.tgz", - "integrity": "sha512-dNT4l5gEnUo2ytXLUBUf6AI21dZ77TMclDKE3ElaIHZ8m90nJ/NCcExW51zdSIaS0RhAS5iXcF7bEIxZe8XG2g==", + "version": "12.15.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.15.0.tgz", + "integrity": "sha512-XKg/LnKExdLGugZrDILV7jZjI599785lDIJZLxMiiIFidCsy0a4R2ZEf+Izm67zyOuJgQYTHOmodi7igQsw3vg==", "dependencies": { - "motion-dom": "^12.7.3", - "motion-utils": "^12.7.2", + "motion-dom": "^12.15.0", + "motion-utils": "^12.12.1", "tslib": "^2.4.0" }, "peerDependencies": { @@ -2392,9 +2402,9 @@ } }, "node_modules/jsonwebtoken/node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "bin": { "semver": "bin/semver.js" }, @@ -2403,11 +2413,11 @@ } }, "node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", + "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", "dependencies": { - "buffer-equal-constant-time": "1.0.1", + "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } @@ -2567,11 +2577,11 @@ } }, "node_modules/motion": { - "version": "12.7.3", - "resolved": "https://registry.npmjs.org/motion/-/motion-12.7.3.tgz", - "integrity": "sha512-EGhzIg7vj+USH9SLNLjHRzglldWEletUZTEtBVKW7IJF+1Ig3RI5LnJmHQBNutuOIyeUbcF36MrNFT00etlc3g==", + "version": "12.15.0", + "resolved": "https://registry.npmjs.org/motion/-/motion-12.15.0.tgz", + "integrity": "sha512-HLouXyIb1uQFiZgJTYGrtEzbatPc6vK+HP+Qt6afLQjaudiGiLLVsoy71CwzD/Stlh06FUd5OpyiXqn6XvqjqQ==", "dependencies": { - "framer-motion": "^12.7.3", + "framer-motion": "^12.15.0", "tslib": "^2.4.0" }, "peerDependencies": { @@ -2592,17 +2602,17 @@ } }, "node_modules/motion-dom": { - "version": "12.7.3", - "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.7.3.tgz", - "integrity": "sha512-IjMt1YJHrvyvruFvmpmd6bGXXGCvmygrnvSb3aZ8KhOzF4H3PulU+cMBzH+U8TBJHjC/mnmJFRIA1Cu4vBfcBA==", + "version": "12.15.0", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.15.0.tgz", + "integrity": "sha512-D2ldJgor+2vdcrDtKJw48k3OddXiZN1dDLLWrS8kiHzQdYVruh0IoTwbJBslrnTXIPgFED7PBN2Zbwl7rNqnhA==", "dependencies": { - "motion-utils": "^12.7.2" + "motion-utils": "^12.12.1" } }, "node_modules/motion-utils": { - "version": "12.7.2", - "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.7.2.tgz", - "integrity": "sha512-XhZwqctxyJs89oX00zn3OGCuIIpVevbTa+u82usWBC6pSHUd2AoNWiYa7Du8tJxJy9TFbZ82pcn5t7NOm1PHAw==" + "version": "12.12.1", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.12.1.tgz", + "integrity": "sha512-f9qiqUHm7hWSLlNW8gS9pisnsN7CRFRD58vNjptKdsqFLpkVnX00TNeD6Q0d27V9KzT7ySFyK1TZ/DShfVOv6w==" }, "node_modules/ms": { "version": "2.1.3", @@ -2725,21 +2735,21 @@ } }, "node_modules/pg": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.14.1.tgz", - "integrity": "sha512-0TdbqfjwIun9Fm/r89oB7RFQ0bLgduAhiIqIXOsyKoiC/L54DbuAAzIEN/9Op0f1Po9X7iCPXGoa/Ah+2aI8Xw==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.0.tgz", + "integrity": "sha512-7SKfdvP8CTNXjMUzfcVTaI+TDzBEeaUnVwiVGZQD1Hh33Kpev7liQba9uLd4CfN8r9mCVsD0JIpq03+Unpz+kg==", "dependencies": { - "pg-connection-string": "^2.7.0", - "pg-pool": "^3.8.0", - "pg-protocol": "^1.8.0", - "pg-types": "^2.1.0", - "pgpass": "1.x" + "pg-connection-string": "^2.9.0", + "pg-pool": "^3.10.0", + "pg-protocol": "^1.10.0", + "pg-types": "2.2.0", + "pgpass": "1.0.5" }, "engines": { "node": ">= 8.0.0" }, "optionalDependencies": { - "pg-cloudflare": "^1.1.1" + "pg-cloudflare": "^1.2.5" }, "peerDependencies": { "pg-native": ">=3.0.1" @@ -2751,15 +2761,15 @@ } }, "node_modules/pg-cloudflare": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", - "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.5.tgz", + "integrity": "sha512-OOX22Vt0vOSRrdoUPKJ8Wi2OpE/o/h9T8X1s4qSkCedbNah9ei2W2765be8iMVxQUsvgT7zIAT2eIa9fs5+vtg==", "optional": true }, "node_modules/pg-connection-string": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.7.0.tgz", - "integrity": "sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==" + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.0.tgz", + "integrity": "sha512-P2DEBKuvh5RClafLngkAuGe9OUlFV7ebu8w1kmaaOgPcpJd1RIFh7otETfI6hAR8YupOLFTY7nuvvIn7PLciUQ==" }, "node_modules/pg-int8": { "version": "1.0.1", @@ -2770,17 +2780,17 @@ } }, "node_modules/pg-pool": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.8.0.tgz", - "integrity": "sha512-VBw3jiVm6ZOdLBTIcXLNdSotb6Iy3uOCwDGFAksZCXmi10nyRvnP2v3jl4d+IsLYRyXf6o9hIm/ZtUzlByNUdw==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.0.tgz", + "integrity": "sha512-DzZ26On4sQ0KmqnO34muPcmKbhrjmyiO4lCCR0VwEd7MjmiKf5NTg/6+apUEu0NF7ESa37CGzFxH513CoUmWnA==", "peerDependencies": { "pg": ">=8.0" } }, "node_modules/pg-protocol": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.8.0.tgz", - "integrity": "sha512-jvuYlEkL03NRvOoyoRktBK7+qU5kOvlAwvmrH8sr3wbLrOdVWsRxQfz8mMy9sZFsqJ1hEWNfdWKI4SAmoL+j7g==" + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.0.tgz", + "integrity": "sha512-IpdytjudNuLv8nhlHs/UrVBhU0e78J0oIS/0AVdTbWxSOkFUVdsHC/NrorO6nXsQNDTT1kzDSOMJubBQviX18Q==" }, "node_modules/pg-types": { "version": "2.2.0", @@ -2920,26 +2930,22 @@ } }, "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "dependencies": { - "loose-envify": "^1.1.0" - }, + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "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==", "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" + "scheduler": "^0.26.0" }, "peerDependencies": { - "react": "^18.3.1" + "react": "^19.1.0" } }, "node_modules/react-dropzone": { @@ -2972,22 +2978,21 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-refresh": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", - "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/react-router": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.5.2.tgz", - "integrity": "sha512-9Rw8r199klMnlGZ8VAsV/I8WrIF6IyJ90JQUdboupx1cdkgYqwnrYjH+I/nY/7cA1X5zia4mDJqH36npP7sxGQ==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.6.1.tgz", + "integrity": "sha512-hPJXXxHJZEsPFNVbtATH7+MMX43UDeOauz+EAU4cgqTn7ojdI9qQORqS8Z0qmDlL1TclO/6jLRYUEtbWidtdHQ==", "dependencies": { "cookie": "^1.0.1", - "set-cookie-parser": "^2.6.0", - "turbo-stream": "2.4.0" + "set-cookie-parser": "^2.6.0" }, "engines": { "node": ">=20.0.0" @@ -3003,11 +3008,11 @@ } }, "node_modules/react-router-dom": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.5.2.tgz", - "integrity": "sha512-yk1XW8Fj7gK7flpYBXF3yzd2NbX6P7Kxjvs2b5nu1M04rb5pg/Zc4fGdBNTeT4eDYL2bvzWNyKaIMJX/RKHTTg==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.6.1.tgz", + "integrity": "sha512-vxU7ei//UfPYQ3iZvHuO1D/5fX3/JOqhNTbRR+WjSBWxf9bIvpWK+ftjmdfJHzPOuMQKe2fiEdG+dZX6E8uUpA==", "dependencies": { - "react-router": "7.5.2" + "react-router": "7.6.1" }, "engines": { "node": ">=20.0.0" @@ -3027,12 +3032,12 @@ } }, "node_modules/rollup": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.37.0.tgz", - "integrity": "sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg==", + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.41.1.tgz", + "integrity": "sha512-cPmwD3FnFv8rKMBc1MxWCwVQFxwf1JEmSX3iQXrRVVG15zerAIXRjMFVWnd5Q5QvgKF7Aj+5ykXFhUl+QGnyOw==", "dev": true, "dependencies": { - "@types/estree": "1.0.6" + "@types/estree": "1.0.7" }, "bin": { "rollup": "dist/bin/rollup" @@ -3042,35 +3047,29 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.37.0", - "@rollup/rollup-android-arm64": "4.37.0", - "@rollup/rollup-darwin-arm64": "4.37.0", - "@rollup/rollup-darwin-x64": "4.37.0", - "@rollup/rollup-freebsd-arm64": "4.37.0", - "@rollup/rollup-freebsd-x64": "4.37.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.37.0", - "@rollup/rollup-linux-arm-musleabihf": "4.37.0", - "@rollup/rollup-linux-arm64-gnu": "4.37.0", - "@rollup/rollup-linux-arm64-musl": "4.37.0", - "@rollup/rollup-linux-loongarch64-gnu": "4.37.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.37.0", - "@rollup/rollup-linux-riscv64-gnu": "4.37.0", - "@rollup/rollup-linux-riscv64-musl": "4.37.0", - "@rollup/rollup-linux-s390x-gnu": "4.37.0", - "@rollup/rollup-linux-x64-gnu": "4.37.0", - "@rollup/rollup-linux-x64-musl": "4.37.0", - "@rollup/rollup-win32-arm64-msvc": "4.37.0", - "@rollup/rollup-win32-ia32-msvc": "4.37.0", - "@rollup/rollup-win32-x64-msvc": "4.37.0", + "@rollup/rollup-android-arm-eabi": "4.41.1", + "@rollup/rollup-android-arm64": "4.41.1", + "@rollup/rollup-darwin-arm64": "4.41.1", + "@rollup/rollup-darwin-x64": "4.41.1", + "@rollup/rollup-freebsd-arm64": "4.41.1", + "@rollup/rollup-freebsd-x64": "4.41.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.41.1", + "@rollup/rollup-linux-arm-musleabihf": "4.41.1", + "@rollup/rollup-linux-arm64-gnu": "4.41.1", + "@rollup/rollup-linux-arm64-musl": "4.41.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.41.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.41.1", + "@rollup/rollup-linux-riscv64-gnu": "4.41.1", + "@rollup/rollup-linux-riscv64-musl": "4.41.1", + "@rollup/rollup-linux-s390x-gnu": "4.41.1", + "@rollup/rollup-linux-x64-gnu": "4.41.1", + "@rollup/rollup-linux-x64-musl": "4.41.1", + "@rollup/rollup-win32-arm64-msvc": "4.41.1", + "@rollup/rollup-win32-ia32-msvc": "4.41.1", + "@rollup/rollup-win32-x64-msvc": "4.41.1", "fsevents": "~2.3.2" } }, - "node_modules/rollup/node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -3091,12 +3090,9 @@ ] }, "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "dependencies": { - "loose-envify": "^1.1.0" - } + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==" }, "node_modules/semver": { "version": "6.3.1", @@ -3175,9 +3171,9 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", - "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", "dev": true, "dependencies": { "fdir": "^6.4.4", @@ -3195,11 +3191,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, - "node_modules/turbo-stream": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz", - "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==" - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -3252,9 +3243,9 @@ } }, "node_modules/vite": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.3.tgz", - "integrity": "sha512-5nXH+QsELbFKhsEfWLkHrvgRpTdGJzqOZ+utSdmPTvwHmvU6ITTm3xx+mRusihkcI8GeC7lCDyn3kDtiki9scw==", + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", + "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", "dev": true, "dependencies": { "esbuild": "^0.25.0", diff --git a/package.json b/package.json index a8fd2b9..cf8d5f7 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,8 @@ "preview": "vite preview" }, "dependencies": { - "@azure/msal-browser": "^4.8.0", - "@azure/msal-react": "^3.0.7", + "@azure/msal-browser": "^4.12.0", + "@azure/msal-react": "^3.0.12", "axios": "^1.8.3", "dotenv": "^16.0.3", "framer-motion": "^12.7.3", @@ -21,16 +21,16 @@ "jwt-decode": "^4.0.0", "motion": "^12.7.3", "pg": "^8.8.0", - "react": "^18.3.1", - "react-dom": "^18.3.1", + "react": "^19.1.0", + "react-dom": "^19.1.0", "react-dropzone": "^14.3.8", "react-icons": "^5.5.0", "react-router-dom": "^7.5.0" }, "devDependencies": { "@eslint/js": "^9.21.0", - "@types/react": "^19.0.10", - "@types/react-dom": "^19.0.4", + "@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", diff --git a/src/App.tsx b/src/App.tsx index e10dc56..399b49f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,6 +8,7 @@ import { ProtectedRoute } from './auth/ProtectedRoute'; import Home from './pages/Home'; import Dateien from './pages/Dateien/Dateien'; import Mitglieder from './pages/Mitglieder/Mitglieder'; +import Dashboard from './pages/Dashboard'; function App() { return ( @@ -22,6 +23,7 @@ function App() { }> + } /> } /> } /> diff --git a/src/api.ts b/src/api.ts index ba0d1c0..c9fdf24 100644 --- a/src/api.ts +++ b/src/api.ts @@ -2,8 +2,8 @@ import axios from 'axios'; const api = axios.create({ - baseURL: 'https://gateway.poweron-center.net', - /*baseURL: 'http://localhost:8000',*/ + //baseURL: 'https://gateway.poweron-center.net', + baseURL: 'http://localhost:8000', withCredentials: true }); diff --git a/src/components/Dashboard/DashboardChat/DashboardChat.module.css b/src/components/Dashboard/DashboardChat/DashboardChat.module.css new file mode 100644 index 0000000..c4b9b35 --- /dev/null +++ b/src/components/Dashboard/DashboardChat/DashboardChat.module.css @@ -0,0 +1,304 @@ +.dashboard_chat { + display: flex; + padding: 20px; + flex-direction: column; + align-self: stretch; + border-radius: 30px; + border: 1px solid var(--f-1-f-1-f-1, #F1F1F1); + background: var(--Grayscale-True-White, #FFF); + position: relative; + box-shadow: 0px 2px 6px 0px rgba(194, 194, 194, 0.10); + height: 100%; + min-height: 0; + overflow: hidden; + +} + +.dashboard_chat.expanded { + width: 100%; +} + +.chat_header { + display: flex; + justify-content: space-between; + align-items: flex-start; + flex-shrink: 0; +} + +.chat_button_div { + display: flex; + gap: 20px; + align-items: flex-start; +} + +.buttonWrapper { + display: flex; + flex-direction: column; + position: relative; +} + +.chat_button { + text-align: center; + font-size: 14px; + font-style: normal; + font-weight: 500; + line-height: normal; + border: none; + background: none; + outline: none; + cursor: pointer; + padding: 0; + transition: all 0.2s ease; +} + +.chat_button_active { + color: var(--Grayscale-Black, #24262B); +} + +.chat_button_inactive { + color: #A0A0A0; +} + +.chat_button_collapsed { + opacity: 50%; + color: #A0A0A0; +} + +.iconContainer { + display: flex; + gap: 10px; + align-items: center; +} + +.expandIcon, .collapseIcon { + cursor: pointer; + display: flex; + align-items: center; + color: var(--Brand-Green-Green, #3A8088); +} + +.expandIcon:hover, .collapseIcon:hover { + color: #333; +} + +.horizontalLine { + width: 100%; + background-color: black; + height: 2px; + margin-top: 19px; +} + +.horizontalLineLight { + width: calc(100%); + background-color: #F1F1F1; + height: 2px; + margin-top: 39px; + margin-left: -20px; + position: absolute; + flex-shrink: 0; +} + +.chat_content { + display: flex; + flex-direction: column; + flex: 1; + margin-top: 20px; + min-height: 0; + overflow: hidden; +} + +.chat_messages { + flex: 1; + padding: 15px; + border-radius: 15px; + margin-bottom: 15px; + min-height: 200px; + overflow-y: auto; + overflow-x: hidden; + scroll-behavior: smooth; +} + +.chat_input { + display: flex; + gap: 10px; + align-items: center; + flex-shrink: 0; +} + +.message_input { + flex: 1; + padding: 12px 16px; + border: 1px solid #E0E0E0; + border-radius: 12px; + outline: none; + font-size: 14px; +} + +.message_input:focus { + border-color: #666; +} + +.send_button { + padding: 12px 12px; + background-color: var(--Brand-Green-Green, #3A8088); + color: white; + border: none; + border-radius: 12px; + cursor: pointer; + font-size: 14px; + font-weight: 500; + display: flex; + align-items: center; + justify-content: center; +} + +.send_button_icon { + height: 100%; + width: 100%; + margin: none; + padding: none; +} + +.send_button:disabled { + background-color: #ccc; + cursor: not-allowed; + opacity: 0.6; +} + +.message_input:disabled { + background-color: #f5f5f5; + cursor: not-allowed; + opacity: 0.6; +} + +.loading_message { + padding: 10px; + background-color: #e3f2fd; + border-left: 4px solid #2196f3; + border-radius: 4px; + margin-bottom: 10px; +} + +.loading_message p { + margin: 0; + color: #1976d2; + font-size: 14px; +} + +.error_message { + padding: 10px; + background-color: #ffebee; + border-left: 4px solid #f44336; + border-radius: 4px; + margin-bottom: 10px; +} + +.error_message p { + margin: 0; + color: #c62828; + font-size: 14px; +} + +.message { + margin-bottom: 15px; + padding: 12px; + border-radius: 12px; + max-width: 80%; +} + +.message_user { + background-color: var(--Brand-Green-Green, #3A8088); + color: white; + margin-left: auto; + margin-right: 0; +} + +.message_assistant { + background-color: #f5f5f5; + color: #333; + margin-left: 0; + margin-right: auto; +} + +.message_system { + background-color: #fff3cd; + color: #856404; + margin-left: auto; + margin-right: auto; + text-align: center; +} + +.message_role { + font-size: 12px; + font-weight: 600; + margin-bottom: 4px; + opacity: 0.8; +} + +.message_content { + font-size: 14px; + line-height: 1.4; + white-space: pre-wrap; + word-wrap: break-word; +} + +.message_timestamp { + font-size: 11px; + margin-top: 4px; + opacity: 0.6; +} + +.placeholder_text { + text-align: center; + color: #999; + font-style: italic; + margin: 20px 0; +} + +.workflow_status { + padding: 8px 12px; + background-color: #e8f5e8; + border-left: 4px solid #4caf50; + border-radius: 4px; + margin-bottom: 10px; +} + +.workflow_status p { + margin: 0; + color: #2e7d32; + font-size: 13px; + font-style: italic; +} + +.completion_message { + padding: 10px 12px; + background-color: #e8f5e8; + border-left: 4px solid #4caf50; + border-radius: 4px; + margin-bottom: 10px; + text-align: center; +} + +.completion_message p { + margin: 0 0 10px 0; + color: #2e7d32; + font-size: 14px; + font-weight: 600; +} + +.new_workflow_button { + background-color: var(--Brand-Green-Green, #3A8088); + color: white; + border: none; + border-radius: 8px; + padding: 8px 16px; + font-size: 12px; + font-weight: 500; + cursor: pointer; + transition: background-color 0.2s ease; +} + +.new_workflow_button:hover { + background-color: #2d6b73; +} + diff --git a/src/components/Dashboard/DashboardChat/DashboardChat.tsx b/src/components/Dashboard/DashboardChat/DashboardChat.tsx new file mode 100644 index 0000000..743e0d6 --- /dev/null +++ b/src/components/Dashboard/DashboardChat/DashboardChat.tsx @@ -0,0 +1,134 @@ +import React, { useState } from "react"; +import { BsArrowsAngleExpand, BsArrowsAngleContract } from "react-icons/bs"; +import { motion, AnimatePresence } from "framer-motion"; +import { Prompt } from "../../../hooks/usePrompts"; + +import DashboardChatArea from './DashboardChatArea/DashboardChatArea'; +import DashboardChatHistory from './DashboardChatHistory/DashboardChatHistory'; + +import styles from './DashboardChat.module.css'; + +interface DashboardChatProps { + isExpanded: boolean; + onToggleExpand: () => void; + selectedPrompt?: Prompt | null; + onPromptUsed?: () => void; + onWorkflowIdChange?: (workflowId: string | null) => void; + onWorkflowResume?: (workflowId: string) => void; +} + +const DashboardChat: React.FC = ({ + isExpanded, + onToggleExpand, + selectedPrompt, + onPromptUsed, + onWorkflowIdChange, + onWorkflowResume +}) => { + const [activeTab, setActiveTab] = useState("Chat Area"); + const [resumeWorkflowId, setResumeWorkflowId] = useState(null); + + const handleWorkflowResume = (workflowId: string) => { + // Switch to Chat Area tab first + setActiveTab("Chat Area"); + // Set the workflow ID to resume + setResumeWorkflowId(workflowId); + // Then call the parent's resume handler + if (onWorkflowResume) { + onWorkflowResume(workflowId); + } + // Clear the resume ID after a short delay to allow processing + setTimeout(() => { + setResumeWorkflowId(null); + }, 100); + }; + + return ( + + +
+ {["Chat Area", "Workflow History"].map((tab) => ( +
+ setActiveTab(tab)} + whileHover={{ scale: 1.05 }} + whileTap={{ scale: 0.98 }} + > + {tab} + + + {activeTab === tab && ( + + )} + +
+ ))} +
+
+ + {isExpanded ? : } + +
+
+ + + {activeTab === "Chat Area" ? ( + + ) : ( + + )} + +
+ ); +}; + +export default DashboardChat; \ No newline at end of file diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatArea.module.css b/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatArea.module.css new file mode 100644 index 0000000..3415626 --- /dev/null +++ b/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatArea.module.css @@ -0,0 +1,226 @@ +.chat_area { + display: flex; + flex-direction: column; + flex: 1; + min-height: 0; + overflow: hidden; +} + +.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: #ccc; + border-radius: 3px; +} + +.chat_messages::-webkit-scrollbar-thumb:hover { + background: #999; +} + +.messages_container { + min-height: 100%; + display: flex; + flex-direction: column; + justify-content: flex-end; +} + +.chat_input { + display: flex; + gap: 10px; + align-items: center; + flex-shrink: 0; +} + +.message_input { + flex: 1; + padding: 12px 16px; + border: 1px solid #E0E0E0; + border-radius: 12px; + outline: none; + font-size: 14px; +} + +.message_input:focus { + border-color: #666; +} + +.message_input:disabled { + background-color: #f5f5f5; + cursor: not-allowed; + opacity: 0.6; +} + +.send_button { + padding: 12px 12px; + background-color: var(--Brand-Green-Green, #3A8088); + color: white; + border: none; + border-radius: 12px; + cursor: pointer; + font-size: 14px; + font-weight: 500; + display: flex; + align-items: center; + justify-content: center; +} + +.send_button_icon { + height: 100%; + width: 100%; + margin: none; + padding: none; +} + +.send_button:disabled { + background-color: #ccc; + cursor: not-allowed; + opacity: 0.6; +} + +.loading_message { + padding: 10px; + background-color: #e3f2fd; + border-left: 4px solid #2196f3; + border-radius: 4px; + margin-bottom: 10px; +} + +.loading_message p { + margin: 0; + color: #1976d2; + font-size: 14px; +} + +.error_message { + padding: 10px; + background-color: #ffebee; + border-left: 4px solid #f44336; + border-radius: 4px; + margin-bottom: 10px; +} + +.error_message p { + margin: 0; + color: #c62828; + font-size: 14px; +} + +.message { + margin-bottom: 15px; + padding: 12px; + border-radius: 12px; + max-width: 80%; +} + +.message_user { + background-color: var(--Brand-Green-Green, #3A8088); + color: white; + margin-left: auto; + margin-right: 0; +} + +.message_assistant { + background-color: #f5f5f5; + color: #333; + margin-left: 0; + margin-right: auto; +} + +.message_system { + background-color: #fff3cd; + color: #856404; + margin-left: auto; + margin-right: auto; + text-align: center; +} + +.message_role { + font-size: 12px; + font-weight: 600; + margin-bottom: 4px; + opacity: 0.8; +} + +.message_content { + font-size: 14px; + line-height: 1.4; + white-space: pre-wrap; + word-wrap: break-word; +} + +.message_timestamp { + font-size: 11px; + margin-top: 4px; + opacity: 0.6; +} + +.placeholder_text { + text-align: center; + color: #999; + font-style: italic; + margin: 20px 0; +} + +.workflow_status { + padding: 8px 12px; + background-color: #e8f5e8; + border-left: 4px solid #4caf50; + border-radius: 4px; + margin-bottom: 10px; +} + +.workflow_status p { + margin: 0; + color: #2e7d32; + font-size: 13px; + font-style: italic; +} + +.completion_message { + padding: 10px 12px; + background-color: #e8f5e8; + border-left: 4px solid #4caf50; + border-radius: 4px; + margin-bottom: 10px; + text-align: center; +} + +.completion_message p { + margin: 0 0 10px 0; + color: #2e7d32; + font-size: 14px; + font-weight: 600; +} + +.new_workflow_button { + background-color: var(--Brand-Green-Green, #3A8088); + color: white; + border: none; + border-radius: 8px; + padding: 8px 16px; + font-size: 12px; + font-weight: 500; + cursor: pointer; + transition: background-color 0.2s ease; +} + +.new_workflow_button:hover { + background-color: #2d6b73; +} \ No newline at end of file diff --git a/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatArea.tsx b/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatArea.tsx new file mode 100644 index 0000000..f6057f3 --- /dev/null +++ b/src/components/Dashboard/DashboardChat/DashboardChatArea/DashboardChatArea.tsx @@ -0,0 +1,278 @@ +import React, { useState, useEffect, useRef } from "react"; +import { motion } from "framer-motion"; +import { LuSendHorizontal } from "react-icons/lu"; +import { Prompt } from "../../../../hooks/usePrompts"; +import { useWorkflowOperations, useWorkflowMessages, useWorkflowStatus } from "../../../../hooks/useWorkflows"; + +import styles from './DashboardChatArea.module.css'; + +interface DashboardChatAreaProps { + selectedPrompt?: Prompt | null; + onPromptUsed?: () => void; + onWorkflowIdChange?: (workflowId: string | null) => void; + resumeWorkflowId?: string | null; +} + +const DashboardChatArea: React.FC = ({ + selectedPrompt, + onPromptUsed, + onWorkflowIdChange, + resumeWorkflowId +}) => { + const [inputValue, setInputValue] = useState(""); + const [currentWorkflowId, setCurrentWorkflowId] = useState(null); + const [workflowCompleted, setWorkflowCompleted] = useState(false); + const inputRef = useRef(null); + const messagesEndRef = useRef(null); + const { startWorkflow, startingWorkflow, startError } = useWorkflowOperations(); + const { messages, loading: messagesLoading, error: messagesError, refetch: refetchMessages } = useWorkflowMessages(currentWorkflowId); + const { status: workflowStatus, refetch: refetchStatus } = useWorkflowStatus(currentWorkflowId); + + // 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 + useEffect(() => { + if (messagesEndRef.current) { + messagesEndRef.current.scrollIntoView({ behavior: 'smooth' }); + } + }, [messages]); + + // 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]); + + // Check if workflow is completed based on status or messages + useEffect(() => { + if (workflowStatus && ( + workflowStatus.status === 'completed' || + workflowStatus.status === 'finished' || + workflowStatus.status === 'done' || + workflowStatus.status === 'stopped' + )) { + setWorkflowCompleted(true); + return; + } + + if (messages.length > 0) { + const lastMessage = messages[messages.length - 1]; + // Check if the last message indicates completion + if (lastMessage.role === 'assistant' && + (lastMessage.content.toLowerCase().includes('completed') || + lastMessage.content.toLowerCase().includes('finished') || + lastMessage.content.toLowerCase().includes('done') || + lastMessage.content.toLowerCase().includes('workflow completed'))) { + setWorkflowCompleted(true); + } + } + }, [messages, workflowStatus]); + + const handleSend = async () => { + if (inputValue.trim()) { + console.log('Sending message:', inputValue); + + try { + let result; + + // 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, + listFileId: [] + }, currentWorkflowId); + + if (result.success) { + console.log('Follow-up message sent successfully'); + // Reset workflow completion state to resume polling + 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, + 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 after successful send + setInputValue(""); + // 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(""); + if (onWorkflowIdChange) { + onWorkflowIdChange(null); + } + }; + + useEffect(() => { + if (currentWorkflowId && onWorkflowIdChange) { + onWorkflowIdChange(currentWorkflowId); + } + }, [currentWorkflowId, onWorkflowIdChange]); + + // Handle workflow resumption + useEffect(() => { + if (resumeWorkflowId && resumeWorkflowId !== currentWorkflowId) { + console.log('Resuming workflow:', resumeWorkflowId); + setCurrentWorkflowId(resumeWorkflowId); + setWorkflowCompleted(false); + setInputValue(""); + } + }, [resumeWorkflowId, currentWorkflowId]); + + return ( +
+ +
+ {startingWorkflow && ( +
+

{workflowCompleted && currentWorkflowId ? 'Sending follow-up message...' : 'Sending message...'}

+
+ )} + {startError && ( +
+

Error: {startError}

+
+ )} + {messagesError && ( +
+

Error loading messages: {messagesError}

+
+ )} + {currentWorkflowId && messagesLoading && messages.length === 0 && ( +
+

Loading workflow messages...

+
+ )} + {messages.length > 0 ? ( + messages.map((message, index) => ( +
+
+ {message.role === 'user' ? 'You' : + message.role === 'assistant' ? 'Assistant' : 'System'} +
+
+ {message.content} +
+ {message.timestamp && ( +
+ {new Date(message.timestamp).toLocaleTimeString()} +
+ )} +
+ )) + ) : !currentWorkflowId ? ( +

Start a conversation by typing a message...

+ ) : null} + {currentWorkflowId && !workflowCompleted && ( +
+

+ Workflow {currentWorkflowId.substring(0, 8)}... is {workflowStatus?.status || 'running'} + {workflowStatus?.currentRound && ` (Round ${workflowStatus.currentRound})`} +

+
+ )} + {workflowCompleted && ( +
+

Workflow completed! You can continue the conversation or start a new workflow.

+ +
+ )} +
+
+ + + setInputValue(e.target.value)} + onKeyPress={handleKeyPress} + placeholder={workflowCompleted ? "Continue the conversation..." : "Type your message..."} + className={styles.message_input} + disabled={startingWorkflow} + /> + + + + +
+ ); +}; + +export default DashboardChatArea; \ No newline at end of file diff --git a/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistory.module.css b/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistory.module.css new file mode 100644 index 0000000..e3fd1d3 --- /dev/null +++ b/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistory.module.css @@ -0,0 +1,120 @@ +.chat_history { + height: 100%; + display: flex; + flex-direction: column; + overflow: hidden; +} + +.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: #333; + margin: 0; +} + +.workflowCount { + font-size: 14px; + color: #666; + background-color: #f5f5f5; + padding: 4px 12px; + border-radius: 12px; +} + +.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: #999; + font-size: 16px; + text-align: center; +} + +.loadingContainer { + display: flex; + align-items: center; + justify-content: center; + height: 200px; +} + +.loadingText { + color: #666; + font-size: 16px; +} + +.errorContainer { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 200px; + gap: 16px; +} + +.errorText { + color: #f44336; + font-size: 16px; + text-align: center; +} + +.retryButton { + background-color: #2196F3; + color: white; + border: none; + padding: 8px 16px; + border-radius: 8px; + cursor: pointer; + font-size: 14px; + transition: background-color 0.2s ease; +} + +.retryButton:hover { + background-color: #1976D2; +} + +/* Scrollbar styling */ +.scrollableContent::-webkit-scrollbar { + width: 6px; +} + +.scrollableContent::-webkit-scrollbar-track { + background: #f1f1f1; + border-radius: 3px; +} + +.scrollableContent::-webkit-scrollbar-thumb { + background: #c1c1c1; + border-radius: 3px; +} + +.scrollableContent::-webkit-scrollbar-thumb:hover { + background: #a8a8a8; +} \ No newline at end of file diff --git a/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistory.tsx b/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistory.tsx new file mode 100644 index 0000000..383dc77 --- /dev/null +++ b/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistory.tsx @@ -0,0 +1,96 @@ +import React from "react"; +import { motion } from "framer-motion"; +import { useWorkflows } from "../../../../hooks/useWorkflows"; +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 handleWorkflowResume = (workflowId: string) => { + if (onWorkflowResume) { + onWorkflowResume(workflowId); + } + console.log('Resuming workflow:', workflowId); + }; + + if (loading) { + return ( + +
+
Loading workflows...
+
+
+ ); + } + + if (error) { + return ( + +
+
Error loading workflows: {error}
+ +
+
+ ); + } + + return ( + +
+
+

Workflow History

+
+ {workflows.length} {workflows.length === 1 ? 'Workflow' : 'Workflows'} +
+
+ +
+ {workflows.length === 0 ? ( +
+ 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 new file mode 100644 index 0000000..4ec8bcb --- /dev/null +++ b/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistoryItem.module.css @@ -0,0 +1,178 @@ +.workflowItem { + background: white; + border-radius: 12px; + border: 1px solid #e0e0e0; + margin-bottom: 12px; + transition: all 0.2s ease; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); +} + +.workflowItem:hover { + border-color: #d0d0d0; + 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: #333; + margin: 0 0 8px 0; + line-height: 1.2; +} + +.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: rgba(0, 0, 0, 0.05); +} + +.workflowRound { + font-size: 12px; + color: #666; + background-color: #f5f5f5; + padding: 2px 6px; + border-radius: 8px; +} + +.workflowDates { + display: flex; + flex-direction: column; + gap: 2px; +} + +.workflowDate { + font-size: 12px; + color: #666; + margin: 0; + line-height: 1.3; +} + +.workflowDescription { + margin-top: 8px; +} + +.messagePreview { + margin-bottom: 8px; + padding: 8px; + background-color: #f8f9fa; + border-radius: 6px; + border-left: 3px solid #2196F3; +} + +.previewLabel { + font-size: 11px; + font-weight: 600; + color: #666; + text-transform: uppercase; + letter-spacing: 0.5px; + display: block; + margin-bottom: 4px; +} + +.previewText { + font-size: 13px; + color: #444; + margin: 0; + line-height: 1.4; + word-break: break-word; + font-style: italic; +} + +.workflowName { + font-size: 14px; + color: #555; + margin: 0; + line-height: 1.4; + word-break: break-word; +} + +.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: #4CAF50; + color: white; +} + +.resumeButton:hover:not(:disabled) { + background-color: #45a049; + transform: translateY(-1px); +} + +.deleteButton { + background-color: #f44336; + color: white; +} + +.deleteButton:hover:not(:disabled) { + background-color: #da190b; + transform: translateY(-1px); +} + +.deletingMessage { + padding: 8px 16px; + background-color: #fff3cd; + border-top: 1px solid #e0e0e0; + color: #856404; + font-size: 12px; + text-align: center; +} + +@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 new file mode 100644 index 0000000..78194b5 --- /dev/null +++ b/src/components/Dashboard/DashboardChat/DashboardChatHistory/DashboardChatHistoryItem.tsx @@ -0,0 +1,155 @@ +import React, { useState, useEffect } from 'react'; +import { FaArrowRight } from 'react-icons/fa'; +import { AiOutlineDelete } from 'react-icons/ai'; +import { useWorkflowOperations, useWorkflowMessages, Workflow } from '../../../../hooks/useWorkflows'; +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 isDeleting = deletingWorkflows.has(workflow.id); + + // Get the first user message as preview + const firstUserMessage = messages.find(msg => msg.role === 'user'); + const messagePreview = firstUserMessage?.content || 'No message content available'; + + const handleDelete = async () => { + if (window.confirm(`Are you sure you want to delete workflow "${workflow.id.substring(0, 8)}..."?`)) { + const success = await deleteWorkflow(workflow.id); + if (success && onDelete) { + onDelete(); + } + } + }; + + const handleResume = () => { + onResume(workflow.id); + }; + + const formatDate = (dateString?: string) => { + if (!dateString) return '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 'Invalid date'; + } + }; + + const getStatusColor = (status: string) => { + switch (status.toLowerCase()) { + case 'completed': + case 'finished': + case 'done': + return '#4CAF50'; + case 'running': + case 'processing': + return '#2196F3'; + case 'error': + case 'failed': + return '#F44336'; + case 'stopped': + case 'cancelled': + return '#FF9800'; + default: + return '#9E9E9E'; + } + }; + + const truncateMessage = (message: string, maxLength: number = 150) => { + if (message.length <= maxLength) return message; + return message.substring(0, maxLength) + '...'; + }; + + return ( +
+
+
+
+

+ Workflow {workflow.id.substring(0, 8)}... +

+
+ + {workflow.status.toUpperCase()} + + {workflow.currentRound && ( + + Round {workflow.currentRound} + + )} +
+
+ {workflow.startedAt && ( +

+ Started: {formatDate(workflow.startedAt)} +

+ )} + {workflow.lastActivity && ( +

+ Last Activity: {formatDate(workflow.lastActivity)} +

+ )} +
+
+ +
+
+ First message: +

+ {truncateMessage(messagePreview)} +

+
+ {workflow.name && ( +

+ {workflow.name} +

+ )} +
+
+ +
+ + + +
+
+ + {isDeleting && ( +
+ Deleting workflow... +
+ )} +
+ ); +} + +export default DashboardChatHistoryItem; \ No newline at end of file diff --git a/src/components/Dashboard/DashboardLog/DashboardLog.module.css b/src/components/Dashboard/DashboardLog/DashboardLog.module.css new file mode 100644 index 0000000..cd8c775 --- /dev/null +++ b/src/components/Dashboard/DashboardLog/DashboardLog.module.css @@ -0,0 +1,307 @@ +.dashboard_log { + display: flex; + padding: 20px; + flex-direction: column; + align-self: stretch; + border-radius: 30px; + border: 1px solid var(--f-1-f-1-f-1, #F1F1F1); + background: var(--Grayscale-True-White, #FFF); + position: relative; + box-shadow: 0px 2px 6px 0px rgba(194, 194, 194, 0.10); + height: 100%; + width: 100%; + min-height: 0; + overflow: hidden; +} + +.dashboard_log.expanded { + width: 100%; +} + +.log_header { + display: flex; + justify-content: space-between; + align-items: flex-start; + width: 100%; + flex-shrink: 0; +} + +.log_title_div { + display: flex; + flex-direction: column; +} + +.log_title { + text-align: center; + font-size: 14px; + font-style: normal; + font-weight: 500; + line-height: normal; + border: none; + background: none; + outline: none; + color: var(--Grayscale-Black, #24262B); + cursor: default; +} + +.log_title_collapsed { + opacity: 50%; + color: #A0A0A0; +} + +.collapseIcon { + cursor: pointer; + display: flex; + align-items: center; + color: #666; +} + +.collapseIcon:hover { + color: #333; +} + +.horizontalLine { + width: 100%; + background-color: black; + height: 2px; + margin-top: 19px; +} + +.horizontalLineLight { + width: calc(100%); + background-color: #F1F1F1; + height: 2px; + margin-top: 39px; + margin-left: -20px; + position: absolute; + flex-shrink: 0; +} + +.log_content { + margin-top: 20px; + flex: 1; + min-height: 0; + overflow: hidden; + display: flex; + flex-direction: column; +} + +.log_entries { + background-color: #f9f9f9; + border-radius: 15px; + padding: 15px; + height: 100%; + overflow-y: auto; + font-family: 'Courier New', monospace; +} + +.log_entry { + display: flex; + gap: 15px; + padding: 8px 0; + border-bottom: 1px solid #e0e0e0; + align-items: center; + font-size: 12px; +} + +.log_entry:last-child { + border-bottom: none; +} + +.log_timestamp { + color: #666; + min-width: 140px; + font-weight: 500; +} + +.log_level_info { + background-color: #4CAF50; + color: white; + padding: 2px 8px; + border-radius: 30px; + font-size: 10px; + font-weight: bold; + min-width: 45px; + text-align: center; +} + +.log_level_warning { + background-color: #FF9800; + color: white; + padding: 2px 8px; + border-radius: 30px; + font-size: 10px; + font-weight: bold; + min-width: 45px; + text-align: center; +} + +.log_level_error { + background-color: #F44336; + color: white; + padding: 2px 8px; + border-radius: 12px; + font-size: 10px; + font-weight: bold; + min-width: 45px; + text-align: center; +} + +.log_message { + flex: 1; + color: #333; +} + +/* Hacker-style console styles */ +.console_container { + background-color: #0a0a0a; + border-radius: 8px; + padding: 15px; + flex: 1; + min-height: 200px; + overflow-y: auto; + font-family: 'Courier New', 'Monaco', 'Menlo', monospace; + font-size: 12px; + line-height: 1.4; + color: #00ff00; + border: 1px solid #333; + box-shadow: inset 0 0 10px rgba(0, 255, 0, 0.1); + display: flex; + flex-direction: column; +} + +.console_container::-webkit-scrollbar { + width: 8px; +} + +.console_container::-webkit-scrollbar-track { + background: #1a1a1a; + border-radius: 4px; +} + +.console_container::-webkit-scrollbar-thumb { + background: #333; + border-radius: 4px; +} + +.console_container::-webkit-scrollbar-thumb:hover { + background: #555; +} + +.console_content { + flex: 1; + display: flex; + flex-direction: column; + gap: 2px; +} + +.console_line { + display: flex; + flex-wrap: wrap; + margin-bottom: 2px; + animation: fadeIn 0.3s ease-in; +} + +.console_timestamp { + color: #888; + margin-right: 8px; + font-weight: bold; + min-width: 80px; +} + +.console_level { + margin-right: 8px; + font-weight: bold; + min-width: 60px; +} + +.console_message { + color: #00ff00; + flex: 1; + word-break: break-word; +} + +.console_data { + width: 100%; + margin-top: 4px; + margin-left: 20px; + color: #00aaff; + font-size: 11px; + white-space: pre-wrap; + background-color: rgba(0, 170, 255, 0.1); + padding: 8px; + border-radius: 4px; + border-left: 3px solid #00aaff; +} + +.console_prompt { + color: #00ff00; + margin-right: 8px; + font-weight: bold; +} + +.console_text { + color: #00ff00; +} + +.console_placeholder { + display: flex; + align-items: center; + opacity: 0.7; + font-style: italic; + padding: 10px 0; + min-height: 30px; +} + +.console_loading { + display: flex; + align-items: center; + padding: 10px 0; + min-height: 30px; +} + +.console_cursor { + color: #00ff00; + animation: blink 1s infinite; + margin-left: 4px; +} + +.console_error { + display: flex; + align-items: center; + padding: 10px 0; + min-height: 30px; +} + +.console_error .console_text { + color: #ff4444; +} + +.console_empty { + display: flex; + align-items: center; + opacity: 0.7; + font-style: italic; + padding: 10px 0; + min-height: 30px; +} + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(5px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes blink { + 0%, 50% { + opacity: 1; + } + 51%, 100% { + opacity: 0; + } +} diff --git a/src/components/Dashboard/DashboardLog/DashboardLog.tsx b/src/components/Dashboard/DashboardLog/DashboardLog.tsx new file mode 100644 index 0000000..d8b29c7 --- /dev/null +++ b/src/components/Dashboard/DashboardLog/DashboardLog.tsx @@ -0,0 +1,160 @@ +import React, { useEffect, useRef } from "react"; +import { motion } from "framer-motion"; +import { useWorkflowLogs, useWorkflowStatus } from "../../../hooks/useWorkflows"; + +import styles from './DashboardLog.module.css'; + +interface DashboardLogProps { + isExpanded: boolean; + workflowId: string | null; +} + +const DashboardLog: React.FC = ({ isExpanded, workflowId }) => { + const { status: workflowStatus } = useWorkflowStatus(workflowId); + + // Determine if workflow is completed + const workflowCompleted = workflowStatus && ( + workflowStatus.status === 'completed' || + workflowStatus.status === 'finished' || + workflowStatus.status === 'done' || + workflowStatus.status === 'stopped' + ); + + const { logs, loading, error } = useWorkflowLogs(workflowId, undefined, !!workflowId, !!workflowCompleted); + const logsEndRef = useRef(null); + + // Auto-scroll to bottom when new logs arrive + useEffect(() => { + if (logsEndRef.current) { + logsEndRef.current.scrollIntoView({ behavior: 'smooth' }); + } + }, [logs]); + + const formatTimestamp = (timestamp: string) => { + if (!timestamp) return '00:00:00'; + + try { + return new Date(timestamp).toLocaleTimeString('en-US', { + hour12: false, + hour: '2-digit', + minute: '2-digit', + second: '2-digit' + }); + } catch (error) { + return '00:00:00'; + } + }; + + const getLevelColor = (level: string) => { + if (!level) return '#00ff00'; // Default green if level is undefined + + switch (level.toLowerCase()) { + case 'error': + return '#ff4444'; + case 'warn': + case 'warning': + return '#ffaa00'; + case 'info': + return '#00aaff'; + case 'debug': + return '#888888'; + default: + return '#00ff00'; + } + }; + + return ( + + +
+ + Log {workflowId && `- Workflow ${workflowId.substring(0, 8)}...`} + + +
+
+ + +
+
+ {!workflowId ? ( +
+ $ + Waiting for workflow to start... +
+ ) : loading && logs.length === 0 ? ( +
+ $ + Loading workflow logs... + _ +
+ ) : error ? ( +
+ $ + Error loading logs: {error} +
+ ) : logs.length > 0 ? ( + logs.map((log, index) => ( +
+ + [{formatTimestamp(log.timestamp || '')}] + + + [{(log.level || 'INFO').toUpperCase()}] + + + {log.message || 'No message'} + + {log.data && ( +
+ {JSON.stringify(log.data, null, 2)} +
+ )} +
+ )) + ) : ( +
+ $ + No logs available for this workflow +
+ )} +
+
+
+ + + ); +}; + +export default DashboardLog; diff --git a/src/components/Dashboard/DashboardPrompt/DashboardPrompt.module.css b/src/components/Dashboard/DashboardPrompt/DashboardPrompt.module.css new file mode 100644 index 0000000..b182aa9 --- /dev/null +++ b/src/components/Dashboard/DashboardPrompt/DashboardPrompt.module.css @@ -0,0 +1,153 @@ +.dashboard_prompt { + display: flex; + padding: 20px; + flex-direction: column; + align-self: stretch; + border-radius: 30px; + border: 1px solid var(--f-1-f-1-f-1, #F1F1F1); + background: var(--Grayscale-True-White, #FFF); + position: relative; + box-shadow: 0px 2px 6px 0px rgba(194, 194, 194, 0.10); + width: 100%; + transition: height 0.3s ease; +} + +.dashboard_prompt:not(.collapsed) { + height: 100%; + overflow: hidden; + display: flex; + flex-direction: column; +} + +.dashboard_prompt.collapsed { + height: auto; + min-height: auto; +} + +.prompt_header { + display: flex; + justify-content: space-between; + align-items: flex-start; + width: 100%; +} + +.prompt_button_div { + display: flex; + align-self: stretch; + gap: 30px; +} + +.prompt_button { + text-align: center; + font-size: 14px; + font-style: normal; + font-weight: 500; + line-height: normal; + border: none; + background: none; + outline: none; + color: var(--Grayscale-Black, #24262B); + transition: opacity 0.3s ease, color 0.3s ease; +} + +.prompt_button_inactive { + opacity: 50%; +} + +.prompt_button_collapsed { + opacity: 50%; + color: #A0A0A0; +} + +.buttonWrapper { + display: flex; + flex-direction: column; +} + +.expandIcon { + cursor: pointer; + display: flex; + align-items: center; + color: #666; + transition: color 0.3s ease; +} + +.expandIcon:hover { + color: #333; +} + +.horizontalLine { + width: 100%; + background-color: black; + height: 2px; + margin-top: 19px; + transition: opacity 0.3s ease; +} + +.horizontalLineLight { + width: calc(100%); + background-color: #F1F1F1; + height: 2px; + margin-top: 39px; + margin-left: -20px; + position: absolute; + transition: opacity 0.3s ease; +} + +.content_wrapper { + flex: 1; + min-height: 0; + display: flex; + flex-direction: column; + position: relative; +} + +.content_area { + flex: 1; + min-height: 0; + display: flex; + flex-direction: column; + transition: all 0.3s ease; + opacity: 1; + position: relative; +} +.content_collapsed { + opacity: 0; + max-height: 0; + overflow: hidden; + padding: 0; + margin: 0; +} + +.scrollableContent { + flex: 1; + min-height: 0; + overflow-y: auto; + overflow-x: hidden; + padding: 0 0.5rem 2rem 0; +} + +.container { + display: flex; + flex-direction: column; + flex: 1; + min-height: 0; +} + +.collapseUp { + flex-direction: column-reverse; +} + +.collapseContent { + will-change: transform, opacity; + transition: transform 0.3s cubic-bezier(0.4,0,0.2,1), opacity 0.3s cubic-bezier(0.4,0,0.2,1); +} +.collapseContent.collapsed { + transform: translateY(-100%); + opacity: 0; +} +.collapseContent.expanded { + transform: translateY(0); + opacity: 1; +} + diff --git a/src/components/Dashboard/DashboardPrompt/DashboardPrompt.tsx b/src/components/Dashboard/DashboardPrompt/DashboardPrompt.tsx new file mode 100644 index 0000000..dab5a86 --- /dev/null +++ b/src/components/Dashboard/DashboardPrompt/DashboardPrompt.tsx @@ -0,0 +1,98 @@ +import React, { useState, useEffect } from "react"; +import { useSearchParams } from "react-router-dom"; +import { MdExpandMore, MdExpandLess } from "react-icons/md"; + +import DashboardPromptSettings from './DashboardPromptSettings/DashboardPromptSettings'; +import DashboardPromptSet from './DashboardPromptSet/DashboardPromptSet'; +import { Prompt } from '../../../hooks/usePrompts'; + +import styles from './DashboardPrompt.module.css'; + +interface DashboardPromptProps { + onPromptRun: (prompt: Prompt) => void; + isCollapsed: boolean; + onToggleCollapse: () => void; +} + +const DashboardPrompt: React.FC = ({ + onPromptRun, + isCollapsed, + onToggleCollapse +}) => { + const [activeTab, setActiveTab] = useState("Prompt Set"); + const [searchParams] = useSearchParams(); + + useEffect(() => { + const expandedPrompt = searchParams.get('expandedPrompt'); + const promptId = searchParams.get('promptId'); + + if (expandedPrompt) { + setActiveTab("Prompt Set"); + } else if (promptId) { + setActiveTab("Einstellungen"); + } + }, [searchParams]); + + return ( +
+
+
+ {[ + "Prompt Set", + "Einstellungen" + ].map((tab) => ( +
+ + {!isCollapsed && activeTab === tab && ( +
+ )} +
+ ))} +
+
+ +
+
+ {!isCollapsed && ( +
+ )} + {!isCollapsed && ( +
+
+ {activeTab === "Prompt Set" ? ( + + ) : ( + + )} +
+
+ )} +
+ ) +} + +export default DashboardPrompt; \ No newline at end of file diff --git a/src/components/Dashboard/DashboardPrompt/DashboardPromptSet/DashboardPromptSet.module.css b/src/components/Dashboard/DashboardPrompt/DashboardPromptSet/DashboardPromptSet.module.css new file mode 100644 index 0000000..5d9f36c --- /dev/null +++ b/src/components/Dashboard/DashboardPrompt/DashboardPromptSet/DashboardPromptSet.module.css @@ -0,0 +1,118 @@ +.container { + display: flex; + flex-direction: column; + overflow: hidden; +} + +.header { + display: flex; + justify-content: left; + align-items: center; + margin-top: 1rem; + margin-bottom: 1rem; + flex-shrink: 0; + gap: 20px; +} + +.addButton { + border-radius: 30px; + background: var(--Brand-Green-Green, #3A8088); + color: white; + 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; +} + +.addButton:hover { + cursor: pointer; +} + +.promptCount { + font-size: 0.875rem; + color: #6b7280; +} + +.scrollableContent { + flex: 1; + overflow-y: auto; + overflow-x: hidden; + padding-right: 0.5rem; + padding-bottom: 2rem; + min-height: 0; +} + +.scrollableContent::-webkit-scrollbar { + width: 6px; +} + +.scrollableContent::-webkit-scrollbar-track { + background: transparent; +} + +.scrollableContent::-webkit-scrollbar-thumb { + background: #ccc; + border-radius: 3px; +} + +.scrollableContent::-webkit-scrollbar-thumb:hover { + background: #999; +} + +.promptsList { + display: flex; + flex-direction: column; + gap: 14px; + padding-bottom: 1rem; +} + +.loadingContainer { + display: flex; + justify-content: center; + align-items: center; + padding: 2rem; +} + +.loadingText { + color: #6b7280; +} + +.errorContainer { + padding: 1rem; + background-color: #fef2f2; + border: 1px solid #fecaca; + border-radius: 0.5rem; +} + +.errorText { + color: #b91c1c; +} + +.retryButton { + margin-top: 0.5rem; + padding: 0.5rem 1rem; + background-color: #dc2626; + color: white; + border-radius: 0.375rem; + border: none; + cursor: pointer; + transition: background-color 0.2s; +} + +.retryButton:hover { + background-color: #b91c1c; +} + +.emptyState { + text-align: center; + padding: 2rem; + color: #6b7280; +} + + diff --git a/src/components/Dashboard/DashboardPrompt/DashboardPromptSet/DashboardPromptSet.tsx b/src/components/Dashboard/DashboardPrompt/DashboardPromptSet/DashboardPromptSet.tsx new file mode 100644 index 0000000..dcd61a2 --- /dev/null +++ b/src/components/Dashboard/DashboardPrompt/DashboardPromptSet/DashboardPromptSet.tsx @@ -0,0 +1,73 @@ +import React from 'react'; +import { usePrompts, Prompt } from '../../../../hooks/usePrompts'; +import DashboardPromptSetItem from './DashboardPromptSetItem'; +import styles from './DashboardPromptSet.module.css'; +import { FaPlus } from 'react-icons/fa'; + +interface DashboardPromptSetProps { + onPromptRun: (prompt: Prompt) => void; +} + +function DashboardPromptSet({ onPromptRun }: DashboardPromptSetProps) { + const { prompts, loading, error, refetch } = usePrompts(); + + if (loading) { + return ( +
+
Prompts werden geladen...
+
+ ); + } + + if (error) { + return ( +
+
Fehler beim Laden der Prompts: {error}
+ +
+ ); + } + + return ( +
+
+
+ +
+
+ {prompts.length} {prompts.length === 1 ? 'Prompt' : 'Prompts'} +
+ +
+ +
+ {prompts.length === 0 ? ( +
+ Keine Prompts verfügbar +
+ ) : ( +
+ {prompts.map((prompt) => ( + + ))} +
+ )} +
+
+ ); +} + +export default DashboardPromptSet; \ No newline at end of file diff --git a/src/components/Dashboard/DashboardPrompt/DashboardPromptSet/DashboardPromptSetItem.module.css b/src/components/Dashboard/DashboardPrompt/DashboardPromptSet/DashboardPromptSetItem.module.css new file mode 100644 index 0000000..aafb6c9 --- /dev/null +++ b/src/components/Dashboard/DashboardPrompt/DashboardPromptSet/DashboardPromptSetItem.module.css @@ -0,0 +1,134 @@ +.promptItem { + background: var(--Grayscale-Light-Gray, #F9F9F9); + border-radius: 30px; + display: flex; + padding: 20px; + flex-direction: column; + align-items: flex-start; + align-self: stretch; + justify-content: top; + font-family: 'Avenir', sans-serif; + gap: 11px; + font-size: 14px; +} + + +.promptMain { + display: flex; + justify-content: space-between; + align-items: flex-start; + align-self: stretch; + flex: 1; + min-height: 0; +} + +.promptInfo { + flex: 1; +} + +.promptName { + font-weight: 400; + color: #000; + margin:0; +} + +.promptDate { + font: 14px; + color: #6b7280; +} + +.promptText { + overflow: hidden; + height: auto; + flex: 1; + min-height: 0; + opacity: 0.5; + margin:0; +} + +.promptText.p { + margin:0; +} + +.actionButtons { + display: flex; + gap: 0.5rem; + align-self: flex-start; + flex-shrink: 0; +} + +.actionButton { + padding: 0.5rem; + border-radius: 12px; + background: var(--Brand-Green-Green, #3A8088); + color: #fff; + cursor: pointer; + border: none; +} + +.actionButton:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.runButton { + border-radius: 12px; + background: var(--Brand-Green-Green, #3A8088); + color: #fff; +} + +.runButton:hover:not(:disabled) { + border-radius: 12px; + background: var(--Brand-Green-Green, #3A8088); + color: #fff; + cursor: pointer; +} + +.shareButton { + border-radius: 12px; + background: var(--Brand-Green-Green, #3A8088); + color: #fff; +} + +.shareButton:hover:not(:disabled) { + border-radius: 12px; + background: var(--Brand-Green-Green, #3A8088); + color: #fff; +} + +.deleteButton { + border-radius: 12px; + background: var(--Brand-Green-Green, #3A8088); + color: #fff; +} + +.deleteButton:hover:not(:disabled) { + border-radius: 12px; + background: var(--Brand-Green-Green, #3A8088); + color: #fff; +} + +.promptContent { + display: flex; + flex-direction: column; + flex: 1; + min-height: 0; + gap: 11px; + max-width: calc(100% - 120px); +} + +.errorMessage { + margin-top: 0.75rem; + padding: 0.5rem; + background-color: #fef2f2; + border: 1px solid #fecaca; + border-radius: 0.25rem; + font-size: 0.875rem; + color: #b91c1c; +} + +.deletingMessage { + margin-top: 0.75rem; + font-size: 0.875rem; + color: #6b7280; +} diff --git a/src/components/Dashboard/DashboardPrompt/DashboardPromptSet/DashboardPromptSetItem.tsx b/src/components/Dashboard/DashboardPrompt/DashboardPromptSet/DashboardPromptSetItem.tsx new file mode 100644 index 0000000..5d0705e --- /dev/null +++ b/src/components/Dashboard/DashboardPrompt/DashboardPromptSet/DashboardPromptSetItem.tsx @@ -0,0 +1,104 @@ +import React, { useState, useRef, useEffect } from 'react'; +import { FaArrowRight } from 'react-icons/fa'; +import { AiOutlineDelete } from 'react-icons/ai'; +import { BsShareFill } from 'react-icons/bs'; +import { usePromptOperations, Prompt } from '../../../../hooks/usePrompts'; +import styles from './DashboardPromptSetItem.module.css'; + +interface DashboardPromptSetItemProps { + prompt: Prompt; + onDelete?: () => void; + onRun: (prompt: Prompt) => void; +} + +function DashboardPromptSetItem({ prompt, onDelete, onRun }: DashboardPromptSetItemProps) { + const { handlePromptDelete, deletingPrompts, deleteError } = usePromptOperations(); + const contentRef = useRef(null); + + const isDeleting = deletingPrompts.has(prompt.id); + + const handleDelete = async () => { + if (window.confirm(`Möchten Sie den Prompt "${prompt.name}" wirklich löschen?`)) { + const success = await handlePromptDelete(prompt.id); + if (success && onDelete) { + onDelete(); + } + } + }; + + const handleRun = () => { + onRun(prompt); + }; + + const handleShare = () => { + console.log('Sharing prompt:', prompt); + }; + + return ( +
+
+
+
+

+ {prompt.name} +

+ {prompt.createdAt && ( +

+ Erstellt: {new Date(prompt.createdAt).toLocaleDateString('de-DE')} +

+ )} +
+ +
+

+ {prompt.content} +

+
+
+ +
+ + + + + +
+
+ + {deleteError && ( +
+ Fehler beim Löschen: {deleteError} +
+ )} + + {isDeleting && ( +
+ Prompt wird gelöscht... +
+ )} +
+ ); +} + +export default DashboardPromptSetItem; diff --git a/src/components/Dashboard/DashboardPrompt/DashboardPromptSettings/DashboardPromptSettings.module.css b/src/components/Dashboard/DashboardPrompt/DashboardPromptSettings/DashboardPromptSettings.module.css new file mode 100644 index 0000000..edd64e3 --- /dev/null +++ b/src/components/Dashboard/DashboardPrompt/DashboardPromptSettings/DashboardPromptSettings.module.css @@ -0,0 +1,37 @@ +.promptArea { + display: flex; + flex-direction: column; + height: 100%; + position: relative; +} + +.cancelContainer { + position: absolute; + top: 10px; + right: 10px; + z-index: 10; +} + +.cancelButton { + display: flex; + align-items: center; + gap: 4px; + padding: 8px 16px; + background: white; + border: 1px solid #ddd; + border-radius: 20px; + color: #666; + font-size: 14px; + cursor: pointer; + transition: all 0.2s; + font-family: Arial, Helvetica, sans-serif; +} + +.cancelButton:hover { + background-color: #f5f5f5; + border-color: #ccc; +} + +.cancelIcon { + font-size: 16px; +} \ No newline at end of file diff --git a/src/components/Dashboard/DashboardPrompt/DashboardPromptSettings/DashboardPromptSettings.tsx b/src/components/Dashboard/DashboardPrompt/DashboardPromptSettings/DashboardPromptSettings.tsx new file mode 100644 index 0000000..6acedf3 --- /dev/null +++ b/src/components/Dashboard/DashboardPrompt/DashboardPromptSettings/DashboardPromptSettings.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import styles from './DashboardPromptSettings.module.css'; + +function DashboardPromptSettings() { + return ( +
+
+

Dashboard Prompt Settings

+

Settings content will be added here in future updates.

+
+
+ ); +} + +export default DashboardPromptSettings; diff --git a/src/components/Sidebar/SidebarData.tsx b/src/components/Sidebar/SidebarData.tsx index a77ac73..5136b3b 100644 --- a/src/components/Sidebar/SidebarData.tsx +++ b/src/components/Sidebar/SidebarData.tsx @@ -19,48 +19,42 @@ const useSidebarData = () => { }, { id: '2', - name: 'Prompts', - icon: BsChatDots, - submenu: [], - }, - { - id: '3', name: 'Aktivitätszentrum', link: '/dashboard', icon: LuTicket, }, { - id: '4', + id: '3', name: 'Dateien', link: '/dateien', icon: FaRegFileAlt, }, { - id: '5', + id: '4', name: 'Mitglieder', link: '/mitglieder', icon: RiTeamLine, }, { - id: '6', + id: '5', name: 'Nachrichten', link: '', icon: BiInfoSquare, }, { - id: '7', + id: '6', name: 'Logs', link: '', icon: TbLogs , }, { - id: '8', + id: '7', name: 'Settings', link: '', icon: GoGear, }, { - id: '9', + id: '8', name: 'Help', link: '', icon: BiInfoSquare, diff --git a/src/hooks/usePrompts.ts b/src/hooks/usePrompts.ts new file mode 100644 index 0000000..8bf08bf --- /dev/null +++ b/src/hooks/usePrompts.ts @@ -0,0 +1,128 @@ +import { useState, useEffect } from 'react'; +import { useApiRequest } from './useApi'; + +// Prompt interfaces +export interface Prompt { + id: number; + name: string; + content: string; + createdAt?: string; +} + +// Prompts list hook +export function usePrompts() { + const [prompts, setPrompts] = useState([]); + const { request, isLoading: loading, error } = useApiRequest(); + + const fetchPrompts = async () => { + try { + const data = await request({ + url: '/api/prompts', + method: 'get' + }); + + setPrompts(data); + } catch (error) { + // Error is already handled by useApiRequest + } + }; + + useEffect(() => { + fetchPrompts(); + }, []); + + return { prompts, loading, error, refetch: fetchPrompts }; +} + +// Prompt operations hook +export function usePromptOperations() { + const [deletingPrompts, setDeletingPrompts] = useState>(new Set()); + const [creatingPrompt, setCreatingPrompt] = useState(false); + const [updatingPrompts, setUpdatingPrompts] = useState>(new Set()); + const { request, error: apiError, isLoading } = useApiRequest(); + const [deleteError, setDeleteError] = useState(null); + const [createError, setCreateError] = useState(null); + const [updateError, setUpdateError] = useState(null); + + const handlePromptDelete = async (promptId: number) => { + setDeleteError(null); + setDeletingPrompts(prev => new Set(prev).add(promptId)); + + try { + await request({ + url: `/api/prompts/${promptId}`, + method: 'delete' + }); + + // Add a small delay to ensure backend has time to process + await new Promise(resolve => setTimeout(resolve, 300)); + return true; + } catch (error: any) { + setDeleteError(error.message); + return false; + } finally { + setDeletingPrompts(prev => { + const newSet = new Set(prev); + newSet.delete(promptId); + return newSet; + }); + } + }; + + const handlePromptCreate = async (promptData: { name: string; content: string }) => { + setCreateError(null); + setCreatingPrompt(true); + + try { + const newPrompt = await request({ + url: '/api/prompts', + method: 'post', + data: promptData + }); + + return { success: true, promptData: newPrompt }; + } catch (error: any) { + setCreateError(error.message); + return { success: false, error: error.message }; + } finally { + setCreatingPrompt(false); + } + }; + + const handlePromptUpdate = async (promptId: number, promptData: { name?: string; content?: string }) => { + setUpdateError(null); + setUpdatingPrompts(prev => new Set(prev).add(promptId)); + + try { + const updatedPrompt = await request({ + url: `/api/prompts/${promptId}`, + method: 'put', + data: promptData + }); + + return { success: true, promptData: updatedPrompt }; + } catch (error: any) { + setUpdateError(error.message); + return { success: false, error: error.message }; + } finally { + setUpdatingPrompts(prev => { + const newSet = new Set(prev); + newSet.delete(promptId); + return newSet; + }); + } + }; + + return { + deletingPrompts, + creatingPrompt, + updatingPrompts, + deleteError, + createError, + updateError, + handlePromptDelete, + handlePromptCreate, + handlePromptUpdate, + isLoading + }; +} \ No newline at end of file diff --git a/src/hooks/useWorkflows.ts b/src/hooks/useWorkflows.ts new file mode 100644 index 0000000..79c9d99 --- /dev/null +++ b/src/hooks/useWorkflows.ts @@ -0,0 +1,260 @@ +import { useState, useEffect, useCallback } from 'react'; +import { useApiRequest } from './useApi'; + +// Workflow interfaces +export interface Workflow { + id: string; + name?: string; + status: string; + startedAt?: string; + lastActivity?: string; + currentRound?: number; + dataStats?: Record; + userId?: number; + messageIds?: string[]; +} + +export interface WorkflowMessage { + id: string; + content: string; + role: 'user' | 'assistant' | 'system'; + timestamp?: string; + sequenceNo?: number; + fileIds?: number[]; +} + +export interface WorkflowLog { + id: string; + level: string; + message: string; + timestamp: string; + data?: Record; +} + +export interface StartWorkflowRequest { + prompt: string; + listFileId: number[]; +} + +export interface StartWorkflowResponse { + id: string; + status: string; + message: string; +} + +// Workflows list hook +export function useWorkflows() { + const [workflows, setWorkflows] = useState([]); + const { request, isLoading: loading, error } = useApiRequest(); + + const fetchWorkflows = async () => { + try { + const data = await request({ + url: '/api/workflows', + method: 'get' + }); + + setWorkflows(data); + } catch (error) { + // Error is already handled by useApiRequest + } + }; + + useEffect(() => { + fetchWorkflows(); + }, []); + + return { workflows, loading, error, refetch: fetchWorkflows }; +} + +// Workflow operations hook +export function useWorkflowOperations() { + const [startingWorkflow, setStartingWorkflow] = useState(false); + const [stoppingWorkflows, setStoppingWorkflows] = useState>(new Set()); + const [deletingWorkflows, setDeletingWorkflows] = useState>(new Set()); + const { request, error: apiError, isLoading } = useApiRequest(); + const [startError, setStartError] = useState(null); + const [stopError, setStopError] = useState(null); + const [deleteError, setDeleteError] = useState(null); + + const startWorkflow = async (workflowData: StartWorkflowRequest, workflowId?: string) => { + setStartError(null); + setStartingWorkflow(true); + + try { + const response = await request({ + url: '/api/workflows/start', + method: 'post', + data: workflowData, + params: workflowId ? { workflowId } : undefined + }) as StartWorkflowResponse; + + return { success: true, data: response }; + } catch (error: any) { + setStartError(error.message); + return { success: false, error: error.message }; + } finally { + setStartingWorkflow(false); + } + }; + + const stopWorkflow = async (workflowId: string) => { + setStopError(null); + setStoppingWorkflows(prev => new Set(prev).add(workflowId)); + + try { + await request({ + url: `/api/workflows/${workflowId}/stop`, + method: 'post' + }); + + return true; + } catch (error: any) { + setStopError(error.message); + return false; + } finally { + setStoppingWorkflows(prev => { + const newSet = new Set(prev); + newSet.delete(workflowId); + return newSet; + }); + } + }; + + const deleteWorkflow = async (workflowId: string) => { + setDeleteError(null); + setDeletingWorkflows(prev => new Set(prev).add(workflowId)); + + try { + await request({ + url: `/api/workflows/${workflowId}`, + method: 'delete' + }); + + return true; + } catch (error: any) { + setDeleteError(error.message); + return false; + } finally { + setDeletingWorkflows(prev => { + const newSet = new Set(prev); + newSet.delete(workflowId); + return newSet; + }); + } + }; + + return { + startingWorkflow, + stoppingWorkflows, + deletingWorkflows, + startError, + stopError, + deleteError, + startWorkflow, + stopWorkflow, + deleteWorkflow, + isLoading + }; +} + +// Workflow status hook +export function useWorkflowStatus(workflowId: string | null) { + const [status, setStatus] = useState(null); + const { request, isLoading: loading, error } = useApiRequest(); + + const fetchStatus = async () => { + if (!workflowId) return; + + try { + const data = await request({ + url: `/api/workflows/${workflowId}/status`, + method: 'get' + }); + + setStatus(data); + } catch (error) { + // Error is already handled by useApiRequest + } + }; + + useEffect(() => { + fetchStatus(); + }, [workflowId]); + + return { status, loading, error, refetch: fetchStatus }; +} + +// Workflow messages hook +export function useWorkflowMessages(workflowId: string | null, messageId?: string) { + const [messages, setMessages] = useState([]); + const { request, isLoading: loading, error } = useApiRequest(); + + const fetchMessages = async () => { + if (!workflowId) return; + + try { + const data = await request({ + url: `/api/workflows/${workflowId}/messages`, + method: 'get', + params: messageId ? { messageId } : undefined + }); + + setMessages(data); + } catch (error) { + // Error is already handled by useApiRequest + } + }; + + useEffect(() => { + fetchMessages(); + }, [workflowId, messageId]); + + return { messages, loading, error, refetch: fetchMessages }; +} + +// Workflow logs hook +export function useWorkflowLogs(workflowId: string | null, logId?: string, enablePolling: boolean = false, workflowCompleted: boolean = false) { + const [logs, setLogs] = useState([]); + const { request, isLoading: loading, error } = useApiRequest(); + + const fetchLogs = useCallback(async () => { + if (!workflowId) return; + + try { + const data = await request({ + url: `/api/workflows/${workflowId}/logs`, + method: 'get', + params: logId ? { logId } : undefined + }); + + setLogs(data); + } catch (error) { + // Error is already handled by useApiRequest + } + }, [workflowId, logId, request]); + + useEffect(() => { + fetchLogs(); + }, [fetchLogs]); + + // Polling effect for real-time log updates - poll every second until workflow is completed + useEffect(() => { + if (!workflowId || !enablePolling || workflowCompleted) return; + + const interval = setInterval(() => { + fetchLogs(); + }, 1000); // Poll every second for logs + + return () => clearInterval(interval); + }, [workflowId, enablePolling, workflowCompleted, fetchLogs]); + + // Clear logs when workflowId changes + useEffect(() => { + if (!workflowId) { + setLogs([]); + } + }, [workflowId]); + + return { logs, loading, error, refetch: fetchLogs }; +} \ No newline at end of file diff --git a/src/pages/Dashboard.module.css b/src/pages/Dashboard.module.css new file mode 100644 index 0000000..e560362 --- /dev/null +++ b/src/pages/Dashboard.module.css @@ -0,0 +1,58 @@ +.dashboardContainer { + margin: 51px 49px 0 36px; + display: flex; + flex-direction: column; + gap: 20px; +} + +.chatLogContainer { + display: flex; + gap: 20px; + transition: all 0.3s ease; +} + +.chatLogContainer.expanded { + flex-direction: column; + gap: 20px; +} + +/* Height classes for different states */ +.chatArea15vh { + height: 15vh; +} + +.chatArea40vh { + height: 40vh; +} + +.chatArea45vh { + height: 45vh; +} + +.chatArea60vh { + height: 60vh; +} + +.logArea15vh { + height: 15vh; +} + +.logArea25vh { + height: 25vh; +} + +.logArea40vh { + height: 40vh; +} + +.logArea60vh { + height: 60vh; +} + +.promptArea30vh { + height: 30vh; +} + +.promptArea40vh { + height: 40vh; +} \ No newline at end of file diff --git a/src/pages/Dashboard.tsx b/src/pages/Dashboard.tsx new file mode 100644 index 0000000..d22827a --- /dev/null +++ b/src/pages/Dashboard.tsx @@ -0,0 +1,103 @@ +import React, { useState, useCallback } 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' + +function Dashboard () { + const [isChatExpanded, setIsChatExpanded] = useState(false); + const [selectedPrompt, setSelectedPrompt] = useState(null); + const [isPromptAreaCollapsed, setIsPromptAreaCollapsed] = useState(false); + const [currentWorkflowId, setCurrentWorkflowId] = useState(null); + + const handleChatToggleExpand = () => { + setIsChatExpanded(!isChatExpanded); + }; + + const handlePromptRun = (prompt: Prompt) => { + setSelectedPrompt(prompt); + setIsPromptAreaCollapsed(true); + }; + + const handleWorkflowIdChange = useCallback((workflowId: string | null) => { + setCurrentWorkflowId(workflowId); + }, []); + + const handleWorkflowResume = useCallback((workflowId: string) => { + // Set the workflow ID to resume it + setCurrentWorkflowId(workflowId); + // Switch to Chat Area tab to show the resumed workflow + console.log('Resuming workflow:', workflowId); + }, []); + + // Determine CSS classes based on states + const getPromptClass = () => { + if (isPromptAreaCollapsed) return ''; + return isChatExpanded ? styles.promptArea40vh : styles.promptArea30vh; + }; + + const getChatClass = () => { + if (isPromptAreaCollapsed && isChatExpanded) return styles.chatArea45vh; + if (!isPromptAreaCollapsed && isChatExpanded) return styles.chatArea15vh; + if (isPromptAreaCollapsed && !isChatExpanded) return styles.chatArea60vh; + return styles.chatArea40vh; + }; + + const getLogClass = () => { + if (isPromptAreaCollapsed && isChatExpanded) return styles.logArea25vh; + if (!isPromptAreaCollapsed && isChatExpanded) return styles.logArea15vh; + if (isPromptAreaCollapsed && !isChatExpanded) return styles.logArea60vh; + return styles.logArea40vh; + }; + + return ( +
+
+ setIsPromptAreaCollapsed(!isPromptAreaCollapsed)} + /> +
+
+
+ setSelectedPrompt(null)} + onWorkflowIdChange={handleWorkflowIdChange} + onWorkflowResume={handleWorkflowResume} + /> +
+
+ +
+
+
+ ); +} + +export default Dashboard; diff --git a/src/pages/Home.module.css b/src/pages/Home.module.css index 53cae3d..9aa5cd2 100644 --- a/src/pages/Home.module.css +++ b/src/pages/Home.module.css @@ -6,7 +6,9 @@ width: 100%; font-family: Arial, Helvetica, sans-serif; z-index: 0; - overflow: hidden; /* just in case */ + overflow: hidden; + padding: 0 49px 0 36px; + width: calc(100% - 49px - 36px); } .homeContainer::before {