Merge branch 'master' of http://git.hicglobalsolutions.in/BhawanSingh/va-tracker
This commit is contained in:
commit
bb8b654e93
|
|
@ -5,10 +5,10 @@
|
||||||
<!-- <link rel="icon" type="image/svg+xml" href="" /> -->
|
<!-- <link rel="icon" type="image/svg+xml" href="" /> -->
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>VA Tracker</title>
|
<title>VA Tracker</title>
|
||||||
<meta
|
<!-- <meta
|
||||||
http-equiv="Content-Security-Policy"
|
http-equiv="Content-Security-Policy"
|
||||||
content="default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self';"
|
content="default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self';"
|
||||||
/>
|
/> -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
"name": "va-tracker",
|
"name": "va-tracker",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@reduxjs/toolkit": "^2.10.1",
|
||||||
"@tailwindcss/vite": "^4.1.16",
|
"@tailwindcss/vite": "^4.1.16",
|
||||||
"axios": "^1.13.2",
|
"axios": "^1.13.2",
|
||||||
"chalk": "^5.6.2",
|
"chalk": "^5.6.2",
|
||||||
|
|
@ -17,6 +18,7 @@
|
||||||
"os-utils": "^0.0.14",
|
"os-utils": "^0.0.14",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
|
"react-redux": "^9.2.0",
|
||||||
"react-router-dom": "^7.9.5",
|
"react-router-dom": "^7.9.5",
|
||||||
"recharts": "^2.12.7",
|
"recharts": "^2.12.7",
|
||||||
"sharp": "^0.34.4",
|
"sharp": "^0.34.4",
|
||||||
|
|
@ -79,6 +81,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.5.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.5.tgz",
|
||||||
"integrity": "sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==",
|
"integrity": "sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ampproject/remapping": "^2.2.0",
|
"@ampproject/remapping": "^2.2.0",
|
||||||
"@babel/code-frame": "^7.24.2",
|
"@babel/code-frame": "^7.24.2",
|
||||||
|
|
@ -2068,6 +2071,32 @@
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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/@rollup/rollup-android-arm-eabi": {
|
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||||
"version": "4.22.4",
|
"version": "4.22.4",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz",
|
||||||
|
|
@ -2272,6 +2301,18 @@
|
||||||
"url": "https://github.com/sindresorhus/is?sponsor=1"
|
"url": "https://github.com/sindresorhus/is?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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",
|
||||||
|
"integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@szmarczak/http-timer": {
|
"node_modules/@szmarczak/http-timer": {
|
||||||
"version": "4.0.6",
|
"version": "4.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
|
||||||
|
|
@ -2747,13 +2788,14 @@
|
||||||
"version": "15.7.12",
|
"version": "15.7.12",
|
||||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
|
||||||
"integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==",
|
"integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "18.3.8",
|
"version": "18.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.8.tgz",
|
||||||
"integrity": "sha512-syBUrW3/XpnW4WJ41Pft+I+aPoDVbrBVQGEnbD7NijDGlVC+8gV/XKRY+7vMDlfPpbwYt0l1vd/Sj8bJGMbs9Q==",
|
"integrity": "sha512-syBUrW3/XpnW4WJ41Pft+I+aPoDVbrBVQGEnbD7NijDGlVC+8gV/XKRY+7vMDlfPpbwYt0l1vd/Sj8bJGMbs9Q==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
|
|
@ -2777,6 +2819,12 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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/@types/verror": {
|
"node_modules/@types/verror": {
|
||||||
"version": "1.10.10",
|
"version": "1.10.10",
|
||||||
"resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.10.tgz",
|
"resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.10.tgz",
|
||||||
|
|
@ -2983,6 +3031,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fast-deep-equal": "^3.1.1",
|
"fast-deep-equal": "^3.1.1",
|
||||||
"fast-json-stable-stringify": "^2.0.0",
|
"fast-json-stable-stringify": "^2.0.0",
|
||||||
|
|
@ -3171,7 +3220,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz",
|
||||||
"integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==",
|
"integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"archiver-utils": "^2.1.0",
|
"archiver-utils": "^2.1.0",
|
||||||
"async": "^3.2.4",
|
"async": "^3.2.4",
|
||||||
|
|
@ -3190,7 +3238,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz",
|
||||||
"integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==",
|
"integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"glob": "^7.1.4",
|
"glob": "^7.1.4",
|
||||||
"graceful-fs": "^4.2.0",
|
"graceful-fs": "^4.2.0",
|
||||||
|
|
@ -3212,7 +3259,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
|
||||||
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
|
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-util-is": "~1.0.0",
|
"core-util-is": "~1.0.0",
|
||||||
"inherits": "~2.0.3",
|
"inherits": "~2.0.3",
|
||||||
|
|
@ -3227,15 +3273,13 @@
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/archiver-utils/node_modules/string_decoder": {
|
"node_modules/archiver-utils/node_modules/string_decoder": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"safe-buffer": "~5.1.0"
|
"safe-buffer": "~5.1.0"
|
||||||
}
|
}
|
||||||
|
|
@ -3479,6 +3523,7 @@
|
||||||
"url": "https://github.com/sponsors/ai"
|
"url": "https://github.com/sponsors/ai"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"caniuse-lite": "^1.0.30001587",
|
"caniuse-lite": "^1.0.30001587",
|
||||||
"electron-to-chromium": "^1.4.668",
|
"electron-to-chromium": "^1.4.668",
|
||||||
|
|
@ -4049,7 +4094,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz",
|
||||||
"integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==",
|
"integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"buffer-crc32": "^0.2.13",
|
"buffer-crc32": "^0.2.13",
|
||||||
"crc32-stream": "^4.0.2",
|
"crc32-stream": "^4.0.2",
|
||||||
|
|
@ -4231,7 +4275,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
|
||||||
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
|
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"crc32": "bin/crc32.njs"
|
"crc32": "bin/crc32.njs"
|
||||||
},
|
},
|
||||||
|
|
@ -4244,7 +4287,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz",
|
||||||
"integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==",
|
"integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"crc-32": "^1.2.0",
|
"crc-32": "^1.2.0",
|
||||||
"readable-stream": "^3.4.0"
|
"readable-stream": "^3.4.0"
|
||||||
|
|
@ -4656,6 +4698,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-25.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-25.0.5.tgz",
|
||||||
"integrity": "sha512-ocnZV44ZqInoSFaY54fF7BlCtw+WtbrjyPrkBhaB+Ztn7GPKjmFgRbIKytifJ8h9Cib8jdFRMgjCUtkU45Y6DA==",
|
"integrity": "sha512-ocnZV44ZqInoSFaY54fF7BlCtw+WtbrjyPrkBhaB+Ztn7GPKjmFgRbIKytifJ8h9Cib8jdFRMgjCUtkU45Y6DA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"app-builder-lib": "25.0.5",
|
"app-builder-lib": "25.0.5",
|
||||||
"builder-util": "25.0.3",
|
"builder-util": "25.0.3",
|
||||||
|
|
@ -4879,7 +4922,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-25.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-25.0.5.tgz",
|
||||||
"integrity": "sha512-N2U7LGSdt4hmEhjEeIV2XJbjj2YIrTL6enfsGKfOhGTpL6GEejUmT3gjdKUqKBS5+NBx0GWhnEwD3MpO2P6Nfg==",
|
"integrity": "sha512-N2U7LGSdt4hmEhjEeIV2XJbjj2YIrTL6enfsGKfOhGTpL6GEejUmT3gjdKUqKBS5+NBx0GWhnEwD3MpO2P6Nfg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"app-builder-lib": "25.0.5",
|
"app-builder-lib": "25.0.5",
|
||||||
"archiver": "^5.3.1",
|
"archiver": "^5.3.1",
|
||||||
|
|
@ -4892,7 +4934,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"graceful-fs": "^4.2.0",
|
"graceful-fs": "^4.2.0",
|
||||||
"jsonfile": "^6.0.1",
|
"jsonfile": "^6.0.1",
|
||||||
|
|
@ -4907,7 +4948,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"universalify": "^2.0.0"
|
"universalify": "^2.0.0"
|
||||||
},
|
},
|
||||||
|
|
@ -4920,7 +4960,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
|
||||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 10.0.0"
|
"node": ">= 10.0.0"
|
||||||
}
|
}
|
||||||
|
|
@ -5202,15 +5241,6 @@
|
||||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||||
"devOptional": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/encoding": {
|
|
||||||
"version": "0.1.13",
|
|
||||||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
|
|
||||||
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"iconv-lite": "^0.6.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/end-of-stream": {
|
"node_modules/end-of-stream": {
|
||||||
"version": "1.4.4",
|
"version": "1.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||||
|
|
@ -5633,8 +5663,7 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
||||||
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
|
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/fs-extra": {
|
"node_modules/fs-extra": {
|
||||||
"version": "8.1.0",
|
"version": "8.1.0",
|
||||||
|
|
@ -6540,6 +6569,16 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"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/imurmurhash": {
|
"node_modules/imurmurhash": {
|
||||||
"version": "0.1.4",
|
"version": "0.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
|
||||||
|
|
@ -6887,8 +6926,7 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||||
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
|
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/isbinaryfile": {
|
"node_modules/isbinaryfile": {
|
||||||
"version": "5.0.2",
|
"version": "5.0.2",
|
||||||
|
|
@ -7149,7 +7187,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz",
|
||||||
"integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==",
|
"integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"readable-stream": "^2.0.5"
|
"readable-stream": "^2.0.5"
|
||||||
},
|
},
|
||||||
|
|
@ -7162,7 +7199,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
|
||||||
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
|
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-util-is": "~1.0.0",
|
"core-util-is": "~1.0.0",
|
||||||
"inherits": "~2.0.3",
|
"inherits": "~2.0.3",
|
||||||
|
|
@ -7177,15 +7213,13 @@
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/lazystream/node_modules/string_decoder": {
|
"node_modules/lazystream/node_modules/string_decoder": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"safe-buffer": "~5.1.0"
|
"safe-buffer": "~5.1.0"
|
||||||
}
|
}
|
||||||
|
|
@ -7463,36 +7497,31 @@
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
|
||||||
"integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==",
|
"integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/lodash.difference": {
|
"node_modules/lodash.difference": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
|
||||||
"integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==",
|
"integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/lodash.flatten": {
|
"node_modules/lodash.flatten": {
|
||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
|
||||||
"integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==",
|
"integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/lodash.isplainobject": {
|
"node_modules/lodash.isplainobject": {
|
||||||
"version": "4.0.6",
|
"version": "4.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||||
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
|
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/lodash.union": {
|
"node_modules/lodash.union": {
|
||||||
"version": "4.6.0",
|
"version": "4.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
|
||||||
"integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==",
|
"integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/log-symbols": {
|
"node_modules/log-symbols": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
|
|
@ -8132,7 +8161,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
|
|
@ -8757,8 +8785,7 @@
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/progress": {
|
"node_modules/progress": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
|
|
@ -8839,6 +8866,7 @@
|
||||||
"version": "18.3.1",
|
"version": "18.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
|
||||||
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
|
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"loose-envify": "^1.1.0"
|
"loose-envify": "^1.1.0"
|
||||||
},
|
},
|
||||||
|
|
@ -8850,6 +8878,7 @@
|
||||||
"version": "18.3.1",
|
"version": "18.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
|
||||||
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
|
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"loose-envify": "^1.1.0",
|
"loose-envify": "^1.1.0",
|
||||||
"scheduler": "^0.23.2"
|
"scheduler": "^0.23.2"
|
||||||
|
|
@ -8863,6 +8892,30 @@
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||||
},
|
},
|
||||||
|
"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-refresh": {
|
"node_modules/react-refresh": {
|
||||||
"version": "0.14.2",
|
"version": "0.14.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
|
||||||
|
|
@ -9001,7 +9054,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz",
|
||||||
"integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==",
|
"integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"minimatch": "^5.1.0"
|
"minimatch": "^5.1.0"
|
||||||
}
|
}
|
||||||
|
|
@ -9011,7 +9063,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
||||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"brace-expansion": "^2.0.1"
|
"brace-expansion": "^2.0.1"
|
||||||
},
|
},
|
||||||
|
|
@ -9049,6 +9100,22 @@
|
||||||
"decimal.js-light": "^2.4.1"
|
"decimal.js-light": "^2.4.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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/regenerator-runtime": {
|
"node_modules/regenerator-runtime": {
|
||||||
"version": "0.14.1",
|
"version": "0.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
|
||||||
|
|
@ -9107,6 +9174,12 @@
|
||||||
"url": "https://github.com/sponsors/jet2jet"
|
"url": "https://github.com/sponsors/jet2jet"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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": {
|
"node_modules/resolve": {
|
||||||
"version": "1.22.8",
|
"version": "1.22.8",
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
|
||||||
|
|
@ -9967,7 +10040,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
|
||||||
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
|
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bl": "^4.0.3",
|
"bl": "^4.0.3",
|
||||||
"end-of-stream": "^1.4.1",
|
"end-of-stream": "^1.4.1",
|
||||||
|
|
@ -10337,6 +10409,15 @@
|
||||||
"punycode": "^2.1.0"
|
"punycode": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/use-sync-external-store": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/utf8-byte-length": {
|
"node_modules/utf8-byte-length": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz",
|
||||||
|
|
@ -10399,6 +10480,7 @@
|
||||||
"version": "5.4.7",
|
"version": "5.4.7",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.7.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.7.tgz",
|
||||||
"integrity": "sha512-5l2zxqMEPVENgvzTuBpHer2awaetimj2BGkhBPdnwKbPNOlHsODU+oiazEZzLK7KhAnOrO+XGYJYn4ZlUhDtDQ==",
|
"integrity": "sha512-5l2zxqMEPVENgvzTuBpHer2awaetimj2BGkhBPdnwKbPNOlHsODU+oiazEZzLK7KhAnOrO+XGYJYn4ZlUhDtDQ==",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.21.3",
|
"esbuild": "^0.21.3",
|
||||||
"postcss": "^8.4.43",
|
"postcss": "^8.4.43",
|
||||||
|
|
@ -10831,7 +10913,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz",
|
||||||
"integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==",
|
"integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"archiver-utils": "^3.0.4",
|
"archiver-utils": "^3.0.4",
|
||||||
"compress-commons": "^4.1.2",
|
"compress-commons": "^4.1.2",
|
||||||
|
|
@ -10846,7 +10927,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz",
|
||||||
"integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==",
|
"integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"glob": "^7.2.3",
|
"glob": "^7.2.3",
|
||||||
"graceful-fs": "^4.2.0",
|
"graceful-fs": "^4.2.0",
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
"test:unit": "vitest src"
|
"test:unit": "vitest src"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@reduxjs/toolkit": "^2.10.1",
|
||||||
"@tailwindcss/vite": "^4.1.16",
|
"@tailwindcss/vite": "^4.1.16",
|
||||||
"axios": "^1.13.2",
|
"axios": "^1.13.2",
|
||||||
"chalk": "^5.6.2",
|
"chalk": "^5.6.2",
|
||||||
|
|
@ -27,6 +28,7 @@
|
||||||
"os-utils": "^0.0.14",
|
"os-utils": "^0.0.14",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
|
"react-redux": "^9.2.0",
|
||||||
"react-router-dom": "^7.9.5",
|
"react-router-dom": "^7.9.5",
|
||||||
"recharts": "^2.12.7",
|
"recharts": "^2.12.7",
|
||||||
"sharp": "^0.34.4",
|
"sharp": "^0.34.4",
|
||||||
|
|
|
||||||
|
|
@ -1,51 +1,52 @@
|
||||||
// electron/ipc/tokenHandler.ts
|
import { ipcMain, BrowserWindow } from "electron";
|
||||||
import { ipcMain } from 'electron';
|
import { getToken, saveToken, clearToken } from "../utils/tokenHelper.js";
|
||||||
import { getToken, saveToken, clearToken } from '../utils/tokenHelper.js';
|
import { getActiveApp, handleLogin, takeScreenshot, startWindowPolling } from "../utils/utilityFunctions.js";
|
||||||
import { getActiveApp, handleLogin, takeScreenshot } from '../utils/utilityFunctions.js';
|
import api from "../api/axiosClient.js";
|
||||||
import api from '../api/axiosClient.js';
|
|
||||||
import { getMainWindow } from '../main.js';
|
import { getMainWindow } from '../main.js';
|
||||||
import { exec } from 'child_process';
|
import { exec } from 'child_process';
|
||||||
|
|
||||||
ipcMain.handle('get-token', async (_, TOKEN_KEY: "ACCESS_TOKEN" | "REFRESH_TOKEN") => {
|
export const registerIPCHandlers = (mainWindow: BrowserWindow) => {
|
||||||
return await getToken(TOKEN_KEY);
|
console.log("⚙️ Registering IPC Handlers...");
|
||||||
|
|
||||||
|
ipcMain.handle("get-token", async (_, key: "ACCESS_TOKEN" | "REFRESH_TOKEN") => {
|
||||||
|
return await getToken(key);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('save-token', async (_, TOKEN_KEY: "ACCESS_TOKEN" | "REFRESH_TOKEN", token: string) => {
|
ipcMain.handle("save-token", async (_, key: "ACCESS_TOKEN" | "REFRESH_TOKEN", token: string) => {
|
||||||
await saveToken(TOKEN_KEY, token);
|
await saveToken(key, token);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('clear-token', async (_, TOKEN_KEY: string) => {
|
ipcMain.handle("clear-token", async (_, key: string) => {
|
||||||
await clearToken(TOKEN_KEY);
|
await clearToken(key);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.handle("upload-screenshot", async () => {
|
||||||
|
await takeScreenshot();
|
||||||
|
return { success: true };
|
||||||
|
});
|
||||||
|
|
||||||
ipcMain.handle('upload-screenshot', async () => {
|
ipcMain.handle("login-request", async (_, credentials: { email: string; password: string }) => {
|
||||||
takeScreenshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
// Handle login request from renderer
|
|
||||||
ipcMain.handle('login-request', async (event, credentials: { email: string, password: string }) => {
|
|
||||||
return handleLogin(credentials);
|
return handleLogin(credentials);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('logout-request', async () => {
|
ipcMain.handle("logout-request", async () => {
|
||||||
try {
|
try {
|
||||||
console.log("Handle Logout listened")
|
console.log("Handle Logout listened");
|
||||||
console.log("Token", await getToken("ACCESS_TOKEN"))
|
console.log("Token", await getToken("ACCESS_TOKEN"));
|
||||||
const res = await api.get("/logout");
|
const res = await api.get("/logout");
|
||||||
if (res && ("success" in res) && res.success) {
|
if (res && "success" in res && res.success) {
|
||||||
return { success: true, message: "Logout Successfully" }
|
return { success: true, message: "Logout Successfully" };
|
||||||
}
|
}
|
||||||
return { success: false, message: "" }
|
return { success: false, message: "" };
|
||||||
} catch (error) {
|
} catch {
|
||||||
return { success: false, message: "" }
|
return { success: false, message: "Logout failed" };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('get-active-app', () => {
|
ipcMain.handle("get-active-app", async () => {
|
||||||
return getActiveApp();
|
return await getActiveApp();
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('toggle-close-btn', (event, shouldEnable: boolean) => {
|
ipcMain.handle('toggle-close-btn', (event, shouldEnable: boolean) => {
|
||||||
|
|
@ -59,26 +60,11 @@ ipcMain.handle('toggle-close-btn', (event, shouldEnable: boolean) => {
|
||||||
ipcMain.handle('resize-window', (event, width: number, height: number) => {
|
ipcMain.handle('resize-window', (event, width: number, height: number) => {
|
||||||
const mainWindow = getMainWindow()
|
const mainWindow = getMainWindow()
|
||||||
console.log("toggle-close-btn Called", mainWindow)
|
console.log("toggle-close-btn Called", mainWindow)
|
||||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
// if (mainWindow && !mainWindow.isDestroyed()) {
|
||||||
mainWindow.setSize(width, height);
|
mainWindow.setSize(width, height);
|
||||||
}
|
// }
|
||||||
});
|
})
|
||||||
|
|
||||||
ipcMain.handle('get-running-apps', async () => {
|
// ✅ Start background polling when main window is ready
|
||||||
return new Promise((resolve, reject) => {
|
};
|
||||||
exec('tasklist', (err, stdout) => {
|
// startWindowPolling(mainWindow);
|
||||||
if (err) return reject(err);
|
|
||||||
|
|
||||||
const lines = stdout.split('\n').slice(3); // skip headers
|
|
||||||
const apps = lines
|
|
||||||
.map(line => line.trim().split(/\s+/))
|
|
||||||
.filter(parts => parts.length > 1)
|
|
||||||
.map(parts => ({
|
|
||||||
name: parts[0],
|
|
||||||
pid: parts[1],
|
|
||||||
}));
|
|
||||||
|
|
||||||
resolve(apps);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { getStaticData, pollResources } from './resourceManager.js';
|
||||||
import { getPreloadPath, getUIPath } from './pathResolver.js';
|
import { getPreloadPath, getUIPath } from './pathResolver.js';
|
||||||
|
|
||||||
import "./ipc/ipcHandler.js";
|
import "./ipc/ipcHandler.js";
|
||||||
|
import { registerIPCHandlers } from './ipc/ipcHandler.js';
|
||||||
|
|
||||||
let mainWindow:any = null;
|
let mainWindow:any = null;
|
||||||
|
|
||||||
|
|
@ -14,7 +15,7 @@ app.on('ready', async () => {
|
||||||
width: 500, // fixed width
|
width: 500, // fixed width
|
||||||
height: 600, // fixed height
|
height: 600, // fixed height
|
||||||
|
|
||||||
resizable: false, // prevents resizing
|
resizable: true, // prevents resizing
|
||||||
fullscreenable: false, // disables fullscreen toggle (F11 or double-click title bar)
|
fullscreenable: false, // disables fullscreen toggle (F11 or double-click title bar)
|
||||||
minimizable: false, // disables minimize button
|
minimizable: false, // disables minimize button
|
||||||
maximizable: false, // prevents maximize
|
maximizable: false, // prevents maximize
|
||||||
|
|
@ -41,6 +42,10 @@ app.on('ready', async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pollResources(mainWindow);
|
// pollResources(mainWindow);
|
||||||
|
// 🔹 Register all IPC handlers (includes polling)
|
||||||
|
registerIPCHandlers(mainWindow);
|
||||||
|
|
||||||
|
pollResources(mainWindow);
|
||||||
|
|
||||||
// IPC handlers
|
// IPC handlers
|
||||||
// ipcMainHandle('getStaticData', () => getStaticData());
|
// ipcMainHandle('getStaticData', () => getStaticData());
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ contextBridge.exposeInMainWorld('electron', {
|
||||||
getActiveAppDetails: () => ipcRenderer.invoke('get-active-app'),
|
getActiveAppDetails: () => ipcRenderer.invoke('get-active-app'),
|
||||||
toggleCloseBtn: (shouldEnable: boolean) => ipcRenderer.invoke('toggle-close-btn', shouldEnable),
|
toggleCloseBtn: (shouldEnable: boolean) => ipcRenderer.invoke('toggle-close-btn', shouldEnable),
|
||||||
resizeWindow: (width: number, height: number) => ipcRenderer.invoke('resize-window', width, height),
|
resizeWindow: (width: number, height: number) => ipcRenderer.invoke('resize-window', width, height),
|
||||||
getRunningApps: () => ipcRenderer.invoke('get-running-apps'),
|
onWindowUpdate: (callback) =>
|
||||||
|
ipcRenderer.on("window:updated", (_, data) => callback(data)),
|
||||||
} satisfies Window['electron']);
|
} satisfies Window['electron']);
|
||||||
|
|
||||||
// function ipcInvoke<Key extends keyof EventPayloadMapping>(
|
// function ipcInvoke<Key extends keyof EventPayloadMapping>(
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { desktopCapturer } from "electron";
|
import { BrowserWindow, desktopCapturer } from "electron";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
@ -95,7 +95,23 @@ export const handleLogin = async (credentials: { email: string, password: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get active window info with timestamp
|
||||||
export const getActiveApp = async () => {
|
export const getActiveApp = async () => {
|
||||||
const result = await activeWindow();
|
const result = await activeWindow();
|
||||||
return result;
|
const dataWithTime = { ...result, timestamp: new Date().toISOString() };
|
||||||
|
// console.log("🪟 Active Window with Time:", dataWithTime);
|
||||||
|
return dataWithTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Periodically send active window updates
|
||||||
|
export const startWindowPolling = (win: BrowserWindow) => {
|
||||||
|
console.log("⏱️ Started active window polling (every 5s)");
|
||||||
|
setInterval(async () => {
|
||||||
|
try {
|
||||||
|
const app = await getActiveApp();
|
||||||
|
if (app) win.webContents.send("window:updated", app);
|
||||||
|
} catch (err) {
|
||||||
|
console.error("❌ Polling error:", err);
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
};
|
};
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
// src/hooks/useActiveAppTracker.ts
|
||||||
|
import { useEffect, useRef } from "react";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
import { setActiveWindow, WindowInfo } from "../store/windowSlice";
|
||||||
|
|
||||||
|
export const useActiveAppTracker = (
|
||||||
|
isTracking: boolean,
|
||||||
|
projectId: string,
|
||||||
|
projectName: string
|
||||||
|
) => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const lastActiveRef = useRef<WindowInfo | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isTracking || !projectId) {
|
||||||
|
console.log(" Tracking not active or project not selected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(` Tracking started for project: ${projectName}`);
|
||||||
|
|
||||||
|
const fetchActiveApp = async () => {
|
||||||
|
try {
|
||||||
|
const details = (await window.electron.getActiveAppDetails()) as WindowInfo;
|
||||||
|
if (!details || !details.id) return;
|
||||||
|
|
||||||
|
const prev = lastActiveRef.current;
|
||||||
|
const hasChanged =
|
||||||
|
!prev ||
|
||||||
|
prev.title !== details.title ||
|
||||||
|
prev.owner.processId !== details.owner.processId;
|
||||||
|
|
||||||
|
if (hasChanged) {
|
||||||
|
console.log("🪟 Window changed:", details.title);
|
||||||
|
dispatch(setActiveWindow({ window: details, projectId, projectName }));
|
||||||
|
lastActiveRef.current = details;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("❌ Failed to fetch active app:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchActiveApp();
|
||||||
|
const intervalId = setInterval(fetchActiveApp, 5000);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
console.log("🛑 Stopping active window tracker");
|
||||||
|
clearInterval(intervalId);
|
||||||
|
};
|
||||||
|
}, [isTracking, dispatch, projectId, projectName]);
|
||||||
|
};
|
||||||
|
|
@ -22,7 +22,11 @@ import {
|
||||||
ShieldBan,
|
ShieldBan,
|
||||||
ChevronDown,
|
ChevronDown,
|
||||||
Play,
|
Play,
|
||||||
|
ChevronUp,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
|
import { useActiveAppTracker } from "../hooks/useActiveAppTracker";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import { RootState } from "../store";
|
||||||
|
|
||||||
interface User {
|
interface User {
|
||||||
email: string;
|
email: string;
|
||||||
|
|
@ -43,7 +47,7 @@ interface ProjectTrackingData {
|
||||||
isPaused: boolean;
|
isPaused: boolean;
|
||||||
pauseStartTime: Date | null;
|
pauseStartTime: Date | null;
|
||||||
totalPausedTime: number;
|
totalPausedTime: number;
|
||||||
accumulatedTime: number; // ✅ NEW: Stores time from previous sessions
|
accumulatedTime: number; // NEW: Stores time from previous sessions
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TrackingState {
|
interface TrackingState {
|
||||||
|
|
@ -67,11 +71,17 @@ interface DashboardLayoutProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
const DashboardLayout: React.FC<DashboardLayoutProps> = ({ setUser }) => {
|
const DashboardLayout: React.FC<DashboardLayoutProps> = ({ setUser }) => {
|
||||||
|
|
||||||
const [isSidebarOpen, setSidebarOpen] = useState(true);
|
const [isSidebarOpen, setSidebarOpen] = useState(true);
|
||||||
const [isMobile, setIsMobile] = useState(window.innerWidth < 768);
|
const [isMobile, setIsMobile] = useState(window.innerWidth < 768);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
|
const { windowLogs } = useSelector((state: RootState) => state.window);
|
||||||
|
|
||||||
|
console.log("🧾 windowLogs in component:", windowLogs);
|
||||||
|
|
||||||
|
|
||||||
// Tracking states
|
// Tracking states
|
||||||
const [selectedProject, setSelectedProject] = useState<Project | null>(null);
|
const [selectedProject, setSelectedProject] = useState<Project | null>(null);
|
||||||
const [isTracking, setIsTracking] = useState(false);
|
const [isTracking, setIsTracking] = useState(false);
|
||||||
|
|
@ -81,6 +91,8 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ setUser }) => {
|
||||||
const [endTime, setEndTime] = useState<Date | null>(null);
|
const [endTime, setEndTime] = useState<Date | null>(null);
|
||||||
const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
||||||
|
|
||||||
|
useActiveAppTracker(isTracking, selectedProject?.id, selectedProject?.projectName);
|
||||||
|
|
||||||
const [projectsData, setProjectsData] = useState<Project[]>([
|
const [projectsData, setProjectsData] = useState<Project[]>([
|
||||||
{ id: 1, projectName: "CRM Redesign", clientName: "Salesforce" },
|
{ id: 1, projectName: "CRM Redesign", clientName: "Salesforce" },
|
||||||
{ id: 2, projectName: "AI Assistant", clientName: "OpenAI" },
|
{ id: 2, projectName: "AI Assistant", clientName: "OpenAI" },
|
||||||
|
|
@ -105,21 +117,6 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ setUser }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setInterval(async () => {
|
|
||||||
const details = await window.electron.getActiveAppDetails()
|
|
||||||
console.log(details)
|
|
||||||
}, 15000)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
|
|
||||||
const toggleSidebar = () => setSidebarOpen(!isSidebarOpen);
|
|
||||||
|
|
||||||
const closeSidebarOnMobile = () => {
|
|
||||||
if (isMobile) setSidebarOpen(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const menuItems = [
|
const menuItems = [
|
||||||
{ label: "Dashboard", path: "/dashboard", icon: <Home size={18} />, exact: true },
|
{ label: "Dashboard", path: "/dashboard", icon: <Home size={18} />, exact: true },
|
||||||
{ label: "Projects", path: "/dashboard/projects", icon: <FolderKanban size={18} /> },
|
{ label: "Projects", path: "/dashboard/projects", icon: <FolderKanban size={18} /> },
|
||||||
|
|
@ -129,7 +126,7 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ setUser }) => {
|
||||||
{ label: "Help & Support", path: "/dashboard/help-support", icon: <HelpCircleIcon size={18} /> },
|
{ label: "Help & Support", path: "/dashboard/help-support", icon: <HelpCircleIcon size={18} /> },
|
||||||
];
|
];
|
||||||
|
|
||||||
// ✅ Sync global states with selected project tracking data
|
// Sync global states with selected project tracking data
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedProject) {
|
if (selectedProject) {
|
||||||
const projectData = projectTrackingMap.get(selectedProject.id);
|
const projectData = projectTrackingMap.get(selectedProject.id);
|
||||||
|
|
@ -143,7 +140,7 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ setUser }) => {
|
||||||
}
|
}
|
||||||
}, [selectedProject, projectTrackingMap]);
|
}, [selectedProject, projectTrackingMap]);
|
||||||
|
|
||||||
// ✅ Timer effect - calculates elapsed time based on timestamps + accumulated time
|
// Timer effect - calculates elapsed time based on timestamps + accumulated time
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isTracking && !isPaused && selectedProject) {
|
if (isTracking && !isPaused && selectedProject) {
|
||||||
timerRef.current = setInterval(() => {
|
timerRef.current = setInterval(() => {
|
||||||
|
|
@ -157,7 +154,7 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ setUser }) => {
|
||||||
const currentSessionTime = Math.floor((now - startTimestamp) / 1000);
|
const currentSessionTime = Math.floor((now - startTimestamp) / 1000);
|
||||||
const totalPausedTime = current.totalPausedTime || 0;
|
const totalPausedTime = current.totalPausedTime || 0;
|
||||||
|
|
||||||
// ✅ FIX: Add accumulated time from previous sessions
|
// FIX: Add accumulated time from previous sessions
|
||||||
const calculatedElapsed =
|
const calculatedElapsed =
|
||||||
(current.accumulatedTime || 0) + currentSessionTime - totalPausedTime;
|
(current.accumulatedTime || 0) + currentSessionTime - totalPausedTime;
|
||||||
|
|
||||||
|
|
@ -185,7 +182,7 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ setUser }) => {
|
||||||
};
|
};
|
||||||
}, [isTracking, isPaused, selectedProject]);
|
}, [isTracking, isPaused, selectedProject]);
|
||||||
|
|
||||||
// ✅ Start tracking
|
// Start tracking
|
||||||
const handleStartTracking = (project: Project) => {
|
const handleStartTracking = (project: Project) => {
|
||||||
if (timerRef.current) {
|
if (timerRef.current) {
|
||||||
clearInterval(timerRef.current);
|
clearInterval(timerRef.current);
|
||||||
|
|
@ -193,7 +190,7 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ setUser }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
window.electron.toggleCloseBtn(false)
|
||||||
setProjectTrackingMap((prev) => {
|
setProjectTrackingMap((prev) => {
|
||||||
const updated = new Map(prev);
|
const updated = new Map(prev);
|
||||||
const current = updated.get(project.id) || {
|
const current = updated.get(project.id) || {
|
||||||
|
|
@ -207,7 +204,7 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ setUser }) => {
|
||||||
accumulatedTime: 0,
|
accumulatedTime: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
// ✅ Keep accumulated time from previous sessions
|
// Keep accumulated time from previous sessions
|
||||||
current.startTime = now;
|
current.startTime = now;
|
||||||
current.isTracking = true;
|
current.isTracking = true;
|
||||||
current.isPaused = false;
|
current.isPaused = false;
|
||||||
|
|
@ -225,7 +222,7 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ setUser }) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// ✅ Pause/Resume tracking with pause duration tracking
|
// Pause/Resume tracking with pause duration tracking
|
||||||
const handlePauseResume = () => {
|
const handlePauseResume = () => {
|
||||||
if (!selectedProject) return;
|
if (!selectedProject) return;
|
||||||
|
|
||||||
|
|
@ -263,7 +260,7 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ setUser }) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// ✅ Stop tracking - PRESERVES elapsed time
|
// Stop tracking - PRESERVES elapsed time
|
||||||
const handleStopTracking = () => {
|
const handleStopTracking = () => {
|
||||||
if (!selectedProject) return;
|
if (!selectedProject) return;
|
||||||
|
|
||||||
|
|
@ -273,13 +270,13 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ setUser }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
window.electron.toggleCloseBtn(true)
|
||||||
setProjectTrackingMap((prev) => {
|
setProjectTrackingMap((prev) => {
|
||||||
const updated = new Map(prev);
|
const updated = new Map(prev);
|
||||||
const current = updated.get(selectedProject.id);
|
const current = updated.get(selectedProject.id);
|
||||||
if (!current) return updated;
|
if (!current) return updated;
|
||||||
|
|
||||||
// ✅ FIX: Store current elapsed time as accumulated time
|
// FIX: Store current elapsed time as accumulated time
|
||||||
current.accumulatedTime = current.elapsedTime;
|
current.accumulatedTime = current.elapsedTime;
|
||||||
current.isTracking = false;
|
current.isTracking = false;
|
||||||
current.isPaused = false;
|
current.isPaused = false;
|
||||||
|
|
@ -291,7 +288,7 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ setUser }) => {
|
||||||
setIsTracking(false);
|
setIsTracking(false);
|
||||||
setIsPaused(false);
|
setIsPaused(false);
|
||||||
setEndTime(now);
|
setEndTime(now);
|
||||||
setElapsedTime(current.elapsedTime); // ✅ Keep the elapsed time
|
setElapsedTime(current.elapsedTime); // Keep the elapsed time
|
||||||
|
|
||||||
return updated;
|
return updated;
|
||||||
});
|
});
|
||||||
|
|
@ -308,7 +305,7 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ setUser }) => {
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// ✅ Handle project selection
|
// Handle project selection
|
||||||
const handleProjectSelect = (id: number) => {
|
const handleProjectSelect = (id: number) => {
|
||||||
if (isTracking) return;
|
if (isTracking) return;
|
||||||
|
|
||||||
|
|
@ -355,6 +352,8 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ setUser }) => {
|
||||||
return `${hrs}h ${mins}m ${secs}s`;
|
return `${hrs}h ${mins}m ${secs}s`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const toggleWindowSize = useRef(true); // true -> Open, false -> Close
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
|
|
@ -413,22 +412,20 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ setUser }) => {
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{/* Dropdown */}
|
{/* Dropdown */}
|
||||||
<div className="dropdown dropdown-end">
|
<button
|
||||||
<div
|
onClick={() => {
|
||||||
tabIndex={0}
|
if (toggleWindowSize.current) {
|
||||||
role="button"
|
|
||||||
className="btn btn-sm btn-outline btn-primary p-1.5 rounded-lg"
|
window.electron.resizeWindow(500, 85)
|
||||||
>
|
toggleWindowSize.current = false;
|
||||||
<ChevronDown />
|
} else {
|
||||||
</div>
|
window.electron.resizeWindow(500, 600)
|
||||||
<ul
|
toggleWindowSize.current = true;
|
||||||
tabIndex={0}
|
}
|
||||||
className="dropdown-content menu p-2 shadow-lg bg-base-100 rounded-box w-40 mt-2"
|
}}
|
||||||
>
|
className="btn btn-xs btn-outline btn-primary ">
|
||||||
<li><a>View Logs</a></li>
|
{toggleWindowSize.current ? <ChevronDown /> : <ChevronUp />}
|
||||||
<li><a>Settings</a></li>
|
</button>
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
@ -445,8 +442,7 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ setUser }) => {
|
||||||
to={item.path}
|
to={item.path}
|
||||||
end={item.exact}
|
end={item.exact}
|
||||||
className={({ isActive }) =>
|
className={({ isActive }) =>
|
||||||
`flex items-center justify-center w-10 h-10 rounded-lg transition-all duration-150 cursor-pointer ${
|
`flex items-center justify-center w-10 h-10 rounded-lg transition-all duration-150 cursor-pointer ${isActive
|
||||||
isActive
|
|
||||||
? "bg-primary text-primary-content"
|
? "bg-primary text-primary-content"
|
||||||
: "hover:bg-base-300 text-base-content"
|
: "hover:bg-base-300 text-base-content"
|
||||||
}`
|
}`
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,11 @@ import React from 'react'
|
||||||
import ReactDOM from 'react-dom/client'
|
import ReactDOM from 'react-dom/client'
|
||||||
import App from './App'
|
import App from './App'
|
||||||
import './index.css'
|
import './index.css'
|
||||||
|
import { Provider } from "react-redux";
|
||||||
|
import { store } from "./store";
|
||||||
|
|
||||||
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
||||||
<React.StrictMode>
|
<Provider store={store}>
|
||||||
<App />
|
<App />
|
||||||
</React.StrictMode>,
|
</Provider>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React from "react";
|
import React, { useRef } from "react";
|
||||||
import { Clock, TrendingUp, Play, Square, ProjectorIcon, Pause } from "lucide-react";
|
import { Clock, TrendingUp, Play, Square, ProjectorIcon, Pause } from "lucide-react";
|
||||||
import { useOutletContext } from "react-router-dom";
|
import { useOutletContext } from "react-router-dom";
|
||||||
|
|
||||||
|
|
@ -91,6 +91,9 @@ const Dashboard: React.FC = () => {
|
||||||
? projectTrackingMap.get(selectedProject.id)
|
? projectTrackingMap.get(selectedProject.id)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="flex-1 overflow-y-auto no-scrollbar">
|
<main className="flex-1 overflow-y-auto no-scrollbar">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
|
|
@ -104,35 +107,6 @@ const Dashboard: React.FC = () => {
|
||||||
>
|
>
|
||||||
Screenshot Test
|
Screenshot Test
|
||||||
</button>
|
</button>
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
window.electron.toggleCloseBtn(true)
|
|
||||||
}}
|
|
||||||
className="btn btn-xs btn-outline mt-2">
|
|
||||||
Enable
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
window.electron.toggleCloseBtn(false)
|
|
||||||
}}
|
|
||||||
className="btn btn-xs btn-outline mt-2">
|
|
||||||
Disable
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
window.electron.resizeWindow(500, 100)
|
|
||||||
}}
|
|
||||||
className="btn btn-xs btn-outline mt-2">
|
|
||||||
Resize Toggle
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={async () => {
|
|
||||||
const res = await window.electron.getRunningApps()
|
|
||||||
console.log(res, "Line 131")
|
|
||||||
}}
|
|
||||||
className="btn btn-xs btn-outline mt-2">
|
|
||||||
Get Running Apps
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Widgets */}
|
{/* Widgets */}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { CalendarDays, Clock, FileText, CheckCircle, XCircle } from "lucide-react";
|
import { CalendarDays, Clock, FileText, CheckCircle, XCircle } from "lucide-react";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import { RootState } from "../../store";
|
||||||
|
|
||||||
interface TimesheetEntry {
|
interface TimesheetEntry {
|
||||||
id: number;
|
id: number;
|
||||||
|
|
@ -22,6 +24,10 @@ const Timesheets: React.FC = () => {
|
||||||
const totalHours = timesheetData.reduce((acc, t) => acc + t.hours, 0);
|
const totalHours = timesheetData.reduce((acc, t) => acc + t.hours, 0);
|
||||||
const approvedCount = timesheetData.filter((t) => t.status === "Approved").length;
|
const approvedCount = timesheetData.filter((t) => t.status === "Approved").length;
|
||||||
|
|
||||||
|
const { windowLogs } = useSelector((state: RootState) => state.window);
|
||||||
|
|
||||||
|
console.log("🧾 Timesheet in component:", windowLogs);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-2 max-h-screen">
|
<div className="flex flex-col gap-2 max-h-screen">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
// src/store/index.ts
|
||||||
|
import { configureStore } from "@reduxjs/toolkit";
|
||||||
|
import windowReducer from "./windowSlice";
|
||||||
|
|
||||||
|
export const store = configureStore({
|
||||||
|
reducer: {
|
||||||
|
window: windowReducer,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export type RootState = ReturnType<typeof store.getState>;
|
||||||
|
export type AppDispatch = typeof store.dispatch;
|
||||||
|
|
@ -0,0 +1,128 @@
|
||||||
|
// src/store/windowSlice.ts
|
||||||
|
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
|
export interface OwnerInfo {
|
||||||
|
processId: number;
|
||||||
|
path: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WindowInfo {
|
||||||
|
platform: string;
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
owner: OwnerInfo;
|
||||||
|
bounds: Record<string, number>;
|
||||||
|
contentBounds: Record<string, number>;
|
||||||
|
memoryUsage: number;
|
||||||
|
timestamp: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProjectWindowLog {
|
||||||
|
projectId: string;
|
||||||
|
projectName: string;
|
||||||
|
appName: string;
|
||||||
|
windowTitle: string;
|
||||||
|
platform: string;
|
||||||
|
duration: number; // in seconds
|
||||||
|
startTime: string;
|
||||||
|
endTime: string;
|
||||||
|
memoryUsage: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WindowState {
|
||||||
|
activeWindow: WindowInfo | null;
|
||||||
|
activeSince: number | null;
|
||||||
|
activeProjectId: string | null;
|
||||||
|
activeProjectName: string | null;
|
||||||
|
windowLogs: ProjectWindowLog[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState: WindowState = {
|
||||||
|
activeWindow: null,
|
||||||
|
activeSince: null,
|
||||||
|
activeProjectId: null,
|
||||||
|
activeProjectName: null,
|
||||||
|
windowLogs: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
interface SetActiveWindowPayload {
|
||||||
|
window: WindowInfo;
|
||||||
|
projectId: string;
|
||||||
|
projectName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const windowSlice = createSlice({
|
||||||
|
name: "window",
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
// ✅ Start tracking window for a project
|
||||||
|
setActiveWindow: (state, action: PayloadAction<SetActiveWindowPayload>) => {
|
||||||
|
const { window, projectId, projectName } = action.payload;
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
// 🕒 Log previous window before switching
|
||||||
|
if (state.activeWindow && state.activeSince && state.activeProjectId) {
|
||||||
|
const duration = Math.floor((now - state.activeSince) / 1000);
|
||||||
|
|
||||||
|
const logEntry: ProjectWindowLog = {
|
||||||
|
projectId: state.activeProjectId,
|
||||||
|
projectName: state.activeProjectName || "Untitled",
|
||||||
|
appName: state.activeWindow.owner.name,
|
||||||
|
windowTitle: state.activeWindow.title,
|
||||||
|
platform: state.activeWindow.platform,
|
||||||
|
duration,
|
||||||
|
startTime: new Date(state.activeSince).toISOString(),
|
||||||
|
endTime: new Date(now).toISOString(),
|
||||||
|
memoryUsage: state.activeWindow.memoryUsage,
|
||||||
|
};
|
||||||
|
|
||||||
|
state.windowLogs.push(logEntry);
|
||||||
|
console.log("🧾 Log saved:", logEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔁 Update new active window + project context
|
||||||
|
state.activeWindow = window;
|
||||||
|
state.activeSince = now;
|
||||||
|
state.activeProjectId = projectId;
|
||||||
|
state.activeProjectName = projectName;
|
||||||
|
},
|
||||||
|
|
||||||
|
// ✅ Stop tracking (finalize)
|
||||||
|
finalizeActiveWindow: (state) => {
|
||||||
|
if (state.activeWindow && state.activeSince && state.activeProjectId) {
|
||||||
|
const now = Date.now();
|
||||||
|
const duration = Math.floor((now - state.activeSince) / 1000);
|
||||||
|
|
||||||
|
const logEntry: ProjectWindowLog = {
|
||||||
|
projectId: state.activeProjectId,
|
||||||
|
projectName: state.activeProjectName || "Untitled",
|
||||||
|
appName: state.activeWindow.owner.name,
|
||||||
|
windowTitle: state.activeWindow.title,
|
||||||
|
platform: state.activeWindow.platform,
|
||||||
|
duration,
|
||||||
|
startTime: new Date(state.activeSince).toISOString(),
|
||||||
|
endTime: new Date(now).toISOString(),
|
||||||
|
memoryUsage: state.activeWindow.memoryUsage,
|
||||||
|
};
|
||||||
|
|
||||||
|
state.windowLogs.push(logEntry);
|
||||||
|
console.log("✅ Final log saved:", logEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
state.activeWindow = null;
|
||||||
|
state.activeSince = null;
|
||||||
|
state.activeProjectId = null;
|
||||||
|
state.activeProjectName = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
clearWindowLogs: (state) => {
|
||||||
|
state.windowLogs = [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { setActiveWindow, finalizeActiveWindow, clearWindowLogs } =
|
||||||
|
windowSlice.actions;
|
||||||
|
|
||||||
|
export default windowSlice.reducer;
|
||||||
|
|
@ -32,7 +32,7 @@ interface Window {
|
||||||
getActiveAppDetails: () => {};
|
getActiveAppDetails: () => {};
|
||||||
toggleCloseBtn: (shouldEnable: boolean) => {},
|
toggleCloseBtn: (shouldEnable: boolean) => {},
|
||||||
resizeWindow: (width: number, height: number) => {},
|
resizeWindow: (width: number, height: number) => {},
|
||||||
getRunningApps: () => Promise<{name: string, pid:string}[]>,
|
onWindowUpdate: (callback: (data: any) => void) => void;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue