Ver a proveniência

add unsubmitted time sheet chart

tags/Baseline_30082024_FRONTEND_UAT
Mac\David há 1 ano
ascendente
cometimento
a06d9644dc
2 ficheiros alterados com 453 adições e 71 eliminações
  1. +213
    -70
      package-lock.json
  2. +240
    -1
      src/components/StaffUtilization/StaffUtilization.tsx

+ 213
- 70
package-lock.json Ver ficheiro

@@ -14,6 +14,7 @@
"@faker-js/faker": "^8.4.1",
"@fontsource/inter": "^5.0.16",
"@fontsource/plus-jakarta-sans": "^5.0.18",
"@fullcalendar/react": "^6.1.11",
"@mui/icons-material": "^5.15.0",
"@mui/material": "^5.15.0",
"@mui/material-nextjs": "^5.15.0",
@@ -21,13 +22,14 @@
"@mui/x-date-pickers": "^6.18.7",
"@unly/universal-language-detector": "^2.0.3",
"apexcharts": "^3.45.2",
"axios": "^1.6.8",
"date-holidays": "^3.23.11",
"dayjs": "^1.11.10",
"fullcalendar": "^6.1.11",
"i18next": "^23.7.11",
"i18next-resources-to-backend": "^1.2.0",
"lodash": "^4.17.21",
"next": "14.0.4",
"next-auth": "^4.24.5",
"next-auth": "^4.24.7",
"next-pwa": "^5.6.0",
"react": "^18",
"react-apexcharts": "^1.4.1",
@@ -2081,6 +2083,79 @@
"tslib": "^2.4.0"
}
},
"node_modules/@fullcalendar/core": {
"version": "6.1.11",
"resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.11.tgz",
"integrity": "sha512-TjG7c8sUz+Vkui2FyCNJ+xqyu0nq653Ibe99A66LoW95oBo6tVhhKIaG1Wh0GVKymYiqAQN/OEdYTuj4ay27kA==",
"dependencies": {
"preact": "~10.12.1"
}
},
"node_modules/@fullcalendar/core/node_modules/preact": {
"version": "10.12.1",
"resolved": "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz",
"integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/preact"
}
},
"node_modules/@fullcalendar/daygrid": {
"version": "6.1.11",
"resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.11.tgz",
"integrity": "sha512-hF5jJB7cgUIxWD5MVjj8IU407HISyLu7BWXcEIuTytkfr8oolOXeCazqnnjmRbnFOncoJQVstTtq6SIhaT32Xg==",
"peerDependencies": {
"@fullcalendar/core": "~6.1.11"
}
},
"node_modules/@fullcalendar/interaction": {
"version": "6.1.11",
"resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.11.tgz",
"integrity": "sha512-ynOKjzuPwEAMgTQ6R/Z2zvzIIqG4p8/Qmnhi1q0vzPZZxSIYx3rlZuvpEK2WGBZZ1XEafDOP/LGfbWoNZe+qdg==",
"peerDependencies": {
"@fullcalendar/core": "~6.1.11"
}
},
"node_modules/@fullcalendar/list": {
"version": "6.1.11",
"resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-6.1.11.tgz",
"integrity": "sha512-9Qx8uvik9pXD12u50FiHwNzlHv4wkhfsr+r03ycahW7vEeIAKCsIZGTkUfFP+96I5wHihrfLazu1cFQG4MPiuw==",
"peerDependencies": {
"@fullcalendar/core": "~6.1.11"
}
},
"node_modules/@fullcalendar/multimonth": {
"version": "6.1.11",
"resolved": "https://registry.npmjs.org/@fullcalendar/multimonth/-/multimonth-6.1.11.tgz",
"integrity": "sha512-7DbPC+AAlaKnquGVdw1Z85Q3nSZ4GZ1NcVIk4k7bLnqDlntwHPPsrDlSIzUWKcN0q5/u7jQHm4PU1m3LAl70Sg==",
"dependencies": {
"@fullcalendar/daygrid": "~6.1.11"
},
"peerDependencies": {
"@fullcalendar/core": "~6.1.11"
}
},
"node_modules/@fullcalendar/react": {
"version": "6.1.11",
"resolved": "https://registry.npmjs.org/@fullcalendar/react/-/react-6.1.11.tgz",
"integrity": "sha512-Og0Tv0OiglTFp+b++yRyEhAeWnAmKkMLQ3iS0eJE1KDEov6QqGkoO+dUG4x8zp2w55IJqzik/a9iHi0s3oQDbA==",
"peerDependencies": {
"@fullcalendar/core": "~6.1.11",
"react": "^16.7.0 || ^17 || ^18",
"react-dom": "^16.7.0 || ^17 || ^18"
}
},
"node_modules/@fullcalendar/timegrid": {
"version": "6.1.11",
"resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.11.tgz",
"integrity": "sha512-0seUHK/ferH89IeuCvV4Bib0zWjgK0nsptNdmAc9wDBxD/d9hm5Mdti0URJX6bDoRtsSfRDu5XsRcrzwoc+AUQ==",
"dependencies": {
"@fullcalendar/daygrid": "~6.1.11"
},
"peerDependencies": {
"@fullcalendar/core": "~6.1.11"
}
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.14",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
@@ -3648,8 +3723,7 @@
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"node_modules/aria-query": {
"version": "5.3.0",
@@ -3855,6 +3929,14 @@
"integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==",
"dev": true
},
"node_modules/astronomia": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/astronomia/-/astronomia-4.1.1.tgz",
"integrity": "sha512-TcJD9lUC5eAo0/Ji7rnQauX/yQbi0yZWM+JsNr77W3OA5fsrgvuFgubLMFwfw4VlZ29cu9dG/yfJbfvuTSftjg==",
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/async": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
@@ -3869,11 +3951,6 @@
"has-symbols": "^1.0.3"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/at-least-node": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
@@ -3942,16 +4019,6 @@
"node": ">=4"
}
},
"node_modules/axios": {
"version": "1.6.8",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz",
"integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/axobject-query": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz",
@@ -4136,6 +4203,17 @@
"node": ">=10.16.0"
}
},
"node_modules/caldate": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/caldate/-/caldate-2.0.5.tgz",
"integrity": "sha512-JndhrUuDuE975KUhFqJaVR1OQkCHZqpOrJur/CFXEIEhWhBMjxO85cRSK8q4FW+B+yyPq6GYua2u4KvNzTcq0w==",
"dependencies": {
"moment-timezone": "^0.5.43"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/call-bind": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
@@ -4337,17 +4415,6 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
@@ -4489,6 +4556,68 @@
"integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==",
"dev": true
},
"node_modules/date-bengali-revised": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/date-bengali-revised/-/date-bengali-revised-2.0.2.tgz",
"integrity": "sha512-q9iDru4+TSA9k4zfm0CFHJj6nBsxP7AYgWC/qodK/i7oOIlj5K2z5IcQDtESfs/Qwqt/xJYaP86tkazd/vRptg==",
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/date-chinese": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/date-chinese/-/date-chinese-2.1.4.tgz",
"integrity": "sha512-WY+6+Qw92ZGWFvGtStmNQHEYpNa87b8IAQ5T8VKt4wqrn24lBXyyBnWI5jAIyy7h/KVwJZ06bD8l/b7yss82Ww==",
"dependencies": {
"astronomia": "^4.1.0"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/date-easter": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/date-easter/-/date-easter-1.0.3.tgz",
"integrity": "sha512-aOViyIgpM4W0OWUiLqivznwTtuMlD/rdUWhc5IatYnplhPiWrLv75cnifaKYhmQwUBLAMWLNG4/9mlLIbXoGBQ==",
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/date-holidays": {
"version": "3.23.12",
"resolved": "https://registry.npmjs.org/date-holidays/-/date-holidays-3.23.12.tgz",
"integrity": "sha512-DLyP0PPVgNydgaTAY7SBS26+5h3KO1Z8FRKiAROkz0hAGNBLGAM48SMabfVa2ACRHH7Qw3LXYvlJkt9oa9WePA==",
"dependencies": {
"date-holidays-parser": "^3.4.4",
"js-yaml": "^4.1.0",
"lodash": "^4.17.21",
"prepin": "^1.0.3"
},
"bin": {
"holidays2json": "scripts/holidays2json.cjs"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/date-holidays-parser": {
"version": "3.4.4",
"resolved": "https://registry.npmjs.org/date-holidays-parser/-/date-holidays-parser-3.4.4.tgz",
"integrity": "sha512-R5aO4oT8H51ZKdvApqHrqYEiNBrqT6tRj2PFXNcZfqMI4nxY7KKKly0ZsmquR5gY+x9ldKR8SAMdozzIInaoXg==",
"dependencies": {
"astronomia": "^4.1.1",
"caldate": "^2.0.5",
"date-bengali-revised": "^2.0.2",
"date-chinese": "^2.1.4",
"date-easter": "^1.0.2",
"deepmerge": "^4.3.1",
"jalaali-js": "^1.2.6",
"moment-timezone": "^0.5.43"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/dayjs": {
"version": "1.11.10",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz",
@@ -4626,14 +4755,6 @@
"rimraf": "bin.js"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/dequal": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
@@ -5706,25 +5827,6 @@
"integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
"dev": true
},
"node_modules/follow-redirects": {
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/for-each": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@@ -5802,6 +5904,19 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/fullcalendar": {
"version": "6.1.11",
"resolved": "https://registry.npmjs.org/fullcalendar/-/fullcalendar-6.1.11.tgz",
"integrity": "sha512-OOlx/+yFn9k5LnucRzcDmShONBecOVKNN6HHWe8jl7hGzQBmkxO+iD6eBokO6p24EY1PjATqhZkhJqHiCUgx3A==",
"dependencies": {
"@fullcalendar/core": "~6.1.11",
"@fullcalendar/daygrid": "~6.1.11",
"@fullcalendar/interaction": "~6.1.11",
"@fullcalendar/list": "~6.1.11",
"@fullcalendar/multimonth": "~6.1.11",
"@fullcalendar/timegrid": "~6.1.11"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -6755,6 +6870,11 @@
"node": ">=8"
}
},
"node_modules/jalaali-js": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/jalaali-js/-/jalaali-js-1.2.6.tgz",
"integrity": "sha512-io974va+Qyu+UfuVX3UIAgJlxLhAMx9Y8VMfh+IG00Js7hXQo1qNQuwSiSa0xxco0SVgx5HWNkaiCcV+aZ8WPw=="
},
"node_modules/jest-worker": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
@@ -6800,9 +6920,9 @@
}
},
"node_modules/jose": {
"version": "4.15.4",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz",
"integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==",
"version": "4.15.5",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz",
"integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==",
"funding": {
"url": "https://github.com/sponsors/panva"
}
@@ -6816,7 +6936,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dev": true,
"dependencies": {
"argparse": "^2.0.1"
},
@@ -7135,6 +7254,7 @@
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"peer": true,
"engines": {
"node": ">= 0.6"
}
@@ -7143,6 +7263,7 @@
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"peer": true,
"dependencies": {
"mime-db": "1.52.0"
},
@@ -7183,6 +7304,25 @@
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/moment": {
"version": "2.30.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
"engines": {
"node": "*"
}
},
"node_modules/moment-timezone": {
"version": "0.5.45",
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz",
"integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==",
"dependencies": {
"moment": "^2.29.4"
},
"engines": {
"node": "*"
}
},
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -7275,14 +7415,14 @@
}
},
"node_modules/next-auth": {
"version": "4.24.6",
"resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.24.6.tgz",
"integrity": "sha512-djQt3ZEaWEIxcsuh3HTW2uuzLfXMRjHH+ugAsichlQSbH4iA5MRcgMA2HvTNvsDTDLh44tyU72+/gWsxgTbAKg==",
"version": "4.24.7",
"resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.24.7.tgz",
"integrity": "sha512-iChjE8ov/1K/z98gdKbn2Jw+2vLgJtVV39X+rCP5SGnVQuco7QOr19FRNGMIrD8d3LYhHWV9j9sKLzq1aDWWQQ==",
"dependencies": {
"@babel/runtime": "^7.20.13",
"@panva/hkdf": "^1.0.2",
"cookie": "^0.5.0",
"jose": "^4.11.4",
"jose": "^4.15.5",
"oauth": "^0.9.15",
"openid-client": "^5.4.0",
"preact": "^10.6.3",
@@ -7993,6 +8133,14 @@
"node": ">= 0.8.0"
}
},
"node_modules/prepin": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/prepin/-/prepin-1.0.3.tgz",
"integrity": "sha512-0XL2hreherEEvUy0fiaGEfN/ioXFV+JpImqIzQjxk6iBg4jQ2ARKqvC4+BmRD8w/pnpD+lbxvh0Ub+z7yBEjvA==",
"bin": {
"prepin": "bin/prepin.js"
}
},
"node_modules/prettier": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz",
@@ -8057,11 +8205,6 @@
"react-is": "^16.13.1"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",


+ 240
- 1
src/components/StaffUtilization/StaffUtilization.tsx Ver ficheiro

@@ -124,6 +124,8 @@ const StaffUtilization: React.FC = () => {
const [manHoursSpentPeriod, setManHoursSpentPeriod]: any[] = React.useState(
firstDayOfWeekString + " to " + lastDayOfWeekString,
);
const [unsubmittedTimeSheetSelect, setUnsubmittedTimeSheetSelect]: any =
React.useState("Weekly");
const [teamTotalManhoursSpentSelect, setTeamTotalManhoursSpentSelect]: any =
React.useState("Weekly");
const [staffGradeManhoursSpentSelect, setStaffGradeManhoursSpentSelect]: any =
@@ -165,6 +167,10 @@ const StaffUtilization: React.FC = () => {
individualStaffManhoursSpentPeriod,
setIndividualStaffManhoursSpentPeriod,
]: any[] = React.useState(weekDates);
const [
unsubmittedTimeSheetPeriod,
setUnsubmittedTimeSheetPeriod,
]: any[] = React.useState(weekDates);
const [
teamTotalManhoursSpentPlanData,
setTeamTotalManhoursSpentPlanData,
@@ -179,6 +185,8 @@ const StaffUtilization: React.FC = () => {
React.useState<Dayjs | null>(dayjs());
const [weeklyValueByIndividualStaff, setWeeklyValueByIndividualStaff] =
React.useState<Dayjs | null>(dayjs());
const [weeklyUnsubmittedTimeSheet, setWeeklyUnsubmittedTimeSheet ] =
React.useState<Dayjs | null>(dayjs());
const [staffGradeManhoursSpentValue, setStaffGradeManhoursSpentValue] =
React.useState<Dayjs | null>(dayjs());
const [totalManHoursMonthlyFromValue, setTotalManHoursMonthlyFromValue] =
@@ -424,6 +432,56 @@ const StaffUtilization: React.FC = () => {
],
};

const unsubmittedTimeSheetOptions: ApexOptions = {
chart: {
height: 350,
type: "line",
},
stroke: {
width: [1],
},
plotOptions: {
bar: {
horizontal: true,
distributed: false,
},
},
dataLabels: {
enabled: true,
},
xaxis: {
categories: [
"001-Staff A",
"002-Staff B",
"005-Staff E",
"006-Staff F",
"007-Staff G",
],
},
yaxis: [
{
title: {
text: "Staff",
},
min: 0,
max: 12,
tickAmount: 5,
},
],
grid: {
borderColor: "#f1f1f1",
},
annotations: {},
series: [
{
name: "Unsubmitted Time Sheet",
type: "bar",
color: "#00acb1",
data: [2, 2, 1, 5, 1],
},
],
};

const teamTotalManhoursSpentOnClick = (r: any) => {
setTeamTotalManhoursSpentSelect(r);
if (r === "Weekly") {
@@ -456,6 +514,10 @@ const StaffUtilization: React.FC = () => {
// }
};

const unsubmittedTimeSheetOnClick = (r: any) => {
setUnsubmittedTimeSheetSelect(r);
};

const selectWeeklyPeriod = (r: any) => {
const selectDate = new Date(r);
const firstDayOfWeek = new Date();
@@ -486,6 +548,21 @@ const StaffUtilization: React.FC = () => {
setWeeklyValueByStaffGrade(dayjs(firstDayOfWeek));
};

const selectWeeklyPeriodUnsubmittedTimeSheet = (r: any) => {
const selectDate = new Date(r);
const firstDayOfWeek = new Date();
firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0);
const weekDates: any[] = [];
for (let i = 0; i < 7; i++) {
const currentDate = new Date(firstDayOfWeek);
currentDate.setDate(firstDayOfWeek.getDate() + i);
const formattedDate = dayjs(currentDate).format("DD MMM (ddd)");
weekDates.push(formattedDate);
}
setUnsubmittedTimeSheetPeriod(weekDates);
setWeeklyUnsubmittedTimeSheet(dayjs(firstDayOfWeek));
};

const selectWeeklyPeriodIndividualStaff = (r: any) => {
const selectDate = new Date(r);
const firstDayOfWeek = new Date();
@@ -589,6 +666,28 @@ const StaffUtilization: React.FC = () => {
setTeamTotalManhoursByStaffGrade(weekDates);
};

const selectUnsubmittedTimeSheetMonthlyPeriodFrom = (r: any) => {
const monthDates: any[] = [];
const monthPlanData: any[] = [];
const monthActualData: any[] = [];
const selectFromDate = dayjs(r);
for (
let date = selectFromDate.clone();
date.isBefore(totalManHoursMonthlyToValue, "month");
date = date.add(1, "month")
) {
monthDates.push(date.format("MM-YYYY"));
monthPlanData.push(840);
monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
}
monthDates.push(totalManHoursMonthlyToValue.format("MM-YYYY"));
monthPlanData.push(840);
monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
// setTeamTotalManhoursSpentPlanData(monthPlanData)
// setTeamTotalManhoursSpentActualData(monthActualData)
setUnsubmittedTimeSheetPeriod(weekDates);
};

const selectIndividualStaffMonthlyPeriodFrom = (r: any) => {
const monthDates: any[] = [];
const monthPlanData: any[] = [];
@@ -611,6 +710,28 @@ const StaffUtilization: React.FC = () => {
setIndividualStaffManhoursSpentPeriod(weekDates);
};

const selectUnsubmittedTimeSheetMonthlyPeriodTo = (r: any) => {
const monthDates: any[] = [];
const monthPlanData: any[] = [];
const monthActualData: any[] = [];
const selectToDate = dayjs(r);
for (
let date = totalManHoursMonthlyFromValue.clone();
date.isBefore(selectToDate, "month");
date = date.add(1, "month")
) {
monthDates.push(date.format("MM-YYYY"));
monthPlanData.push(840);
monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
}
monthDates.push(selectToDate.format("MM-YYYY"));
monthPlanData.push(840);
monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
// setTeamTotalManhoursSpentPlanData(monthPlanData)
// setTeamTotalManhoursSpentActualData(monthActualData)
setUnsubmittedTimeSheetPeriod(weekDates);
};

const selectIndividualStaffMonthlyPeriodTo = (r: any) => {
const monthDates: any[] = [];
const monthPlanData: any[] = [];
@@ -934,7 +1055,125 @@ const StaffUtilization: React.FC = () => {
}}
>
<Grid item xs={12} md={12} lg={12}>
<Card>
<Card className="mb-5">
<CardHeader
className="text-slate-500"
title="Unsubmitted Time Sheet by Staff"
/>
<div style={{ display: "inline-block", width: "99%" }}>
<div className="w-fit align-top mr-5 float-right">
{unsubmittedTimeSheetSelect === "Weekly" && (
<>
<button className="text-lg bg-violet-100 border-violet-500 text-violet-500 border-solid w-32">
Weekly
</button>
<button
onClick={() =>
unsubmittedTimeSheetOnClick("Monthly")
}
className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid rounded-r-md w-32"
>
Monthly
</button>
</>
)}
{unsubmittedTimeSheetSelect === "Monthly" && (
<>
<button
onClick={() =>
unsubmittedTimeSheetOnClick("Weekly")
}
className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid w-32"
>
Weekly
</button>
<button className="text-lg bg-violet-100 border-violet-500 text-violet-500 border-solid rounded-r-md w-32">
Monthly
</button>
</>
)}
</div>
<div className="inline-block w-fit mt-2">
<div className="inline-block ml-6">
<Label className="text-slate-500 font-medium">
Team:&nbsp;
</Label>
</div>
<div className="inline-block ml-1 w-60">
<Select
placeholder="Team"
options={teamOptions}
isClearable={true}
/>
</div>
<div className="ml-6 mt-2" style={{ verticalAlign: "top" }}>
{/* <Label className="text-slate-500 font-medium ml-6">
Period:&nbsp;
</Label> */}
{unsubmittedTimeSheetSelect === "Weekly" && (
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DatePicker
className="w-72 h-10 align-top"
label="Period:"
value={value}
format="DD-MM-YYYY"
onChange={(newValue) =>
selectWeeklyPeriodUnsubmittedTimeSheet(newValue)
}
showDaysOutsideCurrentMonth
displayWeekNumber
slots={{ day: Day }}
slotProps={{
day: (ownerState) =>
({
selectedDay: value,
hoveredDay,
onPointerEnter: () =>
setHoveredDay(ownerState.day),
onPointerLeave: () => setHoveredDay(null),
}) as any,
}}
/>
</LocalizationProvider>
)}
{unsubmittedTimeSheetSelect === "Monthly" && (
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DatePicker
className="w-40 h-10 align-top"
onChange={(newValue) =>
selectUnsubmittedTimeSheetMonthlyPeriodFrom(newValue)
}
defaultValue={
totalManHoursByIndividualStaffMonthlyFromValue
}
label={"Form"}
views={["month", "year"]}
/>
<DatePicker
className="w-40 h-10 align-top"
onChange={(newValue) =>
selectUnsubmittedTimeSheetMonthlyPeriodTo(newValue)
}
defaultValue={
totalManHoursByIndividualStaffMonthlyToValue
}
label={"To"}
views={["month", "year"]}
/>
</LocalizationProvider>
)}
</div>
</div>

<ReactApexChart
options={unsubmittedTimeSheetOptions}
series={unsubmittedTimeSheetOptions.series}
type="bar"
height="380"
/>
</div>
</Card>
<Card>
<Card>
<CardHeader
className="text-slate-500"


Carregando…
Cancelar
Guardar