diff --git a/package-lock.json b/package-lock.json index dc7abe4ad16..5e389ac2bf3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,12 +19,17 @@ "@hello-pangea/dnd": "^17.0.0", "@pnotify/core": "^5.2.0", "@pnotify/mobile": "^5.2.0", + "@radix-ui/react-checkbox": "^1.1.2", + "@radix-ui/react-collapsible": "^1.1.1", "@radix-ui/react-dialog": "^1.1.4", "@radix-ui/react-dropdown-menu": "^2.1.2", "@radix-ui/react-icons": "^1.3.2", "@radix-ui/react-label": "^2.1.1", "@radix-ui/react-popover": "^1.1.2", + "@radix-ui/react-radio-group": "^1.2.1", "@radix-ui/react-scroll-area": "^1.2.0", + "@radix-ui/react-select": "^2.1.2", + "@radix-ui/react-separator": "^1.1.0", "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-toast": "^1.2.2", "@radix-ui/react-tooltip": "^1.1.6", @@ -119,6 +124,49 @@ "node": ">=22.11.0" } }, + "apps/care_abdm_fe": { + "version": "1.0.0", + "extraneous": true, + "license": "ISC", + "dependencies": { + "@radix-ui/react-slot": "^1.1.1", + "@radix-ui/react-tooltip": "^1.1.5", + "@yudiel/react-qr-scanner": "^2.1.0", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "dayjs": "^1.11.13", + "hi-profiles": "^1.1.0", + "lucide-react": "^0.468.0", + "qrcode.react": "^4.2.0", + "raviger": "^4.1.2", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-i18next": "^15.2.0", + "tailwind-merge": "^2.5.5", + "tailwindcss-animate": "^1.0.7" + }, + "devDependencies": { + "@eslint/js": "^9.15.0", + "@originjs/vite-plugin-federation": "^1.3.6", + "@tailwindcss/container-queries": "^0.1.1", + "@tailwindcss/forms": "^0.5.9", + "@tailwindcss/typography": "^0.5.15", + "@types/node": "^22.10.2", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-react": "^4.3.4", + "autoprefixer": "^10.4.20", + "eslint": "^9.15.0", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.14", + "globals": "^15.12.0", + "postcss": "^8.4.49", + "tailwindcss": "^3.4.16", + "typescript": "~5.6.2", + "typescript-eslint": "^8.15.0", + "vite": "^6.0.1" + } + }, "node_modules/@actions/core": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz", @@ -195,12 +243,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", - "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "license": "MIT", "dependencies": { - "@babel/highlight": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", "picocolors": "^1.0.0" }, "engines": { @@ -208,9 +257,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.25.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.8.tgz", - "integrity": "sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz", + "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", "dev": true, "license": "MIT", "engines": { @@ -218,22 +267,22 @@ } }, "node_modules/@babel/core": { - "version": "7.25.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.8.tgz", - "integrity": "sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.25.7", - "@babel/generator": "^7.25.7", - "@babel/helper-compilation-targets": "^7.25.7", - "@babel/helper-module-transforms": "^7.25.7", - "@babel/helpers": "^7.25.7", - "@babel/parser": "^7.25.8", - "@babel/template": "^7.25.7", - "@babel/traverse": "^7.25.7", - "@babel/types": "^7.25.8", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -259,13 +308,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", - "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", + "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.25.7", + "@babel/parser": "^7.26.3", + "@babel/types": "^7.26.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -302,14 +352,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz", - "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.25.7", - "@babel/helper-validator-option": "^7.25.7", + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -478,30 +528,29 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", - "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.25.7", - "@babel/types": "^7.25.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz", - "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.25.7", - "@babel/helper-simple-access": "^7.25.7", - "@babel/helper-validator-identifier": "^7.25.7", - "@babel/traverse": "^7.25.7" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -524,9 +573,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz", - "integrity": "sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", "dev": true, "license": "MIT", "engines": { @@ -630,9 +679,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz", - "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "dev": true, "license": "MIT", "engines": { @@ -655,113 +704,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz", - "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.25.7", - "@babel/types": "^7.25.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", - "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.25.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/parser": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", - "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.26.0" + "@babel/types": "^7.26.3" }, "bin": { "parser": "bin/babel-parser.js" @@ -1885,32 +1848,32 @@ } }, "node_modules/@babel/template": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", - "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.25.7", - "@babel/parser": "^7.25.7", - "@babel/types": "^7.25.7" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", - "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", + "version": "7.26.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", + "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.25.7", - "@babel/generator": "^7.25.7", - "@babel/parser": "^7.25.7", - "@babel/template": "^7.25.7", - "@babel/types": "^7.25.7", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.3", + "@babel/parser": "^7.26.3", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.3", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1929,9 +1892,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", - "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", + "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", "dev": true, "license": "MIT", "dependencies": { @@ -2448,9 +2411,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", - "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, "license": "MIT", "engines": { @@ -3646,6 +3609,64 @@ } } }, + "node_modules/@radix-ui/react-checkbox": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.1.2.tgz", + "integrity": "sha512-/i0fl686zaJbDQLNKrkCbMyDm6FQMt4jg323k7HuqitoANm9sE23Ql8yOK3Wusk34HSLKDChhMux05FnP6KUkw==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-presence": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.1.tgz", + "integrity": "sha512-1///SnrfQHJEofLokyczERxQbWfCGQlQ2XsCZMucVs6it+lq9iw4vXy+uDn1edlb58cOZOWSldnfPAYcT4O/Yg==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-collection": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", @@ -4372,6 +4393,37 @@ } } }, + "node_modules/@radix-ui/react-radio-group": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.2.1.tgz", + "integrity": "sha512-kdbv54g4vfRjja9DNWPMxKvXblzqbpEC8kspEkZ6dVP7kQksGCn+iZHkcCz2nb00+lPdRvxrqy4WrvvV1cNqrQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-presence": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-roving-focus": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-roving-focus": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz", @@ -4448,6 +4500,87 @@ } } }, + "node_modules/@radix-ui/react-select": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.2.tgz", + "integrity": "sha512-rZJtWmorC7dFRi0owDmoijm6nSJH1tVw64QGiNIZ9PNLyBDtG+iAq+XGsya052At4BfarzY/Dhv9wrrUr6IMZA==", + "dependencies": { + "@radix-ui/number": "1.1.0", + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.1", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.0", + "@radix-ui/react-portal": "1.1.2", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.6.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", + "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.0.tgz", + "integrity": "sha512-3uBAs+egzvJBDZAzvb/n4NxxOYpnspmWxO2u5NbZ8Y6FM/NdrGSF9bop3Cf6F6C71z1rTSn8KV0Fo2ZVd79lGA==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-slot": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz", @@ -4723,6 +4856,24 @@ } } }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-slot": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz", + "integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-visually-hidden": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.1.tgz", @@ -4812,6 +4963,20 @@ } } }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz", + "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-rect": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", @@ -6046,6 +6211,59 @@ "@types/estree": "*" } }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, "node_modules/@types/concat-stream": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-2.0.3.tgz", @@ -6067,9 +6285,9 @@ } }, "node_modules/@types/dom-webcodecs": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.13.tgz", - "integrity": "sha512-O5hkiFIcjjszPIYyUSyvScyvrBoV3NOEEZx/pMlsu44TKzWNkLVBBxnxJz42in5n3QIolYOcBYFCPZZ0h8SkwQ==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.11.tgz", + "integrity": "sha512-yPEZ3z7EohrmOxbk/QTAa0yonMFkNkjnVXqbGb7D4rMr+F1dGQ8ZUFxXkyLLJuiICPejZ0AZE9Rrk9wUCczx4A==", "license": "MIT" }, "node_modules/@types/dompurify": { @@ -6171,15 +6389,22 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.9.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", - "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", + "version": "22.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", + "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", "devOptional": true, "license": "MIT", "dependencies": { - "undici-types": "~6.19.8" + "undici-types": "~6.20.0" } }, + "node_modules/@types/node/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "devOptional": true, + "license": "MIT" + }, "node_modules/@types/prop-types": { "version": "15.7.13", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", @@ -6776,17 +7001,17 @@ "peer": true }, "node_modules/@yudiel/react-qr-scanner": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@yudiel/react-qr-scanner/-/react-qr-scanner-2.0.8.tgz", - "integrity": "sha512-/7WHsdC1a/Z909J2zZxqgpUQ1iI554fZxIagucH/tFu1MhZkNIeykYI1OdZgDEwV4CzuSi+h90wwNrhmETcmRw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@yudiel/react-qr-scanner/-/react-qr-scanner-2.1.0.tgz", + "integrity": "sha512-O3832Qk8YU+vnLO+tsJalfQcXRZ1pOB9l6WrI3OdwpxkQEzukpT48M6Hc2vUUe1rFE6qapQnV3RGRFNM0S7CHw==", "license": "MIT", "dependencies": { - "barcode-detector": "^2.2.7", + "barcode-detector": "^2.3.1", "webrtc-adapter": "9.0.1" }, "peerDependencies": { - "react": "^17 || ^18", - "react-dom": "^17 || ^18" + "react": "^17 || ^18 || ^19", + "react-dom": "^17 || ^18 || ^19" } }, "node_modules/abbrev": { @@ -6797,9 +7022,9 @@ "optional": true }, "node_modules/acorn": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", - "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "devOptional": true, "license": "MIT", "bin": { @@ -7402,13 +7627,13 @@ "license": "MIT" }, "node_modules/barcode-detector": { - "version": "2.2.11", - "resolved": "https://registry.npmjs.org/barcode-detector/-/barcode-detector-2.2.11.tgz", - "integrity": "sha512-N50XZ6Rav2sxTgHXOc38/mkpVJMan11GZ8Yqi1pPMZpTJSXuZ/FpIee6OtLehZX/Vs4ZOzGbp1DgXzFCfKggWA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/barcode-detector/-/barcode-detector-2.3.1.tgz", + "integrity": "sha512-D9KEtrquS1tmBZduxBZl8qublIKnRrFqD8TAHDYcLCyrHQBo+vitIxmjMJ61LvXjXyAMalOlO7q0Oh/9Rl2PbQ==", "license": "MIT", "dependencies": { - "@types/dom-webcodecs": "^0.1.13", - "zxing-wasm": "1.2.14" + "@types/dom-webcodecs": "0.1.11", + "zxing-wasm": "1.3.4" } }, "node_modules/base64-js": { @@ -12229,12 +12454,15 @@ } }, "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "license": "MIT", "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" } }, "node_modules/lines-and-columns": { @@ -12449,19 +12677,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, "node_modules/lint-staged/node_modules/listr2": { "version": "8.2.5", "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.5.tgz", @@ -15537,9 +15752,9 @@ } }, "node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", "funding": [ { "type": "opencollective", @@ -15557,7 +15772,7 @@ "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.1.0", + "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, "engines": { @@ -15652,18 +15867,6 @@ } } }, - "node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, "node_modules/postcss-load-config/node_modules/yaml": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", @@ -16041,12 +16244,12 @@ } }, "node_modules/qrcode.react": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-4.1.0.tgz", - "integrity": "sha512-uqXVIIVD/IPgWLYxbOczCNAQw80XCM/LulYDADF+g2xDsPj5OoRwSWtIS4jGyp295wyjKstfG1qIv/I2/rNWpQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-4.2.0.tgz", + "integrity": "sha512-QpgqWi8rD9DsS9EP3z7BT+5lY5SFhsqGjpgW5DY/i3mK4M9DTBNz3ErMi8BWYEfI3L0d8GIbGmcdFAS1uIRGjA==", "license": "ISC", "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/qs": { @@ -16195,9 +16398,9 @@ } }, "node_modules/react-i18next": { - "version": "15.1.3", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.1.3.tgz", - "integrity": "sha512-J11oA30FbM3NZegUZjn8ySK903z6PLBz/ZuBYyT1JMR0QPrW6PFXvl1WoUhortdGi9dM0m48/zJQlPskVZXgVw==", + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.2.0.tgz", + "integrity": "sha512-iJNc8111EaDtVTVMKigvBtPHyrJV+KblWG73cUxqp+WmJCcwkzhWNFXmkAD5pwP2Z4woeDj/oXDdbjDsb3Gutg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.0", @@ -18158,33 +18361,33 @@ } }, "node_modules/tailwindcss": { - "version": "3.4.14", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", - "integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==", + "version": "3.4.16", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.16.tgz", + "integrity": "sha512-TI4Cyx7gDiZ6r44ewaJmt0o6BrMCT5aK5e0rmJ/G9Xq3w7CX/5VXl/zIPEJZFUK5VEqwByyhqNPycPlvcK4ZNw==", "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", - "chokidar": "^3.5.3", + "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", - "fast-glob": "^3.3.0", + "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "jiti": "^1.21.0", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", @@ -18861,7 +19064,7 @@ "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -21345,9 +21548,9 @@ } }, "node_modules/zxing-wasm": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/zxing-wasm/-/zxing-wasm-1.2.14.tgz", - "integrity": "sha512-UaYfzSmFPIEmYDt/KyPvs/H02t8jO470BBFHUIlvtmloAm8f2zdAmOL93iWYQ5QYfSnTyFPg0yzZwznlBjfg4A==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/zxing-wasm/-/zxing-wasm-1.3.4.tgz", + "integrity": "sha512-9l0QymyATF19FmI92QHe7Dayb+BUN7P7zFAt5iDgTnUf0dFWokz6GVA/W9EepjW5q8s3e89fIE/7uxpX27yqEQ==", "license": "MIT", "dependencies": { "@types/emscripten": "^1.39.13" diff --git a/package.json b/package.json index a32904af6b7..66d833128e2 100644 --- a/package.json +++ b/package.json @@ -58,12 +58,17 @@ "@hello-pangea/dnd": "^17.0.0", "@pnotify/core": "^5.2.0", "@pnotify/mobile": "^5.2.0", + "@radix-ui/react-checkbox": "^1.1.2", + "@radix-ui/react-collapsible": "^1.1.1", "@radix-ui/react-dialog": "^1.1.4", "@radix-ui/react-dropdown-menu": "^2.1.2", "@radix-ui/react-icons": "^1.3.2", "@radix-ui/react-label": "^2.1.1", "@radix-ui/react-popover": "^1.1.2", + "@radix-ui/react-radio-group": "^1.2.1", "@radix-ui/react-scroll-area": "^1.2.0", + "@radix-ui/react-select": "^2.1.2", + "@radix-ui/react-separator": "^1.1.0", "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-toast": "^1.2.2", "@radix-ui/react-tooltip": "^1.1.6", diff --git a/public/images/barcode.svg b/public/images/barcode.svg new file mode 100644 index 00000000000..a62c922e81d --- /dev/null +++ b/public/images/barcode.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/public/images/clock_history.svg b/public/images/clock_history.svg new file mode 100644 index 00000000000..a9b6dd44dd6 --- /dev/null +++ b/public/images/clock_history.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/images/filter.svg b/public/images/filter.svg new file mode 100644 index 00000000000..1650ac1d216 --- /dev/null +++ b/public/images/filter.svg @@ -0,0 +1,5 @@ + + + diff --git a/public/locale/en.json b/public/locale/en.json index b9d5c60539c..56124feba40 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -890,6 +890,7 @@ "is_upshift_case": "Is upshift case", "is_vaccinated": "Whether vaccinated", "kasp_enabled_date": "{{kasp_string}} enabled date", + "lab_tests": "Lab Tests", "label": "Label", "landline": "Indian landline", "language_selection": "Language Selection", diff --git a/src/Routers/AppRouter.tsx b/src/Routers/AppRouter.tsx index e5b3d5b3eb1..c3318ea119f 100644 --- a/src/Routers/AppRouter.tsx +++ b/src/Routers/AppRouter.tsx @@ -22,6 +22,7 @@ import { BLACKLISTED_PATHS } from "@/common/constants"; import AssetRoutes from "@/Routers/routes/AssetRoutes"; import ConsultationRoutes from "@/Routers/routes/ConsultationRoutes"; import FacilityRoutes from "@/Routers/routes/FacilityRoutes"; +import LabTestRoutes from "@/Routers/routes/LabTestRoutes"; import PatientRoutes from "@/Routers/routes/PatientRoutes"; import ResourceRoutes from "@/Routers/routes/ResourceRoutes"; import ShiftingRoutes from "@/Routers/routes/ShiftingRoutes"; @@ -47,6 +48,7 @@ const Routes: AppRoutes = { ...AssetRoutes, ...ConsultationRoutes, + ...LabTestRoutes, ...FacilityRoutes, ...PatientRoutes, ...ResourceRoutes, diff --git a/src/Routers/routes/LabTestRoutes.tsx b/src/Routers/routes/LabTestRoutes.tsx new file mode 100644 index 00000000000..bba16313965 --- /dev/null +++ b/src/Routers/routes/LabTestRoutes.tsx @@ -0,0 +1,29 @@ +import { CollectSpecimen } from "@/components/LabTest/CollectSpecimen"; +import { LabTest } from "@/components/LabTest/Index"; +import { ProcessSpecimen } from "@/components/LabTest/ProcessSpecimen"; +import { ReceiveSpecimen } from "@/components/LabTest/ReceiveSpecimen"; +import { ReviewResult } from "@/components/LabTest/ReviewResult"; +import { SendSpecimen } from "@/components/LabTest/SendSpecimen"; + +import { AppRoutes } from "@/Routers/AppRouter"; + +const LabTestRoutes: AppRoutes = { + "/lab_tests/process": () => , + "/lab_tests/:specimenId/process": ({ specimenId }) => ( + + ), + "/lab_tests/send_to_lab": () => , + "/lab_tests/receive_at_lab": () => , + "/lab_tests/:tab": () => , + "/lab_tests/:specimenId/collect": ({ specimenId }) => ( + + ), + "/lab_tests/:diagnosticReportId/review": ({ diagnosticReportId }) => ( + + ), + "/lab_tests/:diagnosticReportId/result": ({ diagnosticReportId }) => ( + + ), +}; + +export default LabTestRoutes; diff --git a/src/Utils/badgeUtils.ts b/src/Utils/badgeUtils.ts new file mode 100644 index 00000000000..46f53a75069 --- /dev/null +++ b/src/Utils/badgeUtils.ts @@ -0,0 +1,16 @@ +import { BadgeProps } from "@/components/ui/badge"; + +/** + * Dynamically maps keys to Badge variants using a provided mapping object. + * + * @param key - The key to map (e.g., "routine", "asap"). + * @param mapping - The mapping object that links keys to Badge variants. + * @param defaultVariant - A fallback variant to use if the key is not found. + */ +export const mapKeyToBadgeVariant = ( + key: string | undefined, + mapping: Record, + defaultVariant: BadgeProps["variant"] = "default", +): BadgeProps["variant"] => { + return mapping[key?.toLowerCase() || ""] || defaultVariant; +}; diff --git a/src/Utils/request/api.tsx b/src/Utils/request/api.tsx index 86886291f11..adf3cbf0b99 100644 --- a/src/Utils/request/api.tsx +++ b/src/Utils/request/api.tsx @@ -57,6 +57,14 @@ import { } from "@/components/Facility/models"; import { InsurerOptionModel } from "@/components/HCX/InsurerAutocomplete"; import { HCXPolicyModel } from "@/components/HCX/models"; +import { + Annotation, + Coding, + DiagnosticReport, + Observation, + ServiceRequest, + Specimen, +} from "@/components/LabTest/types"; import { MedibaseMedicine, Prescription } from "@/components/Medicine/models"; import { NotificationData, @@ -96,6 +104,19 @@ export interface LoginCredentials { password: string; } +export interface ValuesetExpandBody { + search?: string; + count?: number; +} + +export interface ValuesetExpandResponse { + results: { + code: string; + display: string; + system: string; + }[]; +} + const routes = { // Auth Endpoints login: { @@ -1255,6 +1276,148 @@ const routes = { }, }, }, + + labs: { + labOrderCodes: { + method: "POST", + path: "/api/v1/valueset/system-lab-order-code/expand/", + TBody: Type(), + TRes: Type(), + }, + + serviceRequest: { + create: { + method: "POST", + path: "/api/v1/service_request/", + TBody: Type<{ + code: Coding; + subject: string; + encounter: string; + priority?: ServiceRequest["priority"]; + note?: Annotation[]; + }>(), + TRes: Type(), + }, + list: { + method: "GET", + path: "/api/v1/service_request/", + TRes: Type>(), + }, + }, + + specimen: { + list: { + method: "GET", + path: "/api/v1/specimen/", + TRes: Type>(), + }, + get: { + method: "GET", + path: "/api/v1/specimen/{id}/", + TRes: Type(), + }, + collect: { + method: "POST", + path: "/api/v1/specimen/{id}/collect/", + TBody: Type<{ + identifier?: string; + }>(), + TRes: Type(), + }, + sendToLab: { + method: "POST", + path: "/api/v1/specimen/{id}/send_to_lab/", + TBody: Type<{ + lab?: string; + }>(), + TRes: Type(), + }, + ReceiveAtLab: { + method: "POST", + path: "/api/v1/specimen/{id}/receive_at_lab/", + TBody: Type<{ + accession_identifier?: string; + note?: Annotation; + condition?: Coding; + }>(), + TRes: Type(), + }, + process: { + method: "POST", + path: "/api/v1/specimen/{id}/process/", + TBody: Type<{ + process: { + description?: string; + method?: Coding; + }[]; + }>(), + TRes: Type(), + }, + }, + + diagnosticReport: { + create: { + method: "POST", + path: "/api/v1/diagnostic_report/", + TBody: Type<{ + based_on: string; + specimen: string[]; + }>(), + TRes: Type(), + }, + observations: { + method: "POST", + path: "/api/v1/diagnostic_report/{id}/observations/", + TBody: Type<{ + observations: { + id: string; + status: Observation["status"]; + main_code: Coding; + value: string; + subject_type: "patient"; + effective_datetime: string; + data_entered_by_id: number; + note: string; + }[]; + }>(), + TRes: Type(), + }, + get: { + method: "GET", + path: "/api/v1/diagnostic_report/{id}/", + TRes: Type(), + }, + list: { + method: "GET", + path: "/api/v1/diagnostic_report/", + TRes: Type>(), + }, + verify: { + method: "POST", + path: "/api/v1/diagnostic_report/{id}/verify/", + TBody: Type<{ + is_approved: boolean; + }>(), + TRes: Type(), + }, + review: { + method: "POST", + path: "/api/v1/diagnostic_report/{id}/review/", + TBody: Type<{ + is_approved: boolean; + conclusion?: string; + }>(), + TRes: Type(), + }, + }, + + labObservationCodes: { + method: "POST", + path: "/api/v1/valueset/system-lab-order-code/expand/", // TODO: change this to more appropriate path + TBody: Type(), + TRes: Type(), + }, + }, } as const; export default routes; diff --git a/src/components/Common/ResultTable.tsx b/src/components/Common/ResultTable.tsx new file mode 100644 index 00000000000..564d092b7e0 --- /dev/null +++ b/src/components/Common/ResultTable.tsx @@ -0,0 +1,56 @@ +import React from "react"; + +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; + +interface Column { + key: string; + label: string; + headerClass?: string; // Optional +} + +interface ResultTableProps { + columns: Column[]; + data: Array<{ [key: string]: React.ReactNode }>; +} + +export const ResultTable: React.FC = ({ columns, data }) => { + return ( +
+ + + + {columns.map((col) => ( + + {col.label} + + ))} + + + + {data.map((row, i) => ( + + {columns.map((col) => ( + + {row[col.key]} + + ))} + + ))} + +
+
+ ); +}; diff --git a/src/components/Common/ServiceRequestTimeline.tsx b/src/components/Common/ServiceRequestTimeline.tsx new file mode 100644 index 00000000000..ae09e86498c --- /dev/null +++ b/src/components/Common/ServiceRequestTimeline.tsx @@ -0,0 +1,119 @@ +import { CheckIcon } from "@radix-ui/react-icons"; +import React from "react"; + +export interface ProgressBarSubStep { + label: string; + status: "completed" | "active" | "pending" | "notStarted"; +} + +export interface ProgressBarStep { + label: string; + status: "completed" | "active" | "pending" | "notStarted"; + subSteps?: ProgressBarSubStep[]; +} + +interface ServiceRequestTimelineProps { + steps: ProgressBarStep[]; +} + +export const ServiceRequestTimeline: React.FC = ({ + steps, +}) => { + return ( +
+
    + {steps.map((step, index) => { + let stepIcon: React.ReactNode; + let stepLabelColor = "text-gray-600"; + + switch (step.status) { + case "completed": + stepIcon = ( + + ); + stepLabelColor = "text-green-600"; + break; + + case "active": + stepIcon = ( +
    + ); + stepLabelColor = "text-blue-600"; + break; + + case "pending": + stepIcon = ( + Pending clock icon + ); + stepLabelColor = "text-blue-600"; + break; + + case "notStarted": + default: + stepIcon = ( +
    + ); + stepLabelColor = "text-gray-400"; + break; + } + + return ( +
  • + {/* + Only render the vertical line if it's NOT the last item. + That means we conditionally add the after classes. + */} +
    + {stepIcon} +
    + +
    + {step.label} + + {/* Optional sub-steps, if any */} + {!!step.subSteps?.length && ( +
    + {step.subSteps.map((sub, subIdx) => { + let subStepColor = "text-gray-500"; + if (sub.status === "completed") { + subStepColor = "text-green-500"; + } else if (sub.status === "active") { + subStepColor = "text-blue-500"; + } else if (sub.status === "pending") { + subStepColor = "text-blue-600"; + } else { + subStepColor = "text-gray-400"; + } + + return ( + + {sub.label} + + ); + })} +
    + )} +
    +
  • + ); + })} +
+
+ ); +}; diff --git a/src/components/Common/Sidebar/Sidebar.tsx b/src/components/Common/Sidebar/Sidebar.tsx index e6d9edbc2dd..56940f94e5f 100644 --- a/src/components/Common/Sidebar/Sidebar.tsx +++ b/src/components/Common/Sidebar/Sidebar.tsx @@ -53,6 +53,11 @@ const StatelessSidebar = ({ const BaseNavItems: INavItem[] = [ { text: t("facilities"), to: "/facility", icon: "d-hospital" }, { text: t("patients"), to: "/patients", icon: "d-patient" }, + { + text: t("lab_tests"), + to: "/lab_tests/order_placed", + icon: "d-microscope", + }, { text: t("assets"), to: "/assets", icon: "d-folder" }, { text: t("shifting"), to: "/shifting", icon: "d-ambulance" }, { text: t("resource"), to: "/resource", icon: "d-book-open" }, diff --git a/src/components/Facility/ConsultationDetails/ConsultationInvestigationsTab.tsx b/src/components/Facility/ConsultationDetails/ConsultationInvestigationsTab.tsx index bbc17d925a9..9564c30e28e 100644 --- a/src/components/Facility/ConsultationDetails/ConsultationInvestigationsTab.tsx +++ b/src/components/Facility/ConsultationDetails/ConsultationInvestigationsTab.tsx @@ -36,6 +36,7 @@ export const ConsultationInvestigationsTab = (props: ConsultationTabProps) => { facilityId={props.facilityId} patientId={props.patientId} patientData={props.patientData} + consultationData={props.consultationData} /> ); diff --git a/src/components/Facility/Investigations/investigationsTab.tsx b/src/components/Facility/Investigations/investigationsTab.tsx index 1bc4c62011d..20e9b0eb37b 100644 --- a/src/components/Facility/Investigations/investigationsTab.tsx +++ b/src/components/Facility/Investigations/investigationsTab.tsx @@ -1,10 +1,14 @@ import ViewInvestigationSuggestions from "@/components/Facility/Investigations/InvestigationSuggestions"; import ViewInvestigations from "@/components/Facility/Investigations/ViewInvestigations"; +import CreateServiceRequest from "@/components/LabTest/CreateServiceRequest"; +import ListEncounterServiceRequests from "@/components/LabTest/ListEncounterServiceRequests"; import { PatientModel } from "@/components/Patient/models"; import routes from "@/Utils/request/api"; import useTanStackQueryInstead from "@/Utils/request/useQuery"; +import { ConsultationModel } from "../models"; + export interface InvestigationSessionType { session_external_id: string; session_created_date: string; @@ -15,8 +19,15 @@ export default function InvestigationTab(props: { patientId: string; facilityId: string; patientData: PatientModel; + consultationData: ConsultationModel; }) { - const { consultationId, patientId, facilityId, patientData } = props; + const { + consultationId, + patientId, + facilityId, + patientData, + consultationData, + } = props; const { data: investigations, loading: investigationLoading } = useTanStackQueryInstead(routes.getInvestigation, { pathParams: { @@ -33,6 +44,11 @@ export default function InvestigationTab(props: { return ( <> +
+ + +
+ = ({ specimenId }) => { + const { data, refetch } = useQuery(routes.labs.specimen.get, { + pathParams: { id: specimenId }, + }); + + const [openOrders, setOpenOrders] = React.useState>( + {}, + ); + + const toggleOrder = (orderId: string) => { + setOpenOrders((prev) => ({ ...prev, [orderId]: !prev[orderId] })); + }; + + const specimenDispatchedStatus = data?.dispatched_at + ? "completed" + : data?.collected_at + ? "pending" + : "notStarted"; + + const specimenReceivedStatus = data?.received_at + ? "completed" + : data?.dispatched_at + ? "pending" + : "notStarted"; + + // Need diagnostic report date from the backend to determine the status + const specimenTestInProcessStatus = + data?.status === "preliminary" + ? "completed" + : data?.received_at + ? "pending" + : "notStarted"; + + const specimenUderReviewStatus = + data?.status === "final" + ? "completed" + : data?.status === "preliminary" + ? "pending" + : "notStarted"; + + // Minimal example of steps with no sub-steps + const steps: ProgressBarStep[] = [ + { label: "Order Placed", status: "completed" }, + { + label: "Specimen Collection", + status: data?.collected_at ? "completed" : "pending", + }, + { label: "Sent to Lab", status: specimenDispatchedStatus }, + { label: "Received at Lab", status: specimenReceivedStatus }, + { label: "Test Ongoing", status: specimenTestInProcessStatus }, + { label: "Under Review", status: specimenUderReviewStatus }, + { label: "Completed", status: "notStarted" }, + ]; + + return ( +
+ {/* Left - Navigation/Progress Bar */} + + + {/* Right - Main Content */} +
+ {/* Header Section */} + + +
+

Collect Specimen

+
+ + +
+
+ + {/* Patient Details Section */} +
+
+
+

Patient Name

+

{data?.subject.name}

+
+
+

UHID

+

T105690908240017

+
+
+

{data?.subject.age ? "Age" : "YOB"}/Sex

+

+ {data?.subject.age ?? data?.subject.year_of_birth}/ + { + { 1: "Male", 2: "Female", 3: "Other", 4: "Not Mentioned" }[ + data?.subject.gender ?? 4 + ] + } +

+
+
+
+
+ toggleOrder(data?.id as string)} + > +
+
+
+
+ + Order id + +
+ + {data?.request.id.slice(0, 8)} + + + Active + +
+
+
+ + Specimen to be collected:{" "} + + {data?.type.display ?? data?.type.code} + + +
+ + + +
+
+
+ + {/* Expanded Content */} + +
+
+
+ {/* Left Section */} +
+

+ Test +

+

+ {data?.request.code.display ?? + data?.request.code.code} +

+
+ + {/* Right Section */} +
+

+ Order Placed by +

+
+

+ {[ + data?.request.requester?.first_name, + data?.request.requester?.last_name, + ].join(" ") ?? "NA"} +

+

+ {data?.request.requester?.user_type ?? "NA"} +

+
+ +

+ Order Date/Time +

+

+ {data?.request.authored_on ?? "NA"} +

+ +

+ Priority +

+ + {data?.request?.priority ?? "Routine"} + +
+
+ {/* Note Section */} +
+

+ Note: +

+

+ {data?.request.note.length + ? data?.request.note + .map((note) => note.text) + .join(" ") + : "No notes added to this request"} +

+
+
+ +
+ {/* Specimen Section */} +
+
+

+ Specimen: +

+

+ Number of samples +

+
+ +
+
+ + + + + {data?.type.display ?? data?.type.code} + +
+
+ + + 1 + + +
+
+
+
+
+
+
+

+ {data?.type.display ?? data?.type.code} +

+ + {data?.collected_at + ? "Collected" + : "Not Collected"} + +
+
+
+
+

+ Barcode +

+ + {data?.collected_at && ( + + )} +
+ {data?.collected_at ? ( +
+
+ {/* Success Badge */} +
+ + Success + + {/* Success Message */} + + Barcode scanned successfully + +
+ + {/* Barcode */} +
+ filter + + {data?.identifier ?? "Not Available"} + +
+
+
+
+

+ Tube Type +

+ + Not Available + +
+
+

+ Test +

+ + {data?.request.code.display ?? + data?.request.code.code} + +
+
+

+ Collection Date/Time +

+ + {data?.collected_at ?? "Not Available"} + +
+
+
+ ) : ( +
+
+ { + if (e.key === "Enter") { + const barcode = e.currentTarget.value; + + if (!barcode) { + return; + } + + const { res } = await request( + routes.labs.specimen.collect, + { + pathParams: { id: specimenId }, + body: { + identifier: barcode, + }, + }, + ); + + if (!res?.ok) { + return; + } + + refetch(); + } + }} + /> +
+
OR
+
+ +
+
+ )} +
+
+
+
+
+
+
+
+
+
+
+
+ ); +}; diff --git a/src/components/LabTest/ConsolidatedResults.tsx b/src/components/LabTest/ConsolidatedResults.tsx new file mode 100644 index 00000000000..9384e3ffeb4 --- /dev/null +++ b/src/components/LabTest/ConsolidatedResults.tsx @@ -0,0 +1,97 @@ +import React, { useState } from "react"; + +import CareIcon from "@/CAREUI/icons/CareIcon"; + +import { Button } from "@/components/ui/button"; +import { + Collapsible, + CollapsibleContent, + CollapsibleTrigger, +} from "@/components/ui/collapsible"; + +import { ResultTable } from "@/components/Common/ResultTable"; + +interface ConsolidatedResultsProps { + orderId: string; + columns: Array<{ + key: string; + label: string; + }>; + resultsData: Array; +} + +export const ConsolidatedResults: React.FC = ({ + orderId, + columns, + resultsData, +}) => { + const [isOpen, setIsOpen] = useState(false); + + return ( + +
+
+

+ Consolidated Test Results +

+

{orderId}

+
+ +
+ + + + + +
+
+ +
+
+
+
+ carelabs logo +
+
+ +
+
+ +
+
+ Logo +
+
+
+
+
+ ); +}; diff --git a/src/components/LabTest/CreateServiceRequest.tsx b/src/components/LabTest/CreateServiceRequest.tsx new file mode 100644 index 00000000000..f52e5519a51 --- /dev/null +++ b/src/components/LabTest/CreateServiceRequest.tsx @@ -0,0 +1,182 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { useState } from "react"; +import { useTranslation } from "react-i18next"; + +import CareIcon from "@/CAREUI/icons/CareIcon"; + +import * as Notification from "@/Utils/Notifications"; +import routes from "@/Utils/request/api"; +import request from "@/Utils/request/request"; + +import { ConsultationModel } from "../Facility/models"; +import { Button } from "../ui/button"; +import { Card, CardFooter, CardHeader } from "../ui/card"; +import { Label } from "../ui/label"; +import { RadioGroup, RadioGroupItem } from "../ui/radio-group"; +import { Textarea } from "../ui/textarea"; +import LabOrderCodeSelect from "./LabOrderCodeSelect"; +import { Annotation, Coding, ServiceRequest } from "./types"; + +type CreateServiceRequestProps = { + encounter: ConsultationModel; +}; + +export default function CreateServiceRequest({ + encounter, +}: CreateServiceRequestProps) { + const { t } = useTranslation(); + + const [code, setCode] = useState(); + const [note, setNote] = useState([]); + const [priority, setPriority] = useState(); + const [recurrence, setRecurrence] = useState(); + + const handleNoteChange = (e: React.ChangeEvent) => { + const updatedNote: Annotation[] = [ + { + text: e.target.value, + authorString: "CurrentUser", // Replace with actual user + time: new Date().toISOString(), + }, + ]; + setNote(updatedNote); + }; + + const queryClient = useQueryClient(); + + const { mutate: createServiceRequest, isPending } = useMutation({ + mutationFn: (body: { + code: Coding; + subject: string; + encounter: string; + priority: ServiceRequest["priority"]; + note: Annotation[]; + }) => + request(routes.labs.serviceRequest.create, { + body, + }), + onSuccess: () => { + Notification.Success({ msg: "Test ordered successfully" }); + + setCode(undefined); + setNote([{ text: "", authorString: "", time: "" }]); + setPriority(undefined); + + queryClient.invalidateQueries({ + queryKey: [ + routes.labs.serviceRequest.list.path, + { encounter: encounter.id }, + ], + }); + }, + onError: () => { + Notification.Error({ msg: "Failed to order test" }); + }, + }); + + const handleOrderTest = () => { + if (!code) { + return; + } + + createServiceRequest({ + code, + subject: encounter.patient, + encounter: encounter.id, + priority, + note, + }); + }; + + return ( + + + + + {note !== undefined && ( +
+ +