diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index 79e4d357951..2dc9083996d 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -138,4 +138,3 @@ jobs: - name: Notify release run: | echo "Release ${{ github.sha }} is ready to be deployed to production" - diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 2bf60f375fc..df21d84ffe9 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -22,7 +22,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: '20' + node-version: "20" - name: Install dependencies run: npm ci diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f86deec34a4..0c52bfd7124 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: steps: - uses: actions/checkout@v3 with: - fetch-depth: 0 # Necessary to fetch all tags + fetch-depth: 0 # Necessary to fetch all tags - name: Calculate next tag id: calc_tag diff --git a/.prettierrc.json b/.prettierrc.json index 22765ca5aa1..4daaccae376 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -3,11 +3,25 @@ "useTabs": false, "tabWidth": 2, "semi": true, + "endOfLine": "lf", "jsxSingleQuote": false, "arrowParens": "always", "tailwindFunctions": ["classNames"], - "importOrder": ["", "^@/lib/(.*)$", "^@/CAREUI/(.*)$", "^@/components/ui/(.*)$", "^@/components/(.*)$", "^@/hooks/(.*)$", "^@/common/(.*)$", "^@/(.*)$", "^[./]"], + "importOrder": [ + "", + "^@/lib/(.*)$", + "^@/CAREUI/(.*)$", + "^@/components/ui/(.*)$", + "^@/components/(.*)$", + "^@/hooks/(.*)$", + "^@/common/(.*)$", + "^@/(.*)$", + "^[./]" + ], "importOrderSeparation": true, "importOrderSortSpecifiers": true, - "plugins": ["prettier-plugin-tailwindcss", "@trivago/prettier-plugin-sort-imports"] -} \ No newline at end of file + "plugins": [ + "prettier-plugin-tailwindcss", + "@trivago/prettier-plugin-sort-imports" + ] +} diff --git a/.vscode/launch.json b/.vscode/launch.json index d512e87ec49..187bc5f3a42 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,23 +1,18 @@ { - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Run application", - "type": "node", - "request": "launch", - "cwd": "${workspaceFolder}", - "console": "integratedTerminal", - "runtimeExecutable": "npm", - "runtimeArgs": [ - "run-script", - "dev" - ], - "skipFiles": [ - "/**" - ] - } - ] -} \ No newline at end of file + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Run application", + "type": "node", + "request": "launch", + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", + "runtimeExecutable": "npm", + "runtimeArgs": ["run-script", "dev"], + "skipFiles": ["/**"] + } + ] +} diff --git a/crowdin.yml b/crowdin.yml index 2680a939e52..5885b582bee 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -2,4 +2,4 @@ files: - source: public/locale//{{lang}}.json translation: /public/locale/%two_letters_code%.json bundles: - - 2 \ No newline at end of file + - 2 diff --git a/cypress/docs/cypress.md b/cypress/docs/cypress.md index 5e28cef49f0..471cd13dc4d 100644 --- a/cypress/docs/cypress.md +++ b/cypress/docs/cypress.md @@ -1,14 +1,17 @@ # Cypress Testing Documentation ## Overview + This documentation covers the testing standards and patterns for our Cypress test suite. ## Quick Links + - [File Structure and Organization](./file-structure.md) - [Testing Patterns](./patterns.md) - [Best Practices](./best-practices.md) ## Core Principles + - Create and use reusable commands and functions - Use data-cy attributes for element identification - Follow Page Object Model pattern @@ -16,10 +19,12 @@ This documentation covers the testing standards and patterns for our Cypress tes - Use TypeScript for better type safety ## Getting Started + 1. Familiarize yourself with the file structure 2. Review the testing patterns 3. Follow the best practices 4. Use the provided examples as templates ## Support + For questions or clarifications, refer to the specific documentation sections or reach out to the team. diff --git a/public/locale/en.json b/public/locale/en.json index b1e6f09c724..99d270229b3 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -396,9 +396,12 @@ "app_settings": "App Settings", "apply": "Apply", "appointment_booking_success": "Your appointment has been successfully booked!", + "appointment_cancelled": "Appointment has been cancelled!", "appointment_created_success": "Appointment created successfully", "appointment_details": "Appointment Details", "appointment_not_found": "Appointment not found", + "appointment_rescheduled": "Appointment has been rescheduled!", + "appointment_rescheduled_successfully": "Appointment rescheduled successfully", "appointment_type": "Appointment Type", "appointments": "Appointments", "approve": "Approve", @@ -1757,6 +1760,9 @@ "required": "Required", "required_quantity": "Required Quantity", "reschedule": "Reschedule", + "reschedule_appointment": "Reschedule Appointment", + "rescheduled": "Rescheduled", + "rescheduling": "Rescheduling...", "resend_otp": "Resend OTP", "reset": "Reset", "reset_password": "Reset Password", diff --git a/src/CAREUI/icons/DuoTonePaths.json b/src/CAREUI/icons/DuoTonePaths.json index 663f71a7dba..4ece14dfd64 100644 --- a/src/CAREUI/icons/DuoTonePaths.json +++ b/src/CAREUI/icons/DuoTonePaths.json @@ -1,72 +1,72 @@ { - "d-people": [ - 24, - "M14.6,10.9c.7.7,1.66,1.1,2.65,1.1s1.95-.4,2.65-1.1c.7-.7,1.1-1.66,1.1-2.65s-.4-1.95-1.1-2.65c-.7-.7-1.66-1.1-2.65-1.1s-1.95.4-2.65,1.1c-.7.7-1.1,1.66-1.1,2.65s.4,1.95,1.1,2.65ZM16.5,19.5c0,.52-.1,1.03-.32,1.5h6.32s1.5,0,1.5-1.5-1.5-6-7.5-6c-.98-.01-1.96.13-2.9.42,1.88,1.45,2.9,3.55,2.9,5.58Z", - true, - null, - "M13.5,21s1.5,0,1.5-1.5-1.5-6-7.5-6S0,18,0,19.5s1.5,1.5,1.5,1.5h12ZM7.5,12c-1.19,0-2.34-.47-3.18-1.32-.84-.84-1.32-1.99-1.32-3.18s.47-2.34,1.32-3.18c.84-.84,1.99-1.32,3.18-1.32s2.34.47,3.18,1.32c.84.84,1.32,1.99,1.32,3.18s-.47,2.34-1.32,3.18c-.84.84-1.99,1.32-3.18,1.32Z" - ], - "d-bell": [ - 24, - "M13.62,22.62c-.56.56-1.33.88-2.12.88s-1.56-.32-2.12-.88c-.56-.56-.88-1.33-.88-2.12h6c0,.8-.32,1.56-.88,2.12Z", - true, - null, - "M12.99,1.65c.02-.21,0-.42-.07-.62-.07-.2-.17-.38-.31-.54-.14-.16-.31-.28-.5-.36-.19-.09-.4-.13-.61-.13s-.42.04-.61.13c-.19.09-.36.21-.5.36-.14.16-.25.34-.31.54-.07.2-.09.41-.07.62-1.7.34-3.22,1.26-4.32,2.6-1.09,1.34-1.69,3.02-1.69,4.75,0,1.65-.75,9-3,10.5h21c-2.25-1.5-3-8.85-3-10.5,0-3.63-2.58-6.66-6.01-7.35Z" - ], - "d-book-open": [ - 24, - "M11.75,3.02c1.57-.95,2.95-1.46,4.45-1.73,1.55-.27,3.12-.29,4.7-.29.56,0,.84,0,1.06.11.19.1.34.25.44.44.11.21.11.5.11,1.06v8.96c0,1.59,0,2.39-.29,3-.27.57-.63.97-1.18,1.29-.58.35-1.5.43-3.33.6-.42.04-.83.09-1.24.16-1.73.3-3.25,1.09-4.71,2.03V3.02ZM2.75,18.51c-.41,0-.75.34-.75.75s.34.75.75.75c1.97,0,3.4.12,4.68.47,1.27.35,2.45.93,3.91,1.9.25.17.58.17.83,0,1.46-.97,2.63-1.55,3.91-1.9,1.28-.35,2.7-.47,4.68-.47.41,0,.75-.34.75-.75s-.34-.75-.75-.75c-2.03,0-3.6.13-5.07.53-1.34.37-2.56.95-3.93,1.83-1.37-.88-2.59-1.46-3.93-1.83-1.47-.4-3.05-.53-5.07-.53Z", - true, - null, - "M11.75,3.02c-1.57-.95-2.95-1.46-4.45-1.73-1.55-.27-3.12-.29-4.7-.29-.56,0-.84,0-1.06.11-.19.1-.34.25-.44.44-.11.21-.11.5-.11,1.06v8.96c0,1.59,0,2.39.29,3,.27.57.63.97,1.18,1.29.58.35,1.5.43,3.33.6.42.04.83.09,1.24.16,1.73.3,3.25,1.09,4.71,2.03V3.02Z" - ], - "d-patient": [ - 24, - "M12.5,9.66c2.67,0,4.83-2.16,4.83-4.83S15.17,0,12.5,0s-4.83,2.16-4.83,4.83,2.16,4.83,4.83,4.83Z", - true, - null, - "M19.48,12.64c-.26-.26-.55-.5-.86-.69-.26-.17-.53-.31-.82-.43l-1.61,11.62h-4.15l4.07-12.01c-.1,0-.2,0-.31,0h-6.61c-1.39,0-2.69.54-3.67,1.52-.98.98-1.52,2.29-1.52,3.67v4.51c0,1.27,1.04,2.31,2.31,2.31h4.82l-.1.29c-.05.13-.02.28.06.39.08.11.21.18.35.18h5.13c.22,0,.4-.16.43-.37l.07-.49v-.06c1.04-.23,1.81-1.15,1.81-2.25,0-.86-.47-1.63-1.21-2.03l.12-.9c1.18.49,1.95,1.64,1.95,2.93,0,.91-.38,1.73-1,2.31h2.25v-6.82c0-1.39-.54-2.69-1.52-3.67h0ZM7.67,18.52c-.24,0-.43-.19-.43-.43v-1.77c0-.24.19-.43.43-.43s.43.19.43.43v1.34h4.89l-.29.87h-5.02Z" - ], - "d-calendar": [ - 24, - "M7,2c.55,0,1,.45,1,1v1h7v-1c0-.55.45-1,1-1s1,.45,1,1v1h2.5c1.38,0,2.5,1.12,2.5,2.5v2.5H1v-2.5c0-1.38,1.12-2.5,2.5-2.5h2.5v-1c0-.55.45-1,1-1ZM5,13c-.55,0-1,.45-1,1s.45,1,1,1h.01c.55,0,1-.45,1-1s-.45-1-1-1h-.01ZM5,17c-.55,0-1,.45-1,1s.45,1,1,1h.01c.55,0,1-.45,1-1s-.45-1-1-1h-.01ZM9,14c0-.55.45-1,1-1h.01c.55,0,1,.45,1,1s-.45,1-1,1h-.01c-.55,0-1-.45-1-1ZM10,17c-.55,0-1,.45-1,1s.45,1,1,1h.01c.55,0,1-.45,1-1s-.45-1-1-1h-.01ZM14,14c0-.55.45-1,1-1h.01c.55,0,1,.45,1,1s-.45,1-1,1h-.01c-.55,0-1-.45-1-1Z", - true, - null, - "M1,20v-11h21v11c0,1.66-1.34,3-3,3H4c-1.66,0-3-1.34-3-3Z" - ], - "d-folder": [ - 24, - "M2,10v-5c0-1.66,1.34-3,3-3h4.31c.62,0,1.2.29,1.58.78l1.81,2.34c.19.24.48.39.79.39h6.51c1.1,0,2,.9,2,2v2.5c0,1.1-.9,2-2,2H4c-1.1,0-2-.9-2-2Z", - true, - null, - "M2.24,19.04l-.2-14c-.02-1.67,1.33-3.04,3-3.04h4.23c.61,0,1.19.28,1.57.76l1.88,2.38c.18.22.44.36.73.38l6.46.37c1.05.06,1.87.92,1.89,1.97l.16,11.1c.02,1.67-1.33,3.04-3,3.04H5.24c-1.64,0-2.98-1.32-3-2.96Z" - ], - "d-ambulance": [ - 24, - "M15.44,7.06c0-.25.1-.49.28-.66.18-.18.42-.28.66-.28s.49.1.66.28c.18.18.28.42.28.66v.95h-1.89v-.95ZM19.41,9.05l1.29,2.53,1.91,1.02c.32.17.59.44.79.75.18.31.3.68.3,1.05v.23h0c.08,0,.16.03.23.08.06.06.08.14.08.23v1.47c0,.08-.03.16-.1.23-.06.06-.14.08-.23.08h0v.04c0,.07-.01.14-.04.21s-.07.13-.13.18-.11.1-.18.13-.14.04-.21.04h-2.22c-.01-.66-.3-1.3-.78-1.77s-1.12-.72-1.78-.72-1.31.25-1.78.72c-.48.47-.76,1.1-.78,1.77h-1.26v-8.96h3.73c.24,0,.47.07.66.18.2.13.37.3.47.51h.03ZM15.75,13.09h1.24s.11-.03.14-.06c.04-.04.06-.08.06-.14s-.03-.11-.06-.14c-.04-.04-.08-.06-.14-.06h-1.24s-.11.03-.14.06c-.04.04-.06.08-.06.14s.03.11.06.14c.04.04.08.06.14.06ZM15.54,9.25v2.83h4.31l-1.31-2.47c-.06-.11-.14-.2-.24-.25s-.23-.1-.34-.1h-2.42ZM5.31,15.38c-1.12,0-2.03.91-2.03,2.03s.91,2.03,2.03,2.03,2.03-.91,2.03-2.03-.91-2.03-2.03-2.03ZM5.31,18.23c-.45,0-.82-.37-.82-.82s.37-.82.82-.82.82.37.82.82-.37.82-.82.82ZM18.39,15.38c-1.12,0-2.03.91-2.03,2.03s.91,2.03,2.03,2.03,2.03-.91,2.03-2.03-.91-2.03-2.03-2.03ZM18.39,18.23c-.45,0-.82-.37-.82-.82s.37-.82.82-.82.82.37.82.82-.37.82-.82.82Z", - true, - null, - "M.34,14.62V5.91c0-.1.01-.2.06-.28s.1-.17.17-.24.16-.13.24-.17.18-.06.28-.06h2.09c0-.16.07-.3.17-.41.11-.11.25-.17.41-.17h6.36c.16,0,.3.06.41.17s.17.25.17.41h2.5c.2,0,.4.08.54.23s.23.34.23.54v11.4h-6.09c-.01-.66-.3-1.3-.78-1.77s-1.12-.72-1.78-.72-1.31.25-1.78.72c-.48.47-.76,1.1-.78,1.77h-1.67c-.17,0-.34-.06-.48-.17s-.23-.25-.27-.42h-.03c-.08,0-.16-.03-.23-.08-.06-.06-.08-.14-.08-.23v-1.47c0-.08.03-.16.08-.23.06-.06.23-.08.23-.08l.03-.03ZM5.27,11.4h1.33v1.33h1.45v-1.33h1.33v-1.45h-1.33v-1.33h-1.45v1.33h-1.33v1.45Z" - ], - "d-microscope": [ - 24, - "M2.9,5.43c-.21-.21-.21-.55,0-.76l3.29-3.29c.21-.21.55-.21.76,0l6.07,6.07c.21.21.21.55,0,.76l-3.29,3.29c-.21.21-.55.21-.76,0L2.9,5.43ZM4.97,22.33c0-.3.24-.54.54-.54h10.55c.3,0,.54.24.54.54v1.13c0,.3-.24.54-.54.54H5.5c-.3,0-.54-.24-.54-.54v-1.13ZM15.29,15.68c-.3,0-.54.24-.54.54v.76c0,.3.24.54.54.54h6.88c.3,0,.54-.24.54-.54v-.76c0-.3-.24-.54-.54-.54h-6.88Z", - true, - null, - "M1.67,2.43c-.21.21-.21.55,0,.76l1.35,1.35,3.03-3.03L4.7.16c-.21-.21-.55-.21-.76,0L1.67,2.43ZM19.55,17.52c-.71,1.07-1.67,1.99-2.82,2.71-1.15.71-2.47,1.2-3.86,1.43-1.39.23-2.82.19-4.19-.12s-2.65-.86-3.75-1.64c-1.1-.78-1.99-1.75-2.62-2.86-.63-1.11-.97-2.32-1.01-3.56-.04-1.24.22-2.46.78-3.6.55-1.14,1.38-2.16,2.43-2.99l1.55,1.5c-.8.63-1.43,1.41-1.85,2.28-.42.87-.63,1.81-.59,2.75.03.94.3,1.87.77,2.72.48.85,1.16,1.59,2,2.18.84.59,1.82,1.02,2.86,1.25,1.05.23,2.14.26,3.2.09,1.06-.17,2.07-.54,2.95-1.09.88-.54,1.62-1.25,2.16-2.07l2,1.01ZM9.86,11.37l3.03-3.03,1.35,1.35c.21.21.21.55,0,.76l-2.27,2.27c-.21.21-.55.21-.76,0l-1.35-1.35Z" - ], - "d-notice-board": [ - 24, - "M.97,16.66c-.19,0-.38.08-.52.22-.14.14-.22.32-.22.52s.08.38.22.52c.14.14.32.22.52.22h4.21l-1.24,4.97c-.04.19,0,.38.09.55.1.16.26.28.45.33.19.05.38.02.55-.08.17-.1.29-.25.34-.44l.6-2.38h12.09l.6,2.38c.05.19.17.34.34.44.17.1.36.13.55.08.19-.05.35-.16.45-.33.1-.16.13-.36.09-.55l-1.24-4.97h4.21c.19,0,.38-.08.52-.22s.22-.32.22-.52-.08-.38-.22-.52-.32-.22-.52-.22H.97ZM6.32,19.61l.37-1.47h10.62l.37,1.47H6.32Z", - true, - null, - "M12.66.41c-.06-.12-.15-.22-.27-.3-.12-.07-.25-.11-.39-.11s-.27.04-.39.11c-.12.07-.21.17-.27.3l-.53,1.06H3.91c-.58,0-1.15.23-1.56.65s-.65.97-.65,1.56v11.03h20.59V3.68c0-.58-.23-1.15-.65-1.56-.41-.41-.97-.65-1.56-.65h-6.9l-.53-1.06Z" - ], - "d-hospital": [ - 24, - "M12.7,10.42h1.15v1.41h-1.15v1.15h-1.41v-1.15h-1.15v-1.41h1.15v-1.15h1.41v1.15ZM6.24,10.74v10.61c0,.29-.24.53-.53.53H1.03c-.29,0-.53-.24-.53-.53v-10.61c0-.29.24-.53.53-.53h4.68c.29,0,.53.24.53.53ZM4.96,14.98c0-.29-.24-.53-.53-.53h-2.12c-.29,0-.53.24-.53.53v2.12c0,.29.24.53.53.53h2.12c.29,0,.53-.24.53-.53v-2.12ZM23.5,10.74v10.61c0,.29-.24.53-.53.53h-4.68c-.29,0-.53-.24-.53-.53v-10.61c0-.29.24-.53.53-.53h4.68c.29,0,.53.24.53.53ZM22.22,14.98c0-.29-.24-.53-.53-.53h-2.12c-.29,0-.53.24-.53.53v2.12c0,.29.24.53.53.53h2.12c.29,0,.53-.24.53-.53v-2.12Z", - true, - null, - "M7.3,6.9v14.45c0,.29.24.53.53.53h1.5c.29,0,.53-.24.53-.53v-4.88h4.28v4.88c0,.29.24.53.53.53h1.5c.29,0,.53-.24.53-.53v-11.5s0-2.94,0-2.94c0-.29-.24-.53-.53-.53H7.83c-.29,0-.53.24-.53.53ZM12.02,13.94c-1.54,0-2.82-1.24-2.82-2.82s1.24-2.82,2.82-2.82,2.82,1.24,2.82,2.82-1.28,2.82-2.82,2.82ZM17.3,5.31H6.74c-.31,0-.56-.25-.56-.56v-2.07c0-.31.25-.56.56-.56h10.56c.31,0,.56.25.56.56v2.07c0,.31-.25.56-.56.56Z" - ] -} \ No newline at end of file + "d-people": [ + 24, + "M14.6,10.9c.7.7,1.66,1.1,2.65,1.1s1.95-.4,2.65-1.1c.7-.7,1.1-1.66,1.1-2.65s-.4-1.95-1.1-2.65c-.7-.7-1.66-1.1-2.65-1.1s-1.95.4-2.65,1.1c-.7.7-1.1,1.66-1.1,2.65s.4,1.95,1.1,2.65ZM16.5,19.5c0,.52-.1,1.03-.32,1.5h6.32s1.5,0,1.5-1.5-1.5-6-7.5-6c-.98-.01-1.96.13-2.9.42,1.88,1.45,2.9,3.55,2.9,5.58Z", + true, + null, + "M13.5,21s1.5,0,1.5-1.5-1.5-6-7.5-6S0,18,0,19.5s1.5,1.5,1.5,1.5h12ZM7.5,12c-1.19,0-2.34-.47-3.18-1.32-.84-.84-1.32-1.99-1.32-3.18s.47-2.34,1.32-3.18c.84-.84,1.99-1.32,3.18-1.32s2.34.47,3.18,1.32c.84.84,1.32,1.99,1.32,3.18s-.47,2.34-1.32,3.18c-.84.84-1.99,1.32-3.18,1.32Z" + ], + "d-bell": [ + 24, + "M13.62,22.62c-.56.56-1.33.88-2.12.88s-1.56-.32-2.12-.88c-.56-.56-.88-1.33-.88-2.12h6c0,.8-.32,1.56-.88,2.12Z", + true, + null, + "M12.99,1.65c.02-.21,0-.42-.07-.62-.07-.2-.17-.38-.31-.54-.14-.16-.31-.28-.5-.36-.19-.09-.4-.13-.61-.13s-.42.04-.61.13c-.19.09-.36.21-.5.36-.14.16-.25.34-.31.54-.07.2-.09.41-.07.62-1.7.34-3.22,1.26-4.32,2.6-1.09,1.34-1.69,3.02-1.69,4.75,0,1.65-.75,9-3,10.5h21c-2.25-1.5-3-8.85-3-10.5,0-3.63-2.58-6.66-6.01-7.35Z" + ], + "d-book-open": [ + 24, + "M11.75,3.02c1.57-.95,2.95-1.46,4.45-1.73,1.55-.27,3.12-.29,4.7-.29.56,0,.84,0,1.06.11.19.1.34.25.44.44.11.21.11.5.11,1.06v8.96c0,1.59,0,2.39-.29,3-.27.57-.63.97-1.18,1.29-.58.35-1.5.43-3.33.6-.42.04-.83.09-1.24.16-1.73.3-3.25,1.09-4.71,2.03V3.02ZM2.75,18.51c-.41,0-.75.34-.75.75s.34.75.75.75c1.97,0,3.4.12,4.68.47,1.27.35,2.45.93,3.91,1.9.25.17.58.17.83,0,1.46-.97,2.63-1.55,3.91-1.9,1.28-.35,2.7-.47,4.68-.47.41,0,.75-.34.75-.75s-.34-.75-.75-.75c-2.03,0-3.6.13-5.07.53-1.34.37-2.56.95-3.93,1.83-1.37-.88-2.59-1.46-3.93-1.83-1.47-.4-3.05-.53-5.07-.53Z", + true, + null, + "M11.75,3.02c-1.57-.95-2.95-1.46-4.45-1.73-1.55-.27-3.12-.29-4.7-.29-.56,0-.84,0-1.06.11-.19.1-.34.25-.44.44-.11.21-.11.5-.11,1.06v8.96c0,1.59,0,2.39.29,3,.27.57.63.97,1.18,1.29.58.35,1.5.43,3.33.6.42.04.83.09,1.24.16,1.73.3,3.25,1.09,4.71,2.03V3.02Z" + ], + "d-patient": [ + 24, + "M12.5,9.66c2.67,0,4.83-2.16,4.83-4.83S15.17,0,12.5,0s-4.83,2.16-4.83,4.83,2.16,4.83,4.83,4.83Z", + true, + null, + "M19.48,12.64c-.26-.26-.55-.5-.86-.69-.26-.17-.53-.31-.82-.43l-1.61,11.62h-4.15l4.07-12.01c-.1,0-.2,0-.31,0h-6.61c-1.39,0-2.69.54-3.67,1.52-.98.98-1.52,2.29-1.52,3.67v4.51c0,1.27,1.04,2.31,2.31,2.31h4.82l-.1.29c-.05.13-.02.28.06.39.08.11.21.18.35.18h5.13c.22,0,.4-.16.43-.37l.07-.49v-.06c1.04-.23,1.81-1.15,1.81-2.25,0-.86-.47-1.63-1.21-2.03l.12-.9c1.18.49,1.95,1.64,1.95,2.93,0,.91-.38,1.73-1,2.31h2.25v-6.82c0-1.39-.54-2.69-1.52-3.67h0ZM7.67,18.52c-.24,0-.43-.19-.43-.43v-1.77c0-.24.19-.43.43-.43s.43.19.43.43v1.34h4.89l-.29.87h-5.02Z" + ], + "d-calendar": [ + 24, + "M7,2c.55,0,1,.45,1,1v1h7v-1c0-.55.45-1,1-1s1,.45,1,1v1h2.5c1.38,0,2.5,1.12,2.5,2.5v2.5H1v-2.5c0-1.38,1.12-2.5,2.5-2.5h2.5v-1c0-.55.45-1,1-1ZM5,13c-.55,0-1,.45-1,1s.45,1,1,1h.01c.55,0,1-.45,1-1s-.45-1-1-1h-.01ZM5,17c-.55,0-1,.45-1,1s.45,1,1,1h.01c.55,0,1-.45,1-1s-.45-1-1-1h-.01ZM9,14c0-.55.45-1,1-1h.01c.55,0,1,.45,1,1s-.45,1-1,1h-.01c-.55,0-1-.45-1-1ZM10,17c-.55,0-1,.45-1,1s.45,1,1,1h.01c.55,0,1-.45,1-1s-.45-1-1-1h-.01ZM14,14c0-.55.45-1,1-1h.01c.55,0,1,.45,1,1s-.45,1-1,1h-.01c-.55,0-1-.45-1-1Z", + true, + null, + "M1,20v-11h21v11c0,1.66-1.34,3-3,3H4c-1.66,0-3-1.34-3-3Z" + ], + "d-folder": [ + 24, + "M2,10v-5c0-1.66,1.34-3,3-3h4.31c.62,0,1.2.29,1.58.78l1.81,2.34c.19.24.48.39.79.39h6.51c1.1,0,2,.9,2,2v2.5c0,1.1-.9,2-2,2H4c-1.1,0-2-.9-2-2Z", + true, + null, + "M2.24,19.04l-.2-14c-.02-1.67,1.33-3.04,3-3.04h4.23c.61,0,1.19.28,1.57.76l1.88,2.38c.18.22.44.36.73.38l6.46.37c1.05.06,1.87.92,1.89,1.97l.16,11.1c.02,1.67-1.33,3.04-3,3.04H5.24c-1.64,0-2.98-1.32-3-2.96Z" + ], + "d-ambulance": [ + 24, + "M15.44,7.06c0-.25.1-.49.28-.66.18-.18.42-.28.66-.28s.49.1.66.28c.18.18.28.42.28.66v.95h-1.89v-.95ZM19.41,9.05l1.29,2.53,1.91,1.02c.32.17.59.44.79.75.18.31.3.68.3,1.05v.23h0c.08,0,.16.03.23.08.06.06.08.14.08.23v1.47c0,.08-.03.16-.1.23-.06.06-.14.08-.23.08h0v.04c0,.07-.01.14-.04.21s-.07.13-.13.18-.11.1-.18.13-.14.04-.21.04h-2.22c-.01-.66-.3-1.3-.78-1.77s-1.12-.72-1.78-.72-1.31.25-1.78.72c-.48.47-.76,1.1-.78,1.77h-1.26v-8.96h3.73c.24,0,.47.07.66.18.2.13.37.3.47.51h.03ZM15.75,13.09h1.24s.11-.03.14-.06c.04-.04.06-.08.06-.14s-.03-.11-.06-.14c-.04-.04-.08-.06-.14-.06h-1.24s-.11.03-.14.06c-.04.04-.06.08-.06.14s.03.11.06.14c.04.04.08.06.14.06ZM15.54,9.25v2.83h4.31l-1.31-2.47c-.06-.11-.14-.2-.24-.25s-.23-.1-.34-.1h-2.42ZM5.31,15.38c-1.12,0-2.03.91-2.03,2.03s.91,2.03,2.03,2.03,2.03-.91,2.03-2.03-.91-2.03-2.03-2.03ZM5.31,18.23c-.45,0-.82-.37-.82-.82s.37-.82.82-.82.82.37.82.82-.37.82-.82.82ZM18.39,15.38c-1.12,0-2.03.91-2.03,2.03s.91,2.03,2.03,2.03,2.03-.91,2.03-2.03-.91-2.03-2.03-2.03ZM18.39,18.23c-.45,0-.82-.37-.82-.82s.37-.82.82-.82.82.37.82.82-.37.82-.82.82Z", + true, + null, + "M.34,14.62V5.91c0-.1.01-.2.06-.28s.1-.17.17-.24.16-.13.24-.17.18-.06.28-.06h2.09c0-.16.07-.3.17-.41.11-.11.25-.17.41-.17h6.36c.16,0,.3.06.41.17s.17.25.17.41h2.5c.2,0,.4.08.54.23s.23.34.23.54v11.4h-6.09c-.01-.66-.3-1.3-.78-1.77s-1.12-.72-1.78-.72-1.31.25-1.78.72c-.48.47-.76,1.1-.78,1.77h-1.67c-.17,0-.34-.06-.48-.17s-.23-.25-.27-.42h-.03c-.08,0-.16-.03-.23-.08-.06-.06-.08-.14-.08-.23v-1.47c0-.08.03-.16.08-.23.06-.06.23-.08.23-.08l.03-.03ZM5.27,11.4h1.33v1.33h1.45v-1.33h1.33v-1.45h-1.33v-1.33h-1.45v1.33h-1.33v1.45Z" + ], + "d-microscope": [ + 24, + "M2.9,5.43c-.21-.21-.21-.55,0-.76l3.29-3.29c.21-.21.55-.21.76,0l6.07,6.07c.21.21.21.55,0,.76l-3.29,3.29c-.21.21-.55.21-.76,0L2.9,5.43ZM4.97,22.33c0-.3.24-.54.54-.54h10.55c.3,0,.54.24.54.54v1.13c0,.3-.24.54-.54.54H5.5c-.3,0-.54-.24-.54-.54v-1.13ZM15.29,15.68c-.3,0-.54.24-.54.54v.76c0,.3.24.54.54.54h6.88c.3,0,.54-.24.54-.54v-.76c0-.3-.24-.54-.54-.54h-6.88Z", + true, + null, + "M1.67,2.43c-.21.21-.21.55,0,.76l1.35,1.35,3.03-3.03L4.7.16c-.21-.21-.55-.21-.76,0L1.67,2.43ZM19.55,17.52c-.71,1.07-1.67,1.99-2.82,2.71-1.15.71-2.47,1.2-3.86,1.43-1.39.23-2.82.19-4.19-.12s-2.65-.86-3.75-1.64c-1.1-.78-1.99-1.75-2.62-2.86-.63-1.11-.97-2.32-1.01-3.56-.04-1.24.22-2.46.78-3.6.55-1.14,1.38-2.16,2.43-2.99l1.55,1.5c-.8.63-1.43,1.41-1.85,2.28-.42.87-.63,1.81-.59,2.75.03.94.3,1.87.77,2.72.48.85,1.16,1.59,2,2.18.84.59,1.82,1.02,2.86,1.25,1.05.23,2.14.26,3.2.09,1.06-.17,2.07-.54,2.95-1.09.88-.54,1.62-1.25,2.16-2.07l2,1.01ZM9.86,11.37l3.03-3.03,1.35,1.35c.21.21.21.55,0,.76l-2.27,2.27c-.21.21-.55.21-.76,0l-1.35-1.35Z" + ], + "d-notice-board": [ + 24, + "M.97,16.66c-.19,0-.38.08-.52.22-.14.14-.22.32-.22.52s.08.38.22.52c.14.14.32.22.52.22h4.21l-1.24,4.97c-.04.19,0,.38.09.55.1.16.26.28.45.33.19.05.38.02.55-.08.17-.1.29-.25.34-.44l.6-2.38h12.09l.6,2.38c.05.19.17.34.34.44.17.1.36.13.55.08.19-.05.35-.16.45-.33.1-.16.13-.36.09-.55l-1.24-4.97h4.21c.19,0,.38-.08.52-.22s.22-.32.22-.52-.08-.38-.22-.52-.32-.22-.52-.22H.97ZM6.32,19.61l.37-1.47h10.62l.37,1.47H6.32Z", + true, + null, + "M12.66.41c-.06-.12-.15-.22-.27-.3-.12-.07-.25-.11-.39-.11s-.27.04-.39.11c-.12.07-.21.17-.27.3l-.53,1.06H3.91c-.58,0-1.15.23-1.56.65s-.65.97-.65,1.56v11.03h20.59V3.68c0-.58-.23-1.15-.65-1.56-.41-.41-.97-.65-1.56-.65h-6.9l-.53-1.06Z" + ], + "d-hospital": [ + 24, + "M12.7,10.42h1.15v1.41h-1.15v1.15h-1.41v-1.15h-1.15v-1.41h1.15v-1.15h1.41v1.15ZM6.24,10.74v10.61c0,.29-.24.53-.53.53H1.03c-.29,0-.53-.24-.53-.53v-10.61c0-.29.24-.53.53-.53h4.68c.29,0,.53.24.53.53ZM4.96,14.98c0-.29-.24-.53-.53-.53h-2.12c-.29,0-.53.24-.53.53v2.12c0,.29.24.53.53.53h2.12c.29,0,.53-.24.53-.53v-2.12ZM23.5,10.74v10.61c0,.29-.24.53-.53.53h-4.68c-.29,0-.53-.24-.53-.53v-10.61c0-.29.24-.53.53-.53h4.68c.29,0,.53.24.53.53ZM22.22,14.98c0-.29-.24-.53-.53-.53h-2.12c-.29,0-.53.24-.53.53v2.12c0,.29.24.53.53.53h2.12c.29,0,.53-.24.53-.53v-2.12Z", + true, + null, + "M7.3,6.9v14.45c0,.29.24.53.53.53h1.5c.29,0,.53-.24.53-.53v-4.88h4.28v4.88c0,.29.24.53.53.53h1.5c.29,0,.53-.24.53-.53v-11.5s0-2.94,0-2.94c0-.29-.24-.53-.53-.53H7.83c-.29,0-.53.24-.53.53ZM12.02,13.94c-1.54,0-2.82-1.24-2.82-2.82s1.24-2.82,2.82-2.82,2.82,1.24,2.82,2.82-1.28,2.82-2.82,2.82ZM17.3,5.31H6.74c-.31,0-.56-.25-.56-.56v-2.07c0-.31.25-.56.56-.56h10.56c.31,0,.56.25.56.56v2.07c0,.31-.25.56-.56.56Z" + ] +} diff --git a/src/CAREUI/icons/UniconPaths.json b/src/CAREUI/icons/UniconPaths.json index e498edd9fc4..58abe9054ab 100644 --- a/src/CAREUI/icons/UniconPaths.json +++ b/src/CAREUI/icons/UniconPaths.json @@ -3119,10 +3119,7 @@ 24, "M19,2H5A3,3,0,0,0,2,5V19a3,3,0,0,0,3,3H19a3,3,0,0,0,3-3V5A3,3,0,0,0,19,2Zm1,17a1,1,0,0,1-1,1H5a1,1,0,0,1-1-1V5A1,1,0,0,1,5,4H19a1,1,0,0,1,1,1Zm-4-8H8a1,1,0,0,0,0,2h8a1,1,0,0,0,0-2Z" ], - "l-minus": [ - 24, - "M19,11H5a1,1,0,0,0,0,2H19a1,1,0,0,0,0-2Z" - ], + "l-minus": [24, "M19,11H5a1,1,0,0,0,0,2H19a1,1,0,0,0,0-2Z"], "l-missed-call": [ 24, "M6,7.49a1,1,0,0,0,1-1V5.9L9.88,8.78a3,3,0,0,0,4.24,0l4.59-4.59a1,1,0,0,0,0-1.41,1,1,0,0,0-1.42,0L12.71,7.36a1,1,0,0,1-1.42,0L8.41,4.49H9a1,1,0,0,0,0-2H6a1,1,0,0,0-.92.61A1.09,1.09,0,0,0,5,3.49v3A1,1,0,0,0,6,7.49Zm15.94,7.36a16.27,16.27,0,0,0-19.88,0,2.69,2.69,0,0,0-1,2,2.66,2.66,0,0,0,.78,2.07L3.6,20.72A2.68,2.68,0,0,0,7.06,21l.47-.32a8.13,8.13,0,0,1,1-.55,1.85,1.85,0,0,0,1-2.3l-.09-.24a10.49,10.49,0,0,1,5.22,0l-.09.24a1.85,1.85,0,0,0,1,2.3,8.13,8.13,0,0,1,1,.55l.47.32a2.58,2.58,0,0,0,1.54.5,2.72,2.72,0,0,0,1.92-.79l1.81-1.82A2.66,2.66,0,0,0,23,16.83,2.69,2.69,0,0,0,21.94,14.85ZM20.8,17.49,19,19.3a.68.68,0,0,1-.86.1c-.19-.14-.38-.27-.59-.4a11.65,11.65,0,0,0-1.09-.61l.4-1.09a1,1,0,0,0-.6-1.28,12.42,12.42,0,0,0-8.5,0,1,1,0,0,0-.6,1.28l.4,1.1a9.8,9.8,0,0,0-1.1.6l-.58.4A.66.66,0,0,1,5,19.3L3.2,17.49A.67.67,0,0,1,3,17a.76.76,0,0,1,.28-.53,14.29,14.29,0,0,1,17.44,0A.76.76,0,0,1,21,17,.67.67,0,0,1,20.8,17.49Z" @@ -4307,10 +4304,7 @@ 24, "M15,13H9a1,1,0,0,0,0,2h2v2a1,1,0,0,0,2,0V15h2a1,1,0,0,0,0-2Zm2-7H7A1,1,0,0,0,7,8h4v2a1,1,0,0,0,2,0V8h4a1,1,0,0,0,0-2Z" ], - "l-text": [ - 24, - "M17,6H7A1,1,0,0,0,7,8h4v9a1,1,0,0,0,2,0V8h4a1,1,0,0,0,0-2Z" - ], + "l-text": [24, "M17,6H7A1,1,0,0,0,7,8h4v9a1,1,0,0,0,2,0V8h4a1,1,0,0,0,0-2Z"], "l-th-large": [ 24, "M20,3H4A1,1,0,0,0,3,4V20a1,1,0,0,0,1,1H20a1,1,0,0,0,1-1V4A1,1,0,0,0,20,3ZM11,19H5V13h6Zm0-8H5V5h6Zm8,8H13V13h6Zm0-8H13V5h6Z" @@ -4860,4 +4854,4 @@ null, "M6.5 3C6.5 2.73478 6.60536 2.48043 6.79289 2.29289C6.98043 2.10536 7.23478 2 7.5 2H8.5C8.76522 2 9.01957 2.10536 9.20711 2.29289C9.39464 2.48043 9.5 2.73478 9.5 3V6C9.5 6.26522 9.39464 6.51957 9.20711 6.70711C9.01957 6.89464 8.76522 7 8.5 7H7.5C7.23478 7 6.98043 6.89464 6.79289 6.70711C6.60536 6.51957 6.5 6.26522 6.5 6V3ZM2.5 3C2.5 2.73478 2.60536 2.48043 2.79289 2.29289C2.98043 2.10536 3.23478 2 3.5 2H4.5C4.76522 2 5.01957 2.10536 5.20711 2.29289C5.39464 2.48043 5.5 2.73478 5.5 3V10C5.5 10.2652 5.39464 10.5196 5.20711 10.7071C5.01957 10.8946 4.76522 11 4.5 11H3.5C3.23478 11 2.98043 10.8946 2.79289 10.7071C2.60536 10.5196 2.5 10.2652 2.5 10V3ZM10.5 3C10.5 2.73478 10.6054 2.48043 10.7929 2.29289C10.9804 2.10536 11.2348 2 11.5 2H12.5C12.7652 2 13.0196 2.10536 13.2071 2.29289C13.3946 2.48043 13.5 2.73478 13.5 3V13C13.5 13.2652 13.3946 13.5196 13.2071 13.7071C13.0196 13.8946 12.7652 14 12.5 14H11.5C11.2348 14 10.9804 13.8946 10.7929 13.7071C10.6054 13.5196 10.5 13.2652 10.5 13V3Z" ] -} \ No newline at end of file +} diff --git a/src/Utils/request/README.md b/src/Utils/request/README.md index 9a508bcaf36..77b4e2f99e4 100644 --- a/src/Utils/request/README.md +++ b/src/Utils/request/README.md @@ -6,7 +6,7 @@ CARE now uses TanStack Query (formerly React Query) as its data fetching solutio For new API integrations, we recommend using TanStack Query with `query` utility function. This is a wrapper around `fetch` that works seamlessly with TanStack Query. It handles response parsing, error handling, setting headers, and more. -```tsx +````tsx import { useQuery } from "@tanstack/react-query"; import query from "@/Utils/request/query"; @@ -90,7 +90,7 @@ useQuery({ silent: true // Optional: suppress error notifications }) }); -``` +```` ### Debounced Queries @@ -99,18 +99,18 @@ For search inputs or other scenarios requiring debounced API calls, use `query.d ```tsx function SearchComponent() { const [search, setSearch] = useState(""); - + const { data } = useQuery({ - queryKey: ['search', search], + queryKey: ["search", search], queryFn: query.debounced(routes.search, { queryParams: { q: search }, - debounceInterval: 500 // Optional: defaults to 500ms + debounceInterval: 500, // Optional: defaults to 500ms }), - enabled: search.length > 0 + enabled: search.length > 0, }); return ( - setSearch(e.target.value)} placeholder="Search..." @@ -127,7 +127,7 @@ All API errors are now handled globally. Common scenarios like: - Session expiry -> Redirects to /session-expired - Bad requests (400/406) -> Shows error notification -are automatically handled. + are automatically handled. Use the `silent: true` option to suppress error notifications for specific queries. @@ -137,6 +137,7 @@ For data mutations, we provide a `mutate` utility that works seamlessly with Tan ```tsx import { useMutation } from "@tanstack/react-query"; + import mutate from "@/Utils/request/mutate"; function CreatePrescription({ consultationId }: { consultationId: string }) { @@ -150,8 +151,10 @@ function CreatePrescription({ consultationId }: { consultationId: string }) { }); return ( - + + + + + + + + {t("reschedule_appointment")} + + +
+ + +
+ + +
+
+
+
+ {currentStatus === "booked" && ( <> - ); - } - - const { booked_slots, total_slots } = availability; - const bookedPercentage = booked_slots / total_slots; - const tokensLeft = total_slots - booked_slots; - const isFullyBooked = tokensLeft <= 0; - - return ( - - ); - }; - const handleSubmit = async () => { if (!resourceId) { toast.error("Please select a practitioner"); @@ -268,103 +151,12 @@ export default function BookAppointment(props: Props) { !resourceId && "opacity-50 pointer-events-none", )} > -
- { - setSelectedMonth(month); - setSelectedSlotId(undefined); - }} - renderDay={renderDay} - className="mb-6" - highlightToday={false} - /> -
- -
-
-

{t("available_time_slots")}

-
- -
- {slotsQuery.data == null && ( -
-

- {t("to_view_available_slots_select_resource_and_date")} -

-
- )} - {slotsQuery.data?.results.length === 0 && ( -
-

- {t("no_slots_available_for_this_date")} -

-
- )} - {!!slotsQuery.data?.results.length && - groupSlotsByAvailability(slotsQuery.data.results).map( - ({ availability, slots }) => ( -
-

- {availability.name} -

-
- {slots.map((slot) => { - const percentage = - slot.allocated / availability.tokens_per_slot; - - return ( - - ); - })} -
- -
- ), - )} -
-
-
+
diff --git a/src/pages/Appointments/components/AppointmentSlotPicker.tsx b/src/pages/Appointments/components/AppointmentSlotPicker.tsx new file mode 100644 index 00000000000..c73bdd422b8 --- /dev/null +++ b/src/pages/Appointments/components/AppointmentSlotPicker.tsx @@ -0,0 +1,242 @@ +import { useQuery } from "@tanstack/react-query"; +import { format, isBefore, isSameDay, startOfToday } from "date-fns"; +import { useState } from "react"; +import { useTranslation } from "react-i18next"; + +import { cn } from "@/lib/utils"; + +import Calendar from "@/CAREUI/interactive/Calendar"; + +import { Button } from "@/components/ui/button"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { Separator } from "@/components/ui/separator"; + +import query from "@/Utils/request/query"; +import { dateQueryString } from "@/Utils/utils"; +import { + groupSlotsByAvailability, + useAvailabilityHeatmap, +} from "@/pages/Appointments/utils"; +import scheduleApis from "@/types/scheduling/scheduleApis"; + +interface AppointmentSlotPickerProps { + facilityId: string; + resourceId?: string; + onSlotSelect: (slotId: string | undefined) => void; + selectedSlotId?: string; +} + +export function AppointmentSlotPicker({ + facilityId, + resourceId, + onSlotSelect, + selectedSlotId, +}: AppointmentSlotPickerProps) { + const { t } = useTranslation(); + const [selectedMonth, setSelectedMonth] = useState(new Date()); + const [selectedDate, setSelectedDate] = useState(new Date()); + + const heatmapQuery = useAvailabilityHeatmap({ + facilityId, + userId: resourceId, + month: selectedMonth, + }); + + const slotsQuery = useQuery({ + queryKey: ["slots", facilityId, resourceId, dateQueryString(selectedDate)], + queryFn: query(scheduleApis.slots.getSlotsForDay, { + pathParams: { facility_id: facilityId }, + body: { + user: resourceId ?? "", + day: dateQueryString(selectedDate), + }, + }), + enabled: !!resourceId && !!selectedDate, + }); + + const renderDay = (date: Date) => { + const isSelected = isSameDay(date, selectedDate); + const isBeforeToday = isBefore(date, startOfToday()); + const availability = heatmapQuery.data?.[dateQueryString(date)]; + + if ( + heatmapQuery.isFetching || + !availability || + availability.total_slots === 0 || + isBeforeToday + ) { + return ( + + ); + } + + const { booked_slots, total_slots } = availability; + const bookedPercentage = booked_slots / total_slots; + const tokensLeft = total_slots - booked_slots; + const isFullyBooked = tokensLeft <= 0; + + return ( + + ); + }; + + return ( + <> +
+ { + setSelectedMonth(month); + onSlotSelect(undefined); + }} + renderDay={renderDay} + className="mb-6" + highlightToday={false} + /> +
+ +
+
+

{t("available_time_slots")}

+
+ +
+ {slotsQuery.data == null && ( +
+

+ {t("to_view_available_slots_select_resource_and_date")} +

+
+ )} + {slotsQuery.data?.results.length === 0 && ( +
+

+ {t("no_slots_available_for_this_date")} +

+
+ )} + {!!slotsQuery.data?.results.length && + groupSlotsByAvailability(slotsQuery.data.results).map( + ({ availability, slots }) => ( +
+

+ {availability.name} +

+
+ {slots.map((slot) => { + const percentage = + slot.allocated / availability.tokens_per_slot; + const isPastSlot = + isSameDay(selectedDate, new Date()) && + isBefore(slot.start_datetime, new Date()); + + return ( + + ); + })} +
+ +
+ ), + )} +
+
+
+ + ); +} diff --git a/src/pages/Patient/components/AppointmentDialog.tsx b/src/pages/Patient/components/AppointmentDialog.tsx index 0457074cf20..f9923f7181f 100644 --- a/src/pages/Patient/components/AppointmentDialog.tsx +++ b/src/pages/Patient/components/AppointmentDialog.tsx @@ -1,6 +1,7 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; import { Dispatch, SetStateAction } from "react"; import { useTranslation } from "react-i18next"; +import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { @@ -18,7 +19,10 @@ import mutate from "@/Utils/request/mutate"; import { formatName, formatPatientAge } from "@/Utils/utils"; import { formatAppointmentSlotTime } from "@/pages/Appointments/utils"; import PublicAppointmentApi from "@/types/scheduling/PublicAppointmentApi"; -import { Appointment } from "@/types/scheduling/schedule"; +import { + Appointment, + AppointmentFinalStatuses, +} from "@/types/scheduling/schedule"; function AppointmentDialog({ appointment, @@ -45,6 +49,7 @@ function AppointmentDialog({ queryClient.invalidateQueries({ queryKey: ["appointment", tokenData?.phoneNumber], }); + toast.success(t("appointment_cancelled")); setAppointmentDialogOpen(false); }, }); @@ -84,24 +89,25 @@ function AppointmentDialog({ {t(appointment.status)} - - - {/* TODO: wire this */} - {/* */} - + {!AppointmentFinalStatuses.includes(appointment.status) && ( + + + + + )} diff --git a/src/types/facility/facility.ts b/src/types/facility/facility.ts index 33157fd50e5..bd0374c0bd4 100644 --- a/src/types/facility/facility.ts +++ b/src/types/facility/facility.ts @@ -1,5 +1,10 @@ import { Organization } from "@/types/organization/organization"; +export interface FacilityBareMinimum { + id: string; + name: string; +} + export interface BaseFacility { id: string; name: string; diff --git a/src/types/scheduling/schedule.ts b/src/types/scheduling/schedule.ts index 5608749f1e4..62fe2793a3c 100644 --- a/src/types/scheduling/schedule.ts +++ b/src/types/scheduling/schedule.ts @@ -2,6 +2,7 @@ import { DayOfWeek } from "@/CAREUI/interactive/WeekdayCheckbox"; import { Time } from "@/Utils/types"; import { AppointmentPatient } from "@/pages/Patient/Utils"; +import { FacilityBareMinimum } from "@/types/facility/facility"; import { UserBase } from "@/types/user/user"; export type ScheduleSlotType = "appointment" | "open" | "closed"; @@ -113,6 +114,7 @@ export const AppointmentNonCancelledStatuses = [ export const AppointmentCancelledStatuses = [ "cancelled", "entered_in_error", + "rescheduled", ] as const; export const AppointmentStatuses = [ @@ -120,6 +122,13 @@ export const AppointmentStatuses = [ ...AppointmentCancelledStatuses, ] as const; +export const AppointmentFinalStatuses: AppointmentStatus[] = [ + "fulfilled", + "cancelled", + "entered_in_error", + "rescheduled", +]; + export type AppointmentNonCancelledStatus = (typeof AppointmentNonCancelledStatuses)[number]; @@ -133,10 +142,11 @@ export interface Appointment { token_slot: TokenSlot; patient: AppointmentPatient; booked_on: string; - status: AppointmentStatus; + status: AppointmentNonCancelledStatus; reason_for_visit: string; user: UserBase; booked_by: UserBase | null; // This is null if the appointment was booked by the patient itself. + facility: FacilityBareMinimum; } export interface AppointmentCreateRequest { diff --git a/src/types/scheduling/scheduleApis.ts b/src/types/scheduling/scheduleApis.ts index e24c73ea2e0..bf768663c8d 100644 --- a/src/types/scheduling/scheduleApis.ts +++ b/src/types/scheduling/scheduleApis.ts @@ -143,6 +143,12 @@ export default { TBody: Type<{ reason: "cancelled" | "entered_in_error" }>(), TRes: Type(), }, + reschedule: { + path: "/api/v1/facility/{facility_id}/appointments/{id}/reschedule/", + method: HttpMethod.POST, + TBody: Type<{ new_slot: string }>(), + TRes: Type(), + }, /** * Lists schedulable users for a facility */ diff --git a/vite.config.mts b/vite.config.mts index 2cadc9f2e8b..40559689744 100644 --- a/vite.config.mts +++ b/vite.config.mts @@ -164,7 +164,6 @@ export default defineConfig(({ mode }) => { __CUSTOM_DESCRIPTION_HTML__: getDescriptionHtml( env.REACT_CUSTOM_DESCRIPTION || "", ), - __CORE_ENV__: { ...env }, }, plugins: [ federation({