feat(): Crianção da consumação dos seguintes endpoints, Log Server, Log Ged e Log Database
This commit is contained in:
parent
bee7779e39
commit
b6a5dffdec
21 changed files with 1589 additions and 30 deletions
578
package-lock.json
generated
578
package-lock.json
generated
|
|
@ -18,9 +18,10 @@
|
|||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||
"@radix-ui/react-label": "^2.1.7",
|
||||
"@radix-ui/react-popover": "^1.1.15",
|
||||
"@radix-ui/react-scroll-area": "^1.2.10",
|
||||
"@radix-ui/react-select": "^2.2.6",
|
||||
"@radix-ui/react-separator": "^1.1.7",
|
||||
"@radix-ui/react-slot": "^1.2.3",
|
||||
"@radix-ui/react-slot": "^1.2.4",
|
||||
"@radix-ui/react-tabs": "^1.1.13",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
|
|
@ -29,6 +30,7 @@
|
|||
"clsx": "^2.1.1",
|
||||
"cmdk": "^1.1.1",
|
||||
"cookies-next": "^6.1.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"faker-js": "^1.0.0",
|
||||
"input-otp": "^1.4.2",
|
||||
"js-cookie": "^3.0.5",
|
||||
|
|
@ -41,6 +43,7 @@
|
|||
"react-dom": "19.1.0",
|
||||
"react-hook-form": "^7.62.0",
|
||||
"react-masked-text": "^1.0.5",
|
||||
"recharts": "^3.3.0",
|
||||
"sonner": "^2.0.7",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
"tinymce": "^8.1.2",
|
||||
|
|
@ -1119,6 +1122,24 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-slot": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
|
||||
"integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-arrow": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz",
|
||||
|
|
@ -1255,6 +1276,24 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
|
||||
"integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-compose-refs": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
|
||||
|
|
@ -1321,6 +1360,24 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
|
||||
"integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-direction": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz",
|
||||
|
|
@ -1513,6 +1570,24 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-slot": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
|
||||
"integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-popover": {
|
||||
"version": "1.1.15",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz",
|
||||
|
|
@ -1550,6 +1625,24 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-slot": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
|
||||
"integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-popper": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz",
|
||||
|
|
@ -1653,6 +1746,24 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
|
||||
"integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-roving-focus": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz",
|
||||
|
|
@ -1684,6 +1795,37 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-scroll-area": {
|
||||
"version": "1.2.10",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.10.tgz",
|
||||
"integrity": "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/number": "1.1.1",
|
||||
"@radix-ui/primitive": "1.1.3",
|
||||
"@radix-ui/react-compose-refs": "1.1.2",
|
||||
"@radix-ui/react-context": "1.1.2",
|
||||
"@radix-ui/react-direction": "1.1.1",
|
||||
"@radix-ui/react-presence": "1.1.5",
|
||||
"@radix-ui/react-primitive": "2.1.3",
|
||||
"@radix-ui/react-use-callback-ref": "1.1.1",
|
||||
"@radix-ui/react-use-layout-effect": "1.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-select": {
|
||||
"version": "2.2.6",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz",
|
||||
|
|
@ -1727,6 +1869,24 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-slot": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
|
||||
"integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-separator": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz",
|
||||
|
|
@ -1751,9 +1911,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-slot": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
|
||||
"integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz",
|
||||
"integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.2"
|
||||
|
|
@ -1832,6 +1992,24 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-slot": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
|
||||
"integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-use-callback-ref": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz",
|
||||
|
|
@ -2015,6 +2193,32 @@
|
|||
"integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@reduxjs/toolkit": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.10.1.tgz",
|
||||
"integrity": "sha512-/U17EXQ9Do9Yx4DlNGU6eVNfZvFJfYpUtRRdLf19PbPjdWBxNlxGZXywQZ1p1Nz8nMkWplTI7iD/23m07nolDA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@standard-schema/spec": "^1.0.0",
|
||||
"@standard-schema/utils": "^0.3.0",
|
||||
"immer": "^10.2.0",
|
||||
"redux": "^5.0.1",
|
||||
"redux-thunk": "^3.1.0",
|
||||
"reselect": "^5.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.9.0 || ^17.0.0 || ^18 || ^19",
|
||||
"react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react": {
|
||||
"optional": true
|
||||
},
|
||||
"react-redux": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rtsao/scc": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
|
||||
|
|
@ -2029,6 +2233,12 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@standard-schema/spec": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz",
|
||||
"integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@standard-schema/utils": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz",
|
||||
|
|
@ -2383,6 +2593,69 @@
|
|||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-array": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz",
|
||||
"integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-color": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
|
||||
"integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-ease": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz",
|
||||
"integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-interpolate": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
|
||||
"integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/d3-color": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-path": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz",
|
||||
"integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-scale": {
|
||||
"version": "4.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz",
|
||||
"integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/d3-time": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-shape": {
|
||||
"version": "3.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz",
|
||||
"integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/d3-path": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-time": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz",
|
||||
"integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-timer": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz",
|
||||
"integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/js-cookie": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.6.tgz",
|
||||
|
|
@ -2431,6 +2704,7 @@
|
|||
"integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
|
|
@ -2441,10 +2715,17 @@
|
|||
"integrity": "sha512-/EEvYBdT3BflCWvTMO7YkYBHVE9Ci6XdqZciZANQgKpaiDRGOLIlRo91jbTNRQjgPFWVaRxcYc0luVNFitz57A==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"peerDependencies": {
|
||||
"@types/react": "^19.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/use-sync-external-store": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
|
||||
"integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "8.46.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.0.tgz",
|
||||
|
|
@ -2962,6 +3243,7 @@
|
|||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
|
|
@ -3521,6 +3803,127 @@
|
|||
"devOptional": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/d3-array": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
|
||||
"integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"internmap": "1 - 2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-color": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
|
||||
"integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-ease": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
|
||||
"integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-format": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
|
||||
"integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-interpolate": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
|
||||
"integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-color": "1 - 3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-path": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
|
||||
"integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-scale": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
|
||||
"integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-array": "2.10.0 - 3",
|
||||
"d3-format": "1 - 3",
|
||||
"d3-interpolate": "1.2.0 - 3",
|
||||
"d3-time": "2.1.1 - 3",
|
||||
"d3-time-format": "2 - 4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-shape": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
|
||||
"integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-path": "^3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-time": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
|
||||
"integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-array": "2 - 3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-time-format": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
|
||||
"integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-time": "1 - 3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-timer": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
|
||||
"integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/damerau-levenshtein": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
|
||||
|
|
@ -3582,6 +3985,16 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/date-fns": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz",
|
||||
"integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/kossnocorp"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||
|
|
@ -3600,6 +4013,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/decimal.js-light": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz",
|
||||
"integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/deep-is": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
||||
|
|
@ -3894,6 +4313,16 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/es-toolkit": {
|
||||
"version": "1.41.0",
|
||||
"resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.41.0.tgz",
|
||||
"integrity": "sha512-bDd3oRmbVgqZCJS6WmeQieOrzpl3URcWBUVDXxOELlUW2FuW+0glPOz1n0KnRie+PdyvUZcXz2sOn00c6pPRIA==",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"docs",
|
||||
"benchmarks"
|
||||
]
|
||||
},
|
||||
"node_modules/escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
|
|
@ -3914,6 +4343,7 @@
|
|||
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.6.1",
|
||||
|
|
@ -3998,6 +4428,7 @@
|
|||
"integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"eslint-config-prettier": "bin/cli.js"
|
||||
},
|
||||
|
|
@ -4099,6 +4530,7 @@
|
|||
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@rtsao/scc": "^1.1.0",
|
||||
"array-includes": "^3.1.9",
|
||||
|
|
@ -4524,6 +4956,12 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eventemitter3": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
|
||||
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/faker-js": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/faker-js/-/faker-js-1.0.0.tgz",
|
||||
|
|
@ -5039,6 +5477,16 @@
|
|||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/immer": {
|
||||
"version": "10.2.0",
|
||||
"resolved": "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz",
|
||||
"integrity": "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/immer"
|
||||
}
|
||||
},
|
||||
"node_modules/import-fresh": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
|
||||
|
|
@ -5110,6 +5558,15 @@
|
|||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/internmap": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
|
||||
"integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/is-array-buffer": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
|
||||
|
|
@ -6208,6 +6665,7 @@
|
|||
"resolved": "https://registry.npmjs.org/next/-/next-15.5.4.tgz",
|
||||
"integrity": "sha512-xH4Yjhb82sFYQfY3vbkJfgSDgXvBB6a8xPs9i35k6oZJRoQRihZH+4s9Yo2qsWpzBmZ3lPXaJ2KPXLfkvW4LnA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@next/env": "15.5.4",
|
||||
"@swc/helpers": "0.5.15",
|
||||
|
|
@ -6617,6 +7075,7 @@
|
|||
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
|
|
@ -6774,6 +7233,7 @@
|
|||
"resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
|
||||
"integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
|
@ -6783,6 +7243,7 @@
|
|||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
|
||||
"integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"scheduler": "^0.26.0"
|
||||
},
|
||||
|
|
@ -6795,6 +7256,7 @@
|
|||
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.64.0.tgz",
|
||||
"integrity": "sha512-fnN+vvTiMLnRqKNTVhDysdrUay0kUUAymQnFIznmgDvapjveUWOOPqMNzPg+A+0yf9DuE2h6xzBjN1s+Qx8wcg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
|
|
@ -6810,7 +7272,8 @@
|
|||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/react-masked-text": {
|
||||
"version": "1.0.5",
|
||||
|
|
@ -6818,6 +7281,30 @@
|
|||
"integrity": "sha512-WichrlCXehL0apIfIgOdi2mjBE03tdMi8wXF+DhHe2ySWYxXCkP88aqDBaJZWUMa3Jp8p2h71u7TpC7EzEjXYw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/react-redux": {
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
|
||||
"integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/use-sync-external-store": "^0.0.6",
|
||||
"use-sync-external-store": "^1.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^18.2.25 || ^19",
|
||||
"react": "^18.0 || ^19",
|
||||
"redux": "^5.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"redux": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-remove-scroll": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz",
|
||||
|
|
@ -6887,6 +7374,49 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/recharts": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/recharts/-/recharts-3.3.0.tgz",
|
||||
"integrity": "sha512-Vi0qmTB0iz1+/Cz9o5B7irVyUjX2ynvEgImbgMt/3sKRREcUM07QiYjS1QpAVrkmVlXqy5gykq4nGWMz9AS4Rg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@reduxjs/toolkit": "1.x.x || 2.x.x",
|
||||
"clsx": "^2.1.1",
|
||||
"decimal.js-light": "^2.5.1",
|
||||
"es-toolkit": "^1.39.3",
|
||||
"eventemitter3": "^5.0.1",
|
||||
"immer": "^10.1.1",
|
||||
"react-redux": "8.x.x || 9.x.x",
|
||||
"reselect": "5.1.1",
|
||||
"tiny-invariant": "^1.3.3",
|
||||
"use-sync-external-store": "^1.2.2",
|
||||
"victory-vendor": "^37.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||
"react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/redux": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
|
||||
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/redux-thunk": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz",
|
||||
"integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"redux": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/reflect.getprototypeof": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
||||
|
|
@ -6931,6 +7461,12 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/reselect": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
|
||||
"integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.10",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
|
||||
|
|
@ -7617,6 +8153,12 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tiny-invariant": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
|
||||
"integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tinyglobby": {
|
||||
"version": "0.2.15",
|
||||
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
|
||||
|
|
@ -7658,6 +8200,7 @@
|
|||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
|
|
@ -7669,7 +8212,8 @@
|
|||
"version": "8.1.2",
|
||||
"resolved": "https://registry.npmjs.org/tinymce/-/tinymce-8.1.2.tgz",
|
||||
"integrity": "sha512-KITxHEEHRlxC5xOnxA123eAJ67NgsWxNphtItWt9TRu07DiTZrWIqJeIKRX9euE51/l3kJO4WQiqoBXKTJJGsA==",
|
||||
"license": "GPL-2.0-or-later"
|
||||
"license": "GPL-2.0-or-later",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
|
|
@ -7967,6 +8511,28 @@
|
|||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/victory-vendor": {
|
||||
"version": "37.3.6",
|
||||
"resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-37.3.6.tgz",
|
||||
"integrity": "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==",
|
||||
"license": "MIT AND ISC",
|
||||
"dependencies": {
|
||||
"@types/d3-array": "^3.0.3",
|
||||
"@types/d3-ease": "^3.0.0",
|
||||
"@types/d3-interpolate": "^3.0.1",
|
||||
"@types/d3-scale": "^4.0.2",
|
||||
"@types/d3-shape": "^3.1.0",
|
||||
"@types/d3-time": "^3.0.0",
|
||||
"@types/d3-timer": "^3.0.0",
|
||||
"d3-array": "^3.1.6",
|
||||
"d3-ease": "^3.0.1",
|
||||
"d3-interpolate": "^3.0.1",
|
||||
"d3-scale": "^4.0.2",
|
||||
"d3-shape": "^3.1.0",
|
||||
"d3-time": "^3.0.0",
|
||||
"d3-timer": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
|
|
|
|||
|
|
@ -22,9 +22,10 @@
|
|||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||
"@radix-ui/react-label": "^2.1.7",
|
||||
"@radix-ui/react-popover": "^1.1.15",
|
||||
"@radix-ui/react-scroll-area": "^1.2.10",
|
||||
"@radix-ui/react-select": "^2.2.6",
|
||||
"@radix-ui/react-separator": "^1.1.7",
|
||||
"@radix-ui/react-slot": "^1.2.3",
|
||||
"@radix-ui/react-slot": "^1.2.4",
|
||||
"@radix-ui/react-tabs": "^1.1.13",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
|
|
@ -33,6 +34,7 @@
|
|||
"clsx": "^2.1.1",
|
||||
"cmdk": "^1.1.1",
|
||||
"cookies-next": "^6.1.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"faker-js": "^1.0.0",
|
||||
"input-otp": "^1.4.2",
|
||||
"js-cookie": "^3.0.5",
|
||||
|
|
@ -45,6 +47,7 @@
|
|||
"react-dom": "19.1.0",
|
||||
"react-hook-form": "^7.62.0",
|
||||
"react-masked-text": "^1.0.5",
|
||||
"recharts": "^3.3.0",
|
||||
"sonner": "^2.0.7",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
"tinymce": "^8.1.2",
|
||||
|
|
|
|||
|
|
@ -1,39 +1,495 @@
|
|||
'use client';
|
||||
|
||||
import { useParams } from 'next/navigation';
|
||||
import { useLogServerHook } from '@/packages/administrativo/hooks/Log/useLogServerHook'; // importa seu hook customizado
|
||||
import { useEffect } from 'react';
|
||||
|
||||
// Helpers e hooks customizados
|
||||
import { formatLogDateTime } from "@/shared/utils/formatLogDateTime";
|
||||
import { formatDateTime } from '@/shared/utils/formatDateTime';
|
||||
import { convertMBtoGB } from '@/shared/utils/convertMBtoGB';
|
||||
|
||||
// Hooks responsaveis em consumir os endpoint's
|
||||
import { useLogServerHook } from '@/packages/administrativo/hooks/Log/useLogServerHook';
|
||||
import { useLogDatabaseHook } from '@/packages/administrativo/hooks/Log/useLogDatabaseHook';
|
||||
import { useLogGedHook } from '@/packages/administrativo/hooks/Log/useLogGedHook';
|
||||
|
||||
// Componentes do Shadcn/UI
|
||||
import {
|
||||
Card, CardHeader, CardTitle, CardContent
|
||||
} from "@/components/ui/card";
|
||||
import {
|
||||
Table, TableHeader, TableRow, TableHead, TableCell, TableBody
|
||||
} from "@/components/ui/table";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import {
|
||||
Tabs, TabsContent, TabsList, TabsTrigger
|
||||
} from "@/components/ui/tabs";
|
||||
import { PartitionBarChart } from '@/shared/components/charts/PartitionBarChart';
|
||||
import { renderPartitionPieChart } from '@/shared/components/charts/PartitionPieChart';
|
||||
|
||||
export default function ClientePage() {
|
||||
// Captura o ID da rota (ex: /administrativo/clientes/6)
|
||||
const { id } = useParams();
|
||||
|
||||
// Hook customizado para carregar dados do log/server
|
||||
const { log, fetchLogServer } = useLogServerHook();
|
||||
// Hooks de logs (server e database)
|
||||
const { logServer, fetchLogServer } = useLogServerHook();
|
||||
const { logDatabase, fetchLogDatabase } = useLogDatabaseHook();
|
||||
const { logGed, fetchLogGed } = useLogGedHook();
|
||||
|
||||
// Quando o componente montar, busca os dados do servidor/log
|
||||
// Efeito responsável por buscar logs de forma sequencial
|
||||
useEffect(() => {
|
||||
if (id) fetchLogServer(Number(id));
|
||||
|
||||
// Só executa se houver um ID válido
|
||||
if (!id) return;
|
||||
|
||||
const fetchSequentially = async () => {
|
||||
|
||||
try {
|
||||
|
||||
// Primeiro: tenta buscar o log do servidor
|
||||
await fetchLogServer(Number(id));
|
||||
|
||||
} catch (error) {
|
||||
|
||||
console.error("Erro ao buscar log do servidor:", error);
|
||||
|
||||
} finally {
|
||||
|
||||
// Após terminar a busca do servidor (com erro ou não),
|
||||
// tenta buscar o log do banco
|
||||
try {
|
||||
|
||||
await fetchLogDatabase(Number(id));
|
||||
} catch (error) {
|
||||
|
||||
console.error("Erro ao buscar log do banco:", error);
|
||||
|
||||
} finally {
|
||||
// E SOMENTE após a conclusão da busca do banco
|
||||
// (mesmo que dê erro ou traga 0 registros),
|
||||
// executa a busca no GED
|
||||
try {
|
||||
|
||||
await fetchLogGed(Number(id));
|
||||
} catch (error) {
|
||||
console.error("Erro ao buscar log do GED:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
fetchSequentially();
|
||||
}, [id]);
|
||||
|
||||
// Caso não exista log
|
||||
if (!log) {
|
||||
return <p>Nenhum dado encontrado para o cliente {id}.</p>;
|
||||
// Caso não haja log do servidor, mostra mensagem simples
|
||||
if (!logServer) {
|
||||
return (
|
||||
<p className="p-4 text-gray-500">
|
||||
Nenhum dado encontrado para o cliente {id}.
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
// Formata data e hora do log do servidor
|
||||
const { formattedDate, formattedTime, isOutdated } = formatLogDateTime(
|
||||
logServer?.data,
|
||||
logServer?.hora
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// Renderização principal da página
|
||||
// ============================================================
|
||||
return (
|
||||
<div className="p-4">
|
||||
<h1 className="text-2xl font-semibold mb-4">
|
||||
Detalhes do Log do Cliente #{id}
|
||||
<h1 className="text-2xl font-semibold mb-6">
|
||||
{logServer.cns} - {logServer.cartorio}
|
||||
</h1>
|
||||
|
||||
<div className="space-y-2">
|
||||
<p><strong>Nome:</strong> {log.name}</p>
|
||||
<p><strong>CNS:</strong> {log.cns}</p>
|
||||
<p><strong>Status:</strong> {log.status}</p>
|
||||
<p><strong>Email:</strong> {log.email}</p>
|
||||
{/* outros campos conforme LogInterface */}
|
||||
</div>
|
||||
<Tabs defaultValue="server" className="w-full">
|
||||
<TabsList className="grid w-full grid-cols-4">
|
||||
<TabsTrigger className='cursor-pointer' value="server">Informações do Servidor</TabsTrigger>
|
||||
<TabsTrigger className='cursor-pointer' value="database">Banco de Dados</TabsTrigger>
|
||||
<TabsTrigger className='cursor-pointer' value="ged">GED</TabsTrigger>
|
||||
<TabsTrigger className='cursor-pointer' value="config">Configurações</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
{/* ===================================================== */}
|
||||
{/* Aba: Informação do servidor */}
|
||||
{/* ===================================================== */}
|
||||
<TabsContent value="server">
|
||||
<div className="mt-4 space-y-6">
|
||||
{/* Badge com data e alerta */}
|
||||
<div>
|
||||
<Badge
|
||||
variant={isOutdated ? "warning" : "outline"}
|
||||
className={`ml-2 ${
|
||||
isOutdated
|
||||
? "bg-yellow-200 text-yellow-800 border-yellow-400"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
Data do log: {formattedDate} às {formattedTime}
|
||||
|
||||
{isOutdated && (
|
||||
<span>
|
||||
- Atenção: Log do servidor desatualizado
|
||||
</span>
|
||||
)}
|
||||
|
||||
</Badge>
|
||||
|
||||
</div>
|
||||
|
||||
{/* Linha com dois cards lado a lado */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{/* Sistema Operacional */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Sistema Operacional</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-1">
|
||||
<p><strong>SO:</strong> {logServer.server.operacional_system.so}</p>
|
||||
<p><strong>Versão:</strong> {logServer.server.operacional_system.versao}</p>
|
||||
<p><strong>Release:</strong> {logServer.server.operacional_system.release}</p>
|
||||
<p>
|
||||
<strong>Arquitetura:</strong>
|
||||
<Badge variant="outline" className="ml-2">
|
||||
{logServer.server.operacional_system.arquitetura}
|
||||
</Badge>
|
||||
</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Memória */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Memória</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<p><strong>Total:</strong> {logServer.server.memory.total_MB} MB</p>
|
||||
<p><strong>Usada:</strong> {logServer.server.memory.usada_MB} MB</p>
|
||||
<p><strong>Livre:</strong> {logServer.server.memory.livre_MB} MB</p>
|
||||
<p><strong>Buffer:</strong> {logServer.server.memory.buffer_MB} MB</p>
|
||||
<p><strong>Swap Total:</strong> {logServer.server.memory.swap_total_MB} MB</p>
|
||||
<p><strong>Swap Usada:</strong> {logServer.server.memory.swap_usada_MB} MB</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Processadores */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Processadores</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ScrollArea className="h-[250px] w-full rounded-md border">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="text-center">Núcleo</TableHead>
|
||||
<TableHead className="text-center">Modelo</TableHead>
|
||||
<TableHead className="text-center">Clock (MHz)</TableHead>
|
||||
<TableHead className="text-center">Cache</TableHead>
|
||||
<TableHead className="text-center">Threads</TableHead>
|
||||
<TableHead className="text-center">Núcleos</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{logServer.server.cpu.map((cpuItem: any, index: number) => (
|
||||
<TableRow key={index}>
|
||||
<TableCell className="text-center">{cpuItem.núcleo}</TableCell>
|
||||
<TableCell className="text-center text-sm">{cpuItem.modelo}</TableCell>
|
||||
<TableCell className="text-center">{cpuItem.clock_mhz}</TableCell>
|
||||
<TableCell className="text-center">{cpuItem.cache}</TableCell>
|
||||
<TableCell className="text-center">{cpuItem.threads}</TableCell>
|
||||
<TableCell className="text-center">{cpuItem.núcleos}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</ScrollArea>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
{/* ===================================================== */}
|
||||
{/* Aba: Banco de Dados */}
|
||||
{/* ===================================================== */}
|
||||
<TabsContent value="database">
|
||||
<div className="mt-4 space-y-6">
|
||||
{/* Verifica se há dados disponíveis do banco */}
|
||||
{logDatabase?.data ? (
|
||||
<>
|
||||
{/* Badge com data e hora do log do banco */}
|
||||
<div>
|
||||
{(() => {
|
||||
const { formattedDate, formattedTime, isOutdated } =
|
||||
formatLogDateTime(logDatabase.data.data, logDatabase.data.hora);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Badge
|
||||
variant={isOutdated ? "warning" : "outline"}
|
||||
className={`ml-2 ${
|
||||
isOutdated
|
||||
? "bg-yellow-200 text-yellow-800 border-yellow-400"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
Data do log: {formattedDate} às {formattedTime}
|
||||
|
||||
{isOutdated && (
|
||||
<span>
|
||||
- Atenção: Log do banco de dados desatualizado
|
||||
</span>
|
||||
)}
|
||||
</Badge>
|
||||
</>
|
||||
);
|
||||
})()}
|
||||
</div>
|
||||
|
||||
{/* Linha de cards principais */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{/* Card: Partição do Banco */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Partição do Banco</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-1">
|
||||
<p><strong>Unidade:</strong> {logDatabase?.data?.database?.partition.unit}</p>
|
||||
<p><strong>Espaço Total:</strong> {logDatabase?.data.database?.partition.total_disk_space}</p>
|
||||
<p><strong>Espaço Usado:</strong> {logDatabase?.data.database?.partition.total_used_disk_space}</p>
|
||||
<p><strong>Espaço Livre:</strong> {logDatabase?.data.database?.partition.total_free_disk_space}</p>
|
||||
<p>
|
||||
<strong>Uso (%):</strong>{" "}
|
||||
<Badge
|
||||
variant={logDatabase.data.database?.partition.percent_used > 80 ? "destructive" : "outline"}
|
||||
className={`ml-2 ${
|
||||
logDatabase.data.database?.partition.percent_used > 80
|
||||
? "bg-red-200 text-red-800 border-red-400"
|
||||
: "bg-green-100 text-green-800 border-green-400"
|
||||
}`}
|
||||
>
|
||||
{logDatabase.data.database?.partition.percent_used.toFixed(2)}%
|
||||
</Badge>
|
||||
</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Card: Informações do Arquivo de Banco */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Informações do Arquivo</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-1">
|
||||
<p><strong>Tamanho:</strong> {convertMBtoGB(logDatabase.data.database?.file_size_mb)}</p>
|
||||
<p><strong>Acessível:</strong>{" "}
|
||||
{logDatabase.data.database?.db_accessible ? (
|
||||
<Badge variant="outline" className="bg-green-100 text-green-800 border-green-400 ml-2">
|
||||
Sim
|
||||
</Badge>
|
||||
) : (
|
||||
<Badge variant="outline" className="bg-red-100 text-red-800 border-red-400 ml-2">
|
||||
Não
|
||||
</Badge>
|
||||
)}
|
||||
</p>
|
||||
|
||||
{/* Aqui aplicamos a função */}
|
||||
{(() => {
|
||||
const { formattedDate, formattedTime } = formatDateTime(
|
||||
logDatabase?.data?.database?.last_modified
|
||||
);
|
||||
return (
|
||||
<p>
|
||||
<strong>Última Modificação:</strong> {formattedDate} às {formattedTime}
|
||||
</p>
|
||||
);
|
||||
})()}
|
||||
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Card: Gráfico/Pie de Uso da Partição */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Uso da Partição</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{renderPartitionPieChart(logDatabase.data.database?.partition)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Card: Gráfico/Bar de Uso da Partição */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Uso da Partição</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{(() => {
|
||||
const partition = logDatabase.data.database?.partition;
|
||||
if (!partition) return <p className="text-gray-500 italic">Sem dados disponíveis.</p>;
|
||||
return <PartitionBarChart used={partition.percent_used} free={partition.percent_free} />;
|
||||
})()}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<p className="text-gray-500 text-sm italic">
|
||||
Nenhum log de banco de dados disponível para este cliente.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
|
||||
{/* ===================================================== */}
|
||||
{/* Aba: GED */}
|
||||
{/* ===================================================== */}
|
||||
<TabsContent value="ged">
|
||||
<div className="mt-4 space-y-6">
|
||||
{/* Verifica se há dados disponíveis do banco */}
|
||||
{logGed?.data ? (
|
||||
<>
|
||||
{/* Badge com data e hora do log do banco */}
|
||||
<div>
|
||||
{(() => {
|
||||
const { formattedDate, formattedTime, isOutdated } =
|
||||
formatLogDateTime(logGed.data.data, logGed.data.hora);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Badge
|
||||
variant={isOutdated ? "warning" : "outline"}
|
||||
className={`ml-2 ${
|
||||
isOutdated
|
||||
? "bg-yellow-200 text-yellow-800 border-yellow-400"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
Data do log: {formattedDate} às {formattedTime}
|
||||
|
||||
{isOutdated && (
|
||||
<span>
|
||||
- Atenção: Log do GED desatualizado
|
||||
</span>
|
||||
)}
|
||||
</Badge>
|
||||
</>
|
||||
);
|
||||
})()}
|
||||
</div>
|
||||
|
||||
{/* Linha de cards principais */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{/* Card: Partição do Banco */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Partição do GED</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-1">
|
||||
<p><strong>Unidade:</strong> {logGed?.data?.ged?.partition.unit}</p>
|
||||
<p><strong>Espaço Total:</strong> {logGed?.data.ged?.partition.total_disk_space}</p>
|
||||
<p><strong>Espaço Usado:</strong> {logGed?.data.ged?.partition.total_used_disk_space}</p>
|
||||
<p><strong>Espaço Livre:</strong> {logGed?.data.ged?.partition.total_free_disk_space}</p>
|
||||
<p>
|
||||
<strong>Uso (%):</strong>{" "}
|
||||
<Badge
|
||||
variant={logGed.data.ged?.partition.percent_used > 80 ? "destructive" : "outline"}
|
||||
className={`ml-2 ${
|
||||
logGed.data.ged?.partition.percent_used > 80
|
||||
? "bg-red-200 text-red-800 border-red-400"
|
||||
: "bg-green-100 text-green-800 border-green-400"
|
||||
}`}
|
||||
>
|
||||
{logGed.data.ged?.partition.percent_used.toFixed(2)}%
|
||||
</Badge>
|
||||
</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Pasta de arquivos */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Pasta de Arquivos</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ScrollArea className="h-[250px] w-full rounded-md border">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="text-center">Caminho</TableHead>
|
||||
<TableHead className="text-center">Data</TableHead>
|
||||
<TableHead className="text-center">Hora</TableHead>
|
||||
<TableHead className="text-center">Quantidade</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{logGed?.data.ged?.arquivos.map((gedItem: any, index: number) => (
|
||||
<TableRow key={index}>
|
||||
<TableCell>{gedItem.path}</TableCell>
|
||||
<TableCell className="text-center text-sm">{gedItem.data}</TableCell>
|
||||
<TableCell className="text-center">{gedItem.hora}</TableCell>
|
||||
<TableCell className="text-center">{gedItem.quantidade}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</ScrollArea>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
|
||||
{/* Card: Gráfico/Pie de Uso da Partição */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Uso da Partição</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{renderPartitionPieChart(logGed.data.ged?.partition)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Card: Gráfico/Bar de Uso da Partição */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Uso da Partição</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{(() => {
|
||||
const partition = logGed.data.ged?.partition;
|
||||
if (!partition) return <p className="text-gray-500 italic">Sem dados disponíveis.</p>;
|
||||
return <PartitionBarChart used={partition.percent_used} free={partition.percent_free} />;
|
||||
})()}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<p className="text-gray-500 text-sm italic">
|
||||
Nenhum log de banco de dados disponível para este cliente.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</Tabs>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
46
src/components/ui/badge.tsx
Normal file
46
src/components/ui/badge.tsx
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import * as React from "react"
|
||||
import { Slot } from "@radix-ui/react-slot"
|
||||
import { cva, type VariantProps } from "class-variance-authority"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const badgeVariants = cva(
|
||||
"inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
|
||||
secondary:
|
||||
"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
|
||||
destructive:
|
||||
"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
||||
outline:
|
||||
"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
function Badge({
|
||||
className,
|
||||
variant,
|
||||
asChild = false,
|
||||
...props
|
||||
}: React.ComponentProps<"span"> &
|
||||
VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
|
||||
const Comp = asChild ? Slot : "span"
|
||||
|
||||
return (
|
||||
<Comp
|
||||
data-slot="badge"
|
||||
className={cn(badgeVariants({ variant }), className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export { Badge, badgeVariants }
|
||||
58
src/components/ui/scroll-area.tsx
Normal file
58
src/components/ui/scroll-area.tsx
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
function ScrollArea({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
|
||||
return (
|
||||
<ScrollAreaPrimitive.Root
|
||||
data-slot="scroll-area"
|
||||
className={cn("relative", className)}
|
||||
{...props}
|
||||
>
|
||||
<ScrollAreaPrimitive.Viewport
|
||||
data-slot="scroll-area-viewport"
|
||||
className="focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
|
||||
>
|
||||
{children}
|
||||
</ScrollAreaPrimitive.Viewport>
|
||||
<ScrollBar />
|
||||
<ScrollAreaPrimitive.Corner />
|
||||
</ScrollAreaPrimitive.Root>
|
||||
)
|
||||
}
|
||||
|
||||
function ScrollBar({
|
||||
className,
|
||||
orientation = "vertical",
|
||||
...props
|
||||
}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
|
||||
return (
|
||||
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
||||
data-slot="scroll-area-scrollbar"
|
||||
orientation={orientation}
|
||||
className={cn(
|
||||
"flex touch-none p-px transition-colors select-none",
|
||||
orientation === "vertical" &&
|
||||
"h-full w-2.5 border-l border-l-transparent",
|
||||
orientation === "horizontal" &&
|
||||
"h-2.5 flex-col border-t border-t-transparent",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<ScrollAreaPrimitive.ScrollAreaThumb
|
||||
data-slot="scroll-area-thumb"
|
||||
className="bg-border relative flex-1 rounded-full"
|
||||
/>
|
||||
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
||||
)
|
||||
}
|
||||
|
||||
export { ScrollArea, ScrollBar }
|
||||
31
src/packages/administrativo/data/Log/LogDatabaseData.ts
Normal file
31
src/packages/administrativo/data/Log/LogDatabaseData.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
'use server'
|
||||
// Indica que este módulo será executado no lado do servidor (Database Action do Next.js)
|
||||
|
||||
import { Methods } from '@/shared/services/api/enums/ApiMethodEnum';
|
||||
// Importa o enumerador que contém os métodos HTTP padronizados (GET, POST, PUT, DELETE)
|
||||
|
||||
import API from '@/shared/services/api/Api';
|
||||
// Importa a classe responsável por realizar requisições HTTP à API backend
|
||||
|
||||
import { withClientErrorHandler } from '@/withClientErrorHandler/withClientErrorHandler';
|
||||
// Importa o wrapper que padroniza o tratamento de erros e respostas para o cliente
|
||||
|
||||
// Função principal responsável por buscar um usuário específico pelo seu ID
|
||||
async function executeLogDatabaseData(client_id: number) {
|
||||
|
||||
// Cria uma nova instância da classe de comunicação com a API
|
||||
const api = new API();
|
||||
|
||||
// Envia uma requisição GET ao endpoint que retorna os dados de um usuário específico
|
||||
const response = await api.send({
|
||||
'method': Methods.GET, // Define o método HTTP da requisição
|
||||
'endpoint': `administrativo/log/database/${client_id}` // Monta dinamicamente o endpoint com o ID do usuário
|
||||
});
|
||||
|
||||
// Retorna a resposta recebida da API (dados do usuário ou erro)
|
||||
return response;
|
||||
}
|
||||
|
||||
// Exporta a função encapsulada com o handler de erro
|
||||
// Isso garante que exceções sejam tratadas de forma padronizada na camada superior
|
||||
export const LogDatabaseData = withClientErrorHandler(executeLogDatabaseData);
|
||||
31
src/packages/administrativo/data/Log/LogGedData.ts
Normal file
31
src/packages/administrativo/data/Log/LogGedData.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
'use server'
|
||||
// Indica que este módulo será executado no lado do servidor (Ged Action do Next.js)
|
||||
|
||||
import { Methods } from '@/shared/services/api/enums/ApiMethodEnum';
|
||||
// Importa o enumerador que contém os métodos HTTP padronizados (GET, POST, PUT, DELETE)
|
||||
|
||||
import API from '@/shared/services/api/Api';
|
||||
// Importa a classe responsável por realizar requisições HTTP à API backend
|
||||
|
||||
import { withClientErrorHandler } from '@/withClientErrorHandler/withClientErrorHandler';
|
||||
// Importa o wrapper que padroniza o tratamento de erros e respostas para o cliente
|
||||
|
||||
// Função principal responsável por buscar um usuário específico pelo seu ID
|
||||
async function executeLogGedData(client_id: number) {
|
||||
|
||||
// Cria uma nova instância da classe de comunicação com a API
|
||||
const api = new API();
|
||||
|
||||
// Envia uma requisição GET ao endpoint que retorna os dados de um usuário específico
|
||||
const response = await api.send({
|
||||
'method': Methods.GET, // Define o método HTTP da requisição
|
||||
'endpoint': `administrativo/log/ged/${client_id}` // Monta dinamicamente o endpoint com o ID do usuário
|
||||
});
|
||||
|
||||
// Retorna a resposta recebida da API (dados do usuário ou erro)
|
||||
return response;
|
||||
}
|
||||
|
||||
// Exporta a função encapsulada com o handler de erro
|
||||
// Isso garante que exceções sejam tratadas de forma padronizada na camada superior
|
||||
export const LogGedData = withClientErrorHandler(executeLogGedData);
|
||||
23
src/packages/administrativo/hooks/Log/useLogDatabaseHook.ts
Normal file
23
src/packages/administrativo/hooks/Log/useLogDatabaseHook.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { LogDatabaseInterface } from '../../interfaces/Log/LogDatabaseInterface';
|
||||
import { LogDatabaseService } from '../../services/Log/LogDatabaseService';
|
||||
import { useResponse } from '@/shared/components/response/ResponseContext';
|
||||
|
||||
export const useLogDatabaseHook = () => {
|
||||
const { setResponse } = useResponse();
|
||||
const [logDatabase, setLog] = useState<LogDatabaseInterface | null>(null);
|
||||
|
||||
const fetchLogDatabase = async (client_id: number) => {
|
||||
try {
|
||||
const response = await LogDatabaseService(client_id);
|
||||
setLog(response as LogDatabaseInterface);
|
||||
setResponse(response);
|
||||
} catch (error) {
|
||||
console.error("Erro ao buscar informação do banco de dados:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return { logDatabase, fetchLogDatabase };
|
||||
};
|
||||
23
src/packages/administrativo/hooks/Log/useLogGedHook.ts
Normal file
23
src/packages/administrativo/hooks/Log/useLogGedHook.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { LogGedInterface } from '../../interfaces/Log/LogGedInterface';
|
||||
import { LogGedService } from '../../services/Log/LogGedService';
|
||||
import { useResponse } from '@/shared/components/response/ResponseContext';
|
||||
|
||||
export const useLogGedHook = () => {
|
||||
const { setResponse } = useResponse();
|
||||
const [logGed, setLog] = useState<LogGedInterface | null>(null);
|
||||
|
||||
const fetchLogGed = async (client_id: number) => {
|
||||
try {
|
||||
const response = await LogGedService(client_id);
|
||||
setLog(response as LogGedInterface);
|
||||
setResponse(response);
|
||||
} catch (error) {
|
||||
console.error("Erro ao buscar informação do banco de dados:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return { logGed, fetchLogGed };
|
||||
};
|
||||
|
|
@ -8,15 +8,12 @@ import { useResponse } from '@/shared/components/response/ResponseContext';
|
|||
export const useLogServerHook = () => {
|
||||
const { setResponse } = useResponse();
|
||||
|
||||
const [log, setLog] = useState<LogInterface | null>(null);
|
||||
const [logServer, setLog] = useState<LogInterface | null>(null);
|
||||
|
||||
const fetchLogServer = async (client_id: number) => {
|
||||
|
||||
try {
|
||||
const response = await LogServerService(client_id);
|
||||
|
||||
console.log(response)
|
||||
|
||||
setLog(response.data);
|
||||
setResponse(response);
|
||||
} catch (error) {
|
||||
|
|
@ -26,5 +23,5 @@ export const useLogServerHook = () => {
|
|||
}
|
||||
};
|
||||
|
||||
return { log, fetchLogServer };
|
||||
return { logServer, fetchLogServer };
|
||||
};
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* Interface que representa o log de banco de dados retornado pelo endpoint /log/database.
|
||||
*/
|
||||
export interface LogDatabaseInterface {
|
||||
message?: string;
|
||||
data: {
|
||||
cns: string;
|
||||
cartorio: string;
|
||||
data: string;
|
||||
hora: string;
|
||||
database: {
|
||||
partition: {
|
||||
unit: string;
|
||||
percent_free: number;
|
||||
percent_used: number;
|
||||
total_disk_space: string;
|
||||
total_free_disk_space: string;
|
||||
total_used_disk_space: string;
|
||||
};
|
||||
file_size_mb: string;
|
||||
db_accessible: boolean;
|
||||
last_modified: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* Interface que representa o log de banco de dados retornado pelo endpoint /log/database.
|
||||
*/
|
||||
export interface LogDatabaseInterface {
|
||||
message?: string;
|
||||
data: {
|
||||
cns: string;
|
||||
cartorio: string;
|
||||
data: string;
|
||||
hora: string;
|
||||
ged: {
|
||||
partition: {
|
||||
unit: string;
|
||||
percent_free: number;
|
||||
percent_used: number;
|
||||
total_disk_space: string;
|
||||
total_free_disk_space: string;
|
||||
total_used_disk_space: string;
|
||||
};
|
||||
arquivos: [{
|
||||
path: string;
|
||||
data: string;
|
||||
hora: string;
|
||||
quantidade: number;
|
||||
}]
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -7,4 +7,9 @@ export interface LogInterface {
|
|||
client_id: number; // ID do cliente relacionado (chave estrangeira obrigatória)
|
||||
date_post?: string; // Data e hora do registro (gerada automaticamente pelo banco)
|
||||
file: object; // Dados em formato JSON (ex: informações do arquivo ou operação)
|
||||
cartorio?: string;
|
||||
server?: string;
|
||||
cns?: string;
|
||||
data?: string;
|
||||
hora?: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* Interface que representa o log de servidor retornado pelo endpoint /log/server.
|
||||
*/
|
||||
export interface LogServerInterface {
|
||||
message?: string;
|
||||
data: {
|
||||
cns: string;
|
||||
cartorio: string;
|
||||
data: string;
|
||||
hora: string;
|
||||
server: {
|
||||
operacional_system: {
|
||||
so: string;
|
||||
versao: string;
|
||||
release: string;
|
||||
arquitetura: string;
|
||||
};
|
||||
memory: {
|
||||
total_MB: number;
|
||||
usada_MB: number;
|
||||
livre_MB: number;
|
||||
buffer_MB: number;
|
||||
swap_total_MB: number;
|
||||
swap_usada_MB: number;
|
||||
};
|
||||
cpu: Array<{
|
||||
núcleo: string;
|
||||
modelo: string;
|
||||
clock_mhz: number;
|
||||
cache: string;
|
||||
threads: number;
|
||||
núcleos: number;
|
||||
}>;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
'use server'
|
||||
// Indica que este arquivo é um "Database Action", executado no lado do servidor pelo Next.js
|
||||
|
||||
import { withClientErrorHandler } from "@/withClientErrorHandler/withClientErrorHandler";
|
||||
// Importa o wrapper responsável por padronizar o tratamento de erros nas requisições do Loge
|
||||
|
||||
import { LogDatabaseData } from "../../data/Log/LogDatabaseData";
|
||||
// Importa a função que acessa a camada de dados e retorna as informações do usuário a partir do ID
|
||||
|
||||
// Função assíncrona principal responsável por buscar um usuário pelo seu ID
|
||||
async function executeLogDatabaseService(client_id: number) {
|
||||
|
||||
// Executa a função de busca de usuário, passando o ID recebido como parâmetro
|
||||
const response = await LogDatabaseData(client_id);
|
||||
|
||||
// Retorna a resposta vinda da camada de dados (usuário encontrado ou erro)
|
||||
return response;
|
||||
}
|
||||
|
||||
// Exporta o serviço com o tratamento de erros encapsulado
|
||||
// O wrapper "withClientErrorHandler" assegura respostas consistentes em caso de falhas
|
||||
export const LogDatabaseService = withClientErrorHandler(executeLogDatabaseService);
|
||||
22
src/packages/administrativo/services/Log/LogGedService.ts
Normal file
22
src/packages/administrativo/services/Log/LogGedService.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
'use server'
|
||||
// Indica que este arquivo é um "Ged Action", executado no lado do servidor pelo Next.js
|
||||
|
||||
import { withClientErrorHandler } from "@/withClientErrorHandler/withClientErrorHandler";
|
||||
// Importa o wrapper responsável por padronizar o tratamento de erros nas requisições do Loge
|
||||
|
||||
import { LogGedData } from "../../data/Log/LogGedData";
|
||||
// Importa a função que acessa a camada de dados e retorna as informações do usuário a partir do ID
|
||||
|
||||
// Função assíncrona principal responsável por buscar um usuário pelo seu ID
|
||||
async function executeLogGedService(client_id: number) {
|
||||
|
||||
// Executa a função de busca de usuário, passando o ID recebido como parâmetro
|
||||
const response = await LogGedData(client_id);
|
||||
|
||||
// Retorna a resposta vinda da camada de dados (usuário encontrado ou erro)
|
||||
return response;
|
||||
}
|
||||
|
||||
// Exporta o serviço com o tratamento de erros encapsulado
|
||||
// O wrapper "withClientErrorHandler" assegura respostas consistentes em caso de falhas
|
||||
export const LogGedService = withClientErrorHandler(executeLogGedService);
|
||||
40
src/shared/components/charts/PartitionBarChart.tsx
Normal file
40
src/shared/components/charts/PartitionBarChart.tsx
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
'use client';
|
||||
|
||||
import { ResponsiveContainer, BarChart, Bar, XAxis, Tooltip, Cell } from 'recharts';
|
||||
|
||||
interface PartitionBarChartProps {
|
||||
used: number;
|
||||
free: number;
|
||||
}
|
||||
|
||||
export function PartitionBarChart({ used, free }: PartitionBarChartProps) {
|
||||
// Estrutura dos dados do gráfico
|
||||
const barData = [
|
||||
{ name: 'Usado', value: used },
|
||||
{ name: 'Livre', value: free },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="w-full h-64">
|
||||
<ResponsiveContainer>
|
||||
<BarChart data={barData} margin={{ top: 20, right: 30, left: 0, bottom: 5 }}>
|
||||
{/* Eixo X com rótulos (Usado / Livre) */}
|
||||
<XAxis dataKey="name" />
|
||||
|
||||
{/* Tooltip com formatação percentual */}
|
||||
<Tooltip formatter={(value: number) => `${value.toFixed(2)}%`} />
|
||||
|
||||
{/* Barras com cores diferentes para "Usado" e "Livre" */}
|
||||
<Bar dataKey="value" radius={[8, 8, 0, 0]}>
|
||||
{barData.map((entry, index) => (
|
||||
<Cell
|
||||
key={`cell-${index}`}
|
||||
fill={entry.name === 'Usado' ? '#ef4444' : '#22c55e'} // vermelho para Usado, verde para Livre
|
||||
/>
|
||||
))}
|
||||
</Bar>
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
71
src/shared/components/charts/PartitionPieChart.tsx
Normal file
71
src/shared/components/charts/PartitionPieChart.tsx
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
'use client';
|
||||
|
||||
import { ResponsiveContainer, PieChart, Pie, Tooltip, Cell } from 'recharts';
|
||||
|
||||
/**
|
||||
* Função auxiliar que retorna um gráfico de pizza pronto
|
||||
* para exibição no CardContent.
|
||||
*
|
||||
* @param partition - Objeto contendo os dados da partição
|
||||
* (percent_used, percent_free, total_used_disk_space, total_free_disk_space)
|
||||
*/
|
||||
export function renderPartitionPieChart(partition: any) {
|
||||
// Verifica se há dados válidos
|
||||
if (!partition) {
|
||||
return (
|
||||
<p className="text-gray-500 text-sm italic">
|
||||
Nenhuma informação de partição disponível.
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
// Estrutura de dados para o gráfico de pizza
|
||||
const pieData = [
|
||||
{ name: 'Usado', value: partition.percent_used },
|
||||
{ name: 'Livre', value: partition.percent_free },
|
||||
];
|
||||
|
||||
// Paleta de cores das fatias (vermelho e verde)
|
||||
const COLORS = ['#ef4444', '#22c55e'];
|
||||
|
||||
// Retorna o gráfico renderizado pronto para o CardContent
|
||||
return (
|
||||
<div className="flex flex-col items-center">
|
||||
{/* Container responsivo do gráfico */}
|
||||
<div className="w-full h-64">
|
||||
<ResponsiveContainer>
|
||||
<PieChart>
|
||||
<Pie
|
||||
data={pieData}
|
||||
dataKey="value"
|
||||
nameKey="name"
|
||||
innerRadius={60}
|
||||
outerRadius={100}
|
||||
paddingAngle={3}
|
||||
label={({ name, value }) => `${name}: ${value.toFixed(1)}%`}
|
||||
>
|
||||
{pieData.map((entry, index) => (
|
||||
<Cell key={`cell-${index}`} fill={COLORS[index]} />
|
||||
))}
|
||||
</Pie>
|
||||
<Tooltip
|
||||
formatter={(value: number, name: string) => [`${value.toFixed(2)}%`, name]}
|
||||
/>
|
||||
</PieChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
|
||||
{/* Legenda abaixo do gráfico */}
|
||||
<div className="flex justify-center gap-4 mt-4 text-sm">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="w-3 h-3 rounded-full bg-red-500"></span>
|
||||
<span>Usado ({partition.total_used_disk_space})</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="w-3 h-3 rounded-full bg-green-500"></span>
|
||||
<span>Livre ({partition.total_free_disk_space})</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
21
src/shared/utils/convertMBtoGB.ts
Normal file
21
src/shared/utils/convertMBtoGB.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* Converte valor de megabytes (MB) para gigabytes (GB).
|
||||
* Aceita valores numéricos ou strings com separadores e unidades.
|
||||
* Exemplo: "22.380.281 GB" ou "22380281 MB"
|
||||
*/
|
||||
export function convertMBtoGB(value: string | number): string {
|
||||
if (!value) return '-';
|
||||
|
||||
// Extrai apenas dígitos e pontos da string
|
||||
const numericValue = parseFloat(
|
||||
String(value).replace(/[^\d.]/g, '').replace(/\.(?=.*\.)/g, '')
|
||||
);
|
||||
|
||||
if (isNaN(numericValue)) return '-';
|
||||
|
||||
// Converte MB → GB (1 GB = 1024 MB)
|
||||
const gbValue = numericValue / 1024;
|
||||
|
||||
// Arredonda para 2 casas decimais
|
||||
return `${gbValue.toFixed(2)} GB`;
|
||||
}
|
||||
16
src/shared/utils/formatDateTime.ts
Normal file
16
src/shared/utils/formatDateTime.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* Formata uma string no formato "YYYY-MM-DD HH:mm:ss"
|
||||
* para "DD/MM/YYYY" e "HH:mm".
|
||||
*/
|
||||
export function formatDateTime(datetimeString: string) {
|
||||
if (!datetimeString) return { formattedDate: '-', formattedTime: '-' };
|
||||
|
||||
const [datePart, timePart] = datetimeString.split(' ');
|
||||
const [year, month, day] = datePart.split('-');
|
||||
|
||||
// Exemplo: 2025-11-04 09:00:01 → 04/11/2025 às 09:00
|
||||
return {
|
||||
formattedDate: `${day}/${month}/${year}`,
|
||||
formattedTime: timePart ? timePart.substring(0, 5) : ''
|
||||
};
|
||||
}
|
||||
39
src/shared/utils/formatLogDateTime.ts
Normal file
39
src/shared/utils/formatLogDateTime.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import { format } from "date-fns";
|
||||
import { ptBR } from "date-fns/locale";
|
||||
|
||||
/**
|
||||
* Formata os campos "data" e "hora" de um log no padrão brasileiro
|
||||
* e indica se o log está desatualizado em relação à data/hora atual.
|
||||
*
|
||||
* @param data - Data no formato "YYYY-MM-DD"
|
||||
* @param hora - Hora no formato "HH:mm:ss"
|
||||
* @returns Objeto com data/hora formatadas e flag de desatualização
|
||||
*/
|
||||
export function formatLogDateTime(data?: string, hora?: string) {
|
||||
// Combina data e hora em um formato ISO válido (ex: "2025-11-04T09:00:01")
|
||||
const combinedDateTime = data && hora ? `${data}T${hora}` : null;
|
||||
|
||||
// Cria o objeto Date com base no datetime combinado
|
||||
const logDate = combinedDateTime ? new Date(combinedDateTime) : null;
|
||||
|
||||
// Evita erros se a data for inválida
|
||||
const isValid = logDate && !isNaN(logDate.getTime());
|
||||
|
||||
// Formata data e hora no padrão brasileiro (dd/MM/yyyy e HH:mm)
|
||||
const formattedDate = isValid
|
||||
? format(logDate!, "dd/MM/yyyy", { locale: ptBR })
|
||||
: "Data inválida";
|
||||
|
||||
const formattedTime = isValid
|
||||
? format(logDate!, "HH:mm", { locale: ptBR })
|
||||
: "--:--";
|
||||
|
||||
// Verifica se o log está desatualizado (anterior à data/hora atual)
|
||||
const isOutdated = isValid ? logDate! < new Date() : false;
|
||||
|
||||
return {
|
||||
formattedDate, // Ex: "04/11/2025"
|
||||
formattedTime, // Ex: "09:00"
|
||||
isOutdated, // true se a data/hora for anterior à atual
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue