From b02062a836df8559e19870f7c7268de4a2346032 Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Wed, 16 Oct 2024 15:53:11 +0530 Subject: [PATCH 1/9] Fixes multiple tiny issues (#8784) --- public/favicon-light.ico | Bin 217598 -> 0 bytes public/favicon.ico | Bin 217598 -> 6439 bytes src/App.tsx | 2 -- src/CAREUI/misc/PaginatedList.tsx | 10 ++++++- src/CAREUI/misc/ThemedFavicon.tsx | 14 ---------- src/Components/ABDM/LinkABHANumberModal.tsx | 1 - src/Components/Assets/AssetsList.tsx | 1 - src/Components/Common/Breadcrumbs.tsx | 9 +++--- src/Components/Common/Sidebar/Sidebar.tsx | 10 +++---- .../Common/Sidebar/SidebarUserCard.tsx | 8 +----- .../Facility/DischargedPatientsList.tsx | 26 +++++++++--------- src/Components/Facility/FacilityBlock.tsx | 6 ++-- src/Components/Facility/FacilityCard.tsx | 7 +---- src/Components/Facility/FacilityHome.tsx | 22 ++++++--------- .../Facility/LocationManagement.tsx | 22 +++++++-------- src/Components/Patient/ManagePatients.tsx | 9 +++--- .../Patient/PatientConsentRecordBlock.tsx | 5 +--- src/Components/Patient/PatientHome.tsx | 2 +- src/Components/Patient/PatientRegister.tsx | 6 ++-- src/Components/Users/ManageUsers.tsx | 6 ++-- src/Components/Users/SkillsSlideOver.tsx | 1 + src/Locale/en.json | 9 ++++-- src/Routers/AppRouter.tsx | 2 +- 23 files changed, 75 insertions(+), 103 deletions(-) delete mode 100644 public/favicon-light.ico delete mode 100644 src/CAREUI/misc/ThemedFavicon.tsx diff --git a/public/favicon-light.ico b/public/favicon-light.ico deleted file mode 100644 index 244b9d6c1d30aab5b36ffafc41845202059a07d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 217598 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 W+mE&7plRj;>^scKcsnF+4*vt$Z=fLn diff --git a/public/favicon.ico b/public/favicon.ico index 244b9d6c1d30aab5b36ffafc41845202059a07d8..67a5686e32ffe2212a032deb9ee098827e52f887 100644 GIT binary patch literal 6439 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 Apa1{> literal 217598 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 W+mE&7plRj;>^scKcsnF+4*vt$Z=fLn diff --git a/src/App.tsx b/src/App.tsx index 98cf307f18a..c02982fd6df 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,5 @@ import { Suspense } from "react"; import Routers from "./Routers"; -import ThemedFavicon from "./CAREUI/misc/ThemedFavicon"; import Integrations from "./Integrations"; import Loading from "./Components/Common/Loading"; import HistoryAPIProvider from "./Providers/HistoryAPIProvider"; @@ -11,7 +10,6 @@ import { Toaster } from "./Components/ui/toaster"; const App = () => { return ( }> - }> diff --git a/src/CAREUI/misc/PaginatedList.tsx b/src/CAREUI/misc/PaginatedList.tsx index ec270bf8134..3b68b23bd30 100644 --- a/src/CAREUI/misc/PaginatedList.tsx +++ b/src/CAREUI/misc/PaginatedList.tsx @@ -33,6 +33,8 @@ function useContextualized() { interface Props extends QueryOptions> { route: QueryRoute>; perPage?: number; + initialPage?: number; + onPageChange?: (page: number) => void; queryCB?: ( query: ReturnType>>, ) => void; @@ -49,7 +51,13 @@ export default function PaginatedList({ queryCB, ...queryOptions }: Props) { - const [currentPage, setPage] = useState(1); + const [currentPage, _setPage] = useState(queryOptions.initialPage ?? 1); + + const setPage = (page: number) => { + _setPage(page); + queryOptions.onPageChange?.(page); + }; + const query = useQuery(route, { ...queryOptions, query: { diff --git a/src/CAREUI/misc/ThemedFavicon.tsx b/src/CAREUI/misc/ThemedFavicon.tsx deleted file mode 100644 index b908f566b89..00000000000 --- a/src/CAREUI/misc/ThemedFavicon.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { useEffect } from "react"; - -export default function ThemedFavicon() { - useEffect(() => { - const darkThemeMq = window.matchMedia("(prefers-color-scheme: dark)"); - const favicon = document.querySelector( - "link[rel~='icon']", - ) as HTMLLinkElement; - - favicon.href = darkThemeMq.matches ? "/favicon-light.ico" : "/favicon.ico"; - }, []); - - return null; -} diff --git a/src/Components/ABDM/LinkABHANumberModal.tsx b/src/Components/ABDM/LinkABHANumberModal.tsx index 8d6365387cd..c2855ae7569 100644 --- a/src/Components/ABDM/LinkABHANumberModal.tsx +++ b/src/Components/ABDM/LinkABHANumberModal.tsx @@ -225,7 +225,6 @@ const ScanABHAQRSection = ({ Notify.Error({ msg: "Linking Failed" }); } } catch (e) { - console.log(e); Notify.Error({ msg: "Invalid ABHA QR" }); } finally { setIsLoading(false); diff --git a/src/Components/Assets/AssetsList.tsx b/src/Components/Assets/AssetsList.tsx index ee27c2a484f..77961d15b0d 100644 --- a/src/Components/Assets/AssetsList.tsx +++ b/src/Components/Assets/AssetsList.tsx @@ -159,7 +159,6 @@ const AssetsList = () => { }); } } catch (err) { - console.log(err); Notification.Error({ msg: t("invalid_asset_id_msg"), }); diff --git a/src/Components/Common/Breadcrumbs.tsx b/src/Components/Common/Breadcrumbs.tsx index c092ecbbc93..aaee7ac0b64 100644 --- a/src/Components/Common/Breadcrumbs.tsx +++ b/src/Components/Common/Breadcrumbs.tsx @@ -58,8 +58,8 @@ export default function Breadcrumbs({ style: replacements[field]?.style || "", })); - const renderCrumb = (crumb: any, index: number, array: any[]) => { - const isLastItem = index === array.length - 1; + const renderCrumb = (crumb: any, index: number) => { + const isLastItem = index === crumbs!.length - 1; return (
  • )} - {crumbs && - crumbs.length > 0 && - renderCrumb(crumbs[crumbs.length - 1], crumbs.length - 1, crumbs)} + {crumbs?.length && + renderCrumb(crumbs[crumbs.length - 1], crumbs.length - 1)} ); diff --git a/src/Components/Common/Sidebar/Sidebar.tsx b/src/Components/Common/Sidebar/Sidebar.tsx index 0e9ee34b715..31efe00f1b1 100644 --- a/src/Components/Common/Sidebar/Sidebar.tsx +++ b/src/Components/Common/Sidebar/Sidebar.tsx @@ -104,11 +104,11 @@ const StatelessSidebar = ({ : "overflow-y-auto overflow-x-hidden" }`} > - {shrinked && ( + {setShrinked && shrinked && (
    setShrinked && setShrinked(!shrinked)} + toggle={() => setShrinked(!shrinked)} />
    )} @@ -123,11 +123,11 @@ const StatelessSidebar = ({ src={shrinked ? LOGO_COLLAPSE : careConfig.mainLogo?.light} /> - {!shrinked && ( + {setShrinked && !shrinked && (
    setShrinked && setShrinked(!shrinked)} + toggle={() => setShrinked(!shrinked)} />
    )} @@ -220,7 +220,7 @@ interface ToggleShrinkProps { const ToggleShrink = ({ shrinked, toggle }: ToggleShrinkProps) => (
    = ({ shrinked }) => { id="sign-out-button" className={`flex h-full items-center justify-start transition-all duration-200 ease-in-out ${shrinked ? "pl-2" : "pl-5 pr-4"}`} > -
    - -
    - + {!shrinked && (
    {t("sign_out")} diff --git a/src/Components/Facility/DischargedPatientsList.tsx b/src/Components/Facility/DischargedPatientsList.tsx index 6603f3964af..47e5cd5a68d 100644 --- a/src/Components/Facility/DischargedPatientsList.tsx +++ b/src/Components/Facility/DischargedPatientsList.tsx @@ -47,15 +47,16 @@ const DischargedPatientsList = ({ pathParams: { id: facility_external_id }, }); - const { qParams, updateQuery, advancedFilter, FilterBadges } = useFilters({ - limit: 12, - cacheBlacklist: [ - "name", - "patient_no", - "phone_number", - "emergency_phone_number", - ], - }); + const { qParams, updateQuery, advancedFilter, FilterBadges, updatePage } = + useFilters({ + limit: 12, + cacheBlacklist: [ + "name", + "patient_no", + "phone_number", + "emergency_phone_number", + ], + }); useEffect(() => { if (!qParams.phone_number && phone_number.length >= 13) { @@ -434,10 +435,9 @@ const DischargedPatientsList = ({ route={routes.listFacilityDischargedPatients} pathParams={{ facility_external_id }} query={{ ordering: "-modified_date", ...qParams }} - queryCB={(query) => { - setCount(query.data?.count || 0); - console.log(query.data?.count); - }} + queryCB={(query) => setCount(query.data?.count || 0)} + initialPage={qParams.page} + onPageChange={updatePage} > {() => (
    diff --git a/src/Components/Facility/FacilityBlock.tsx b/src/Components/Facility/FacilityBlock.tsx index 64c0a24d78d..891bb4d4e59 100644 --- a/src/Components/Facility/FacilityBlock.tsx +++ b/src/Components/Facility/FacilityBlock.tsx @@ -1,6 +1,6 @@ import { Link } from "raviger"; -import CareIcon from "../../CAREUI/icons/CareIcon"; import { FacilityModel } from "./models"; +import { Avatar } from "@/Components/Common/Avatar"; export default function FacilityBlock(props: { facility: FacilityModel }) { const { facility } = props; @@ -18,9 +18,7 @@ export default function FacilityBlock(props: { facility: FacilityModel }) { src={facility.read_cover_image_url} /> ) : ( - <> - - + )}
    diff --git a/src/Components/Facility/FacilityCard.tsx b/src/Components/Facility/FacilityCard.tsx index 0febe36e4b7..f3614d2685a 100644 --- a/src/Components/Facility/FacilityCard.tsx +++ b/src/Components/Facility/FacilityCard.tsx @@ -61,12 +61,7 @@ export const FacilityCard = (props: { facility: any; userType: any }) => { alt={facility.name} className="h-full max-h-32 w-full object-cover" /> - )) || ( - - )} + )) || }
    diff --git a/src/Components/Facility/FacilityHome.tsx b/src/Components/Facility/FacilityHome.tsx index 7edbb939b8a..6f73fee4a54 100644 --- a/src/Components/Facility/FacilityHome.tsx +++ b/src/Components/Facility/FacilityHome.tsx @@ -43,6 +43,7 @@ type Props = { }; import Loading from "@/Components/Common/Loading"; +import { Avatar } from "@/Components/Common/Avatar.js"; export const getFacilityFeatureIcon = (featureId: number) => { const feature = FACILITY_FEATURE_TYPES.find((f) => f.id === featureId); if (!feature?.icon) return null; @@ -124,7 +125,7 @@ export const FacilityHome = ({ facilityId }: Props) => { onClick={() => setEditCoverImage(true)} > - {`${hasCoverImage ? "Edit" : "Upload"}`} + {t(hasCoverImage ? "edit" : "upload")}
    ); @@ -181,11 +182,7 @@ export const FacilityHome = ({ facilityId }: Props) => { hasPermissionToEditCoverImage && setEditCoverImage(true) } > -
    )} @@ -210,13 +207,7 @@ export const FacilityHome = ({ facilityId }: Props) => { ) : (
    - - - +
    )} {editCoverImageTooltip} @@ -291,7 +282,10 @@ export const FacilityHome = ({ facilityId }: Props) => {
    {spokesQuery.data?.results.map((spoke) => ( - + ))}
    diff --git a/src/Components/Facility/LocationManagement.tsx b/src/Components/Facility/LocationManagement.tsx index 1aaf57b7233..2223aa2e8fd 100644 --- a/src/Components/Facility/LocationManagement.tsx +++ b/src/Components/Facility/LocationManagement.tsx @@ -16,6 +16,7 @@ import useAuthUser from "../../Common/hooks/useAuthUser"; import useQuery from "../../Utils/request/useQuery"; import Loading from "@/Components/Common/Loading"; +import { cn } from "@/lib/utils"; interface Props { facilityId: string; } @@ -87,14 +88,14 @@ export default function LocationManagement({ facilityId }: Props) { id="add-new-location" href={`/facility/${facilityId}/location/add`} authorizeFor={NonReadOnlyUsers} - className="mr-4 hidden lg:block" + className="hidden lg:block" > Add New Location } > -
    +
    - className="my-8 grid gap-3 @4xl:grid-cols-2 @6xl:grid-cols-3 @[100rem]:grid-cols-4 lg:mx-8"> + className="my-8 grid gap-3 @4xl:grid-cols-2 @6xl:grid-cols-3 @[100rem]:grid-cols-4"> {(item) => ( { - const { loading, data } = useQuery(routes.listFacilityBeds, { + const bedsQuery = useQuery(routes.listFacilityBeds, { query: { facility: facilityId, location: id, }, }); - const totalBeds = data?.count ?? 0; - - if (loading) { - return ; - } + const totalBeds = bedsQuery.data?.count; return (
    @@ -290,13 +287,16 @@ const Location = ({ id="manage-bed-button" variant="secondary" border - className="mt-3 flex w-full items-center justify-between" + className={cn( + "mt-3 flex w-full items-center justify-between", + totalBeds != null && "opacity-50", + )} href={`location/${id}/beds`} > Manage Beds - {totalBeds} + {totalBeds ?? "--"}
    diff --git a/src/Components/Patient/ManagePatients.tsx b/src/Components/Patient/ManagePatients.tsx index 0be6fe6b819..46dad347dd5 100644 --- a/src/Components/Patient/ManagePatients.tsx +++ b/src/Components/Patient/ManagePatients.tsx @@ -471,7 +471,7 @@ export const PatientManager = () => { let patientList: ReactNode[] = []; if (data?.count) { - patientList = data.results.map((patient: any) => { + patientList = data.results.map((patient) => { let patientUrl = ""; if ( patient.last_consultation && @@ -506,7 +506,7 @@ export const PatientManager = () => {
    -
    +
    {patient?.last_consultation?.current_bed && patient?.last_consultation?.discharge_date === null ? (
    @@ -541,9 +541,10 @@ export const PatientManager = () => {
    ) : ( -
    +
    diff --git a/src/Components/Patient/PatientConsentRecordBlock.tsx b/src/Components/Patient/PatientConsentRecordBlock.tsx index 07931380cb6..b66a6cbd8aa 100644 --- a/src/Components/Patient/PatientConsentRecordBlock.tsx +++ b/src/Components/Patient/PatientConsentRecordBlock.tsx @@ -70,10 +70,7 @@ export default function PatientConsentRecordBlockGroup(props: { { - console.log(e.value); - setPatientCodeStatus(e.value); - }} + onChange={(e) => setPatientCodeStatus(e.value)} value={ CONSENT_PATIENT_CODE_STATUS_CHOICES.find( (c) => c.id === patientCodeStatus, diff --git a/src/Components/Patient/PatientHome.tsx b/src/Components/Patient/PatientHome.tsx index f6fe4f28a72..4b88df5bd20 100644 --- a/src/Components/Patient/PatientHome.tsx +++ b/src/Components/Patient/PatientHome.tsx @@ -253,7 +253,7 @@ export const PatientHome = (props: any) => { return ( {
    {field("nationality").value === "India" && ( -
    +
    {
    )} -
    +
    {
    -
    +

    Insurance Details diff --git a/src/Components/Users/ManageUsers.tsx b/src/Components/Users/ManageUsers.tsx index 2a00a2a8305..801ffae03af 100644 --- a/src/Components/Users/ManageUsers.tsx +++ b/src/Components/Users/ManageUsers.tsx @@ -415,7 +415,7 @@ export default function ManageUsers() { }} > -

    Linked Facilities

    +

    {t("linked_facilities")}

    -

    Linked Skills

    +

    {t("linked_skills")}

    {["DistrictAdmin", "StateAdmin"].includes( @@ -781,7 +781,7 @@ export function UserFacilities(props: { user: any }) { selected={facility} setSelected={setFacility} errors="" - className="z-40" + className="z-40 w-full" /> { selected={selectedSkill} setSelected={setSelectedSkill} errors="" + className="w-full" userSkills={skills?.results || []} /> -
    +
    {pages}
    From 45a39301cc938d042f1c568940a9a697abf52140 Mon Sep 17 00:00:00 2001 From: Gigin George Date: Wed, 16 Oct 2024 16:00:22 +0530 Subject: [PATCH 2/9] WIP: Care Plugin Support (#8660) Co-authored-by: Shivank Kacker --- .cursorrules | 23 + .env.docker | 2 + .example.env | 2 + .gitignore | 4 + .nvmrc | 1 + .prettierrc.json | 7 +- README.md | 19 +- care.config.ts | 7 + cypress/e2e/users_spec/UsersHomepage.cy.ts | 2 +- .../pageobject/Facility/FacilityCreation.ts | 2 +- package-lock.json | 1090 ++++++++--------- package.json | 21 +- scripts/setup-care-apps.js | 113 ++ src/App.tsx | 26 +- src/CAREUI/display/Timeline.tsx | 4 +- src/CAREUI/icons/CareIcon.tsx | 39 +- src/CAREUI/icons/icon.js | 49 - src/CAREUI/interactive/LegendInput.tsx | 13 +- src/Common/hooks/useCareApps.ts | 35 + .../CentralLiveMonitoring/index.tsx | 2 +- src/Components/Common/ErrorBoundary.tsx | 36 + src/Components/Common/Sidebar/Sidebar.tsx | 19 +- src/Components/Common/Sidebar/SidebarItem.tsx | 22 +- src/Components/Common/SortDropdown.tsx | 1 + .../Facility/DoctorVideoSlideover.tsx | 2 + .../{HospitalList.tsx => FacilityList.tsx} | 2 +- .../Notifications/ShowPushNotification.tsx | 3 +- src/Components/Users/UserProfile.tsx | 100 +- src/Locale/en.json | 27 +- src/PluginEngine.tsx | 51 + src/Redux/api.tsx | 2 +- src/Routers/AppRouter.tsx | 37 +- src/Routers/routes/AssetRoutes.tsx | 25 +- src/Routers/routes/ConsultationRoutes.tsx | 68 +- .../routes/FacilityInventoryRoutes.tsx | 19 +- src/Routers/routes/FacilityLocationRoutes.tsx | 25 +- src/Routers/routes/FacilityRoutes.tsx | 31 +- src/Routers/routes/HCXRoutes.tsx | 17 +- src/Routers/routes/PatientRoutes.tsx | 26 +- src/Routers/routes/ResourceRoutes.tsx | 12 +- src/Routers/routes/SampleRoutes.tsx | 20 +- src/Routers/routes/ShiftingRoutes.tsx | 11 +- src/Routers/routes/UserRoutes.tsx | 5 +- src/Utils/useTimer.tsx | 2 +- src/pluginTypes.ts | 54 + src/vite-env.d.ts | 1 + tsconfig.json | 5 +- vite.config.mts | 61 +- 48 files changed, 1275 insertions(+), 870 deletions(-) create mode 100644 .cursorrules create mode 100644 .env.docker create mode 100644 .nvmrc create mode 100644 scripts/setup-care-apps.js delete mode 100644 src/CAREUI/icons/icon.js create mode 100644 src/Common/hooks/useCareApps.ts create mode 100644 src/Components/Common/ErrorBoundary.tsx rename src/Components/Facility/{HospitalList.tsx => FacilityList.tsx} (99%) create mode 100644 src/PluginEngine.tsx create mode 100644 src/pluginTypes.ts diff --git a/.cursorrules b/.cursorrules new file mode 100644 index 00000000000..a561180ab91 --- /dev/null +++ b/.cursorrules @@ -0,0 +1,23 @@ +Care is a React Typescript Project, built with Vite and styled with TailwindCSS. + +Care uses a Plugin Architecture. Apps are installed in /apps. + +Care uses a custom useQuery hook to fetch data from the API. APIs are defined in the api.tsx file + +Here's an example of how to use the useQuery hook to fetch data from the API: + +``` +useQuery from "@/Common/hooks/useQuery"; +const { data, loading, error } = useQuery(routes.getFacilityUsers, { + facility_id: "1", +}); + +request from "@/Common/utils/request"; +const { res } = await request(routes.partialUpdateAsset, { + pathParams: { external_id: assetId }, + body: data, +}); +``` + + + diff --git a/.env.docker b/.env.docker new file mode 100644 index 00000000000..fb5179c6c50 --- /dev/null +++ b/.env.docker @@ -0,0 +1,2 @@ +# Care API URL without the /api prefix +REACT_CARE_API_URL=http://localhost:9000 \ No newline at end of file diff --git a/.example.env b/.example.env index f3f303bc1e3..0ce9043b9a3 100644 --- a/.example.env +++ b/.example.env @@ -16,6 +16,8 @@ REACT_PLAUSIBLE_SITE_DOMAIN= # Plausible server URL (default: https://plausible.10bedicu.in) REACT_PLAUSIBLE_SERVER_URL= +# Care Apps. repo@branch seperated by commas +REACT_ENABLED_APPS="ohcnetwork/care_livekit_fe@main,ohcnetwork/care_scribe" # Main logo (JSON string with light and dark properties) REACT_HEADER_LOGO= diff --git a/.gitignore b/.gitignore index d8e2615c727..000a965c44a 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,7 @@ bun.lockb # Cypress cypress/downloads cypress/fixtures/token.json + +# Care Apps +/apps/* +src/pluginMap.ts diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000000..2edeafb09db --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +20 \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json index e3a9c2acae9..ba722afdd73 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -5,7 +5,6 @@ "semi": true, "jsxSingleQuote": false, "arrowParens": "always", - "tailwindFunctions": [ - "classNames" - ] -} \ No newline at end of file + "tailwindFunctions": ["classNames"], + "plugins": ["prettier-plugin-tailwindcss"] +} diff --git a/README.md b/README.md index 73ce06815d1..7ea8fe1a221 100644 --- a/README.md +++ b/README.md @@ -8,20 +8,22 @@

    Our goal is to continuously improve the quality and accessibility of public healthcare services using digital tools.

    -

    🚀 Staging Deploy

    -

    +

    🚀 Staging Deployment

    +
    + +[![Netlify Status](https://api.netlify.com/api/v1/badges/de76351f-b1f0-4bf8-8445-d9faf6391b13/deploy-status)](https://app.netlify.com/sites/care-ohc/deploys) + +

    Auto deployed to care.ohc.network for develop branch. All pull requests have preview builds powered by Netlify.

    [![](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/images/0)](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/links/0)[![](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/images/1)](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/links/1)[![](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/images/2)](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/links/2)[![](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/images/3)](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/links/3)[![](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/images/4)](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/links/4)[![](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/images/5)](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/links/5)[![](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/images/6)](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/links/6)[![](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/images/7)](https://sourcerer.io/fame/tomahawk-pilot/ohcnetwork/care_fe/links/7) -[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=coronasafe_care_fe&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=coronasafe_care_fe) ![Code scanning - action](https://github.com/ohcnetwork/care_fe/workflows/Code%20scanning%20-%20action/badge.svg) ![OSSAR](https://github.com/ohcnetwork/care_fe/workflows/OSSAR/badge.svg) [![Cypress Tests](https://img.shields.io/endpoint?url=https://cloud.cypress.io/badge/simple/wf7d2m/develop&style=flat&logo=cypress)](https://cloud.cypress.io/projects/wf7d2m/runs) ![Staging Release](https://github.com/ohcnetwork/care_fe/workflows/CARE%20Develop%20Registry/badge.svg) ![Production Release](https://github.com/ohcnetwork/care_fe/workflows/Production%20Release/badge.svg) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/200482ab117e4b5397ff3f5ae5719aa2)](https://www.codacy.com/gh/ohcnetwork/care_fe?utm_source=github.com&utm_medium=referral&utm_content=ohcnetwork/care_fe&utm_campaign=Badge_Grade) -[![CircleCI](https://circleci.com/gh/ohcnetwork/care_fe.svg?style=svg)](https://circleci.com/gh/ohcnetwork/care_fe) [![Maintainability](https://api.codeclimate.com/v1/badges/f1438f693aa459805301/maintainability)](https://codeclimate.com/github/ohcnetwork/care_fe/maintainability) ## Getting started @@ -33,7 +35,14 @@ #### Install the required dependencies ```sh -npm install +npm run install-all +``` +#### First-time setup + +For first-time setup, run the following command to generate the pluginMap and install plugin configurations: + +```sh +npm run setup ``` #### 🏃 Run the app in development mode diff --git a/care.config.ts b/care.config.ts index c032ba613f3..ed82d69554a 100644 --- a/care.config.ts +++ b/care.config.ts @@ -103,6 +103,13 @@ const careConfig = { abdm: { enabled: (env.REACT_ENABLE_ABDM ?? "true") === "true", }, + + careApps: env.REACT_ENABLED_APPS + ? env.REACT_ENABLED_APPS.split(",").map((app) => ({ + branch: app.split("@")[1], + package: app.split("@")[0], + })) + : [], } as const; export default careConfig; diff --git a/cypress/e2e/users_spec/UsersHomepage.cy.ts b/cypress/e2e/users_spec/UsersHomepage.cy.ts index 0cf25cacfc8..634336a4ef9 100644 --- a/cypress/e2e/users_spec/UsersHomepage.cy.ts +++ b/cypress/e2e/users_spec/UsersHomepage.cy.ts @@ -14,7 +14,7 @@ describe("User Homepage", () => { const altPhoneNumber = "8878825662"; const homeFacility = "Dummy Facility 40"; const nurseUserName = "dummynurse1"; - const doctorUserName = "devdoctor"; + const doctorUserName = "devdoctor1"; before(() => { loginPage.loginAsDisctrictAdmin(); diff --git a/cypress/pageobject/Facility/FacilityCreation.ts b/cypress/pageobject/Facility/FacilityCreation.ts index 26f387935ac..fe838a88f41 100644 --- a/cypress/pageobject/Facility/FacilityCreation.ts +++ b/cypress/pageobject/Facility/FacilityCreation.ts @@ -297,7 +297,7 @@ class FacilityPage { selectLocation(location: string) { cy.intercept("https://maps.googleapis.com/**").as("mapApi"); - cy.get("span > svg.care-svg-icon__baseline.care-l-map-marker").click(); + cy.get("#facility-location-button").click(); cy.wait("@mapApi").its("response.statusCode").should("eq", 200); cy.get("input#pac-input").type(location).type("{enter}"); cy.wait(2000); diff --git a/package-lock.json b/package-lock.json index e66a3ea4ead..e5bae3c6d02 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "care_fe", "version": "2.5.4", "license": "MIT", + "workspaces": [ + "apps/*" + ], "dependencies": { "@fontsource/figtree": "^5.1.0", "@googlemaps/react-wrapper": "^1.1.35", @@ -20,7 +23,7 @@ "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-toast": "^1.2.2", "@sentry/browser": "^8.33.0", - "@yudiel/react-qr-scanner": "^2.0.0-beta.3", + "@yudiel/react-qr-scanner": "^2.0.8", "axios": "^1.7.7", "bowser": "^2.11.0", "browser-image-compression": "^2.0.2", @@ -68,7 +71,7 @@ "@types/lodash-es": "^4.17.12", "@types/node": "^22.7.4", "@types/qrcode.react": "^1.0.5", - "@types/react": "18.3.2", + "@types/react": "^18.3.11", "@types/react-copy-to-clipboard": "^5.0.7", "@types/react-csv": "^1.1.10", "@types/react-dom": "^18.3.0", @@ -79,6 +82,7 @@ "autoprefixer": "^10.4.19", "cypress-localstorage-commands": "^2.2.5", "cypress-split": "^1.23.2", + "dotenv": "^16.4.5", "eslint-config-prettier": "^9.1.0", "eslint-plugin-i18next": "^6.0.9", "eslint-plugin-mdx": "^3.1.5", @@ -106,6 +110,24 @@ "node": ">=20.12.0" } }, + "apps/care_livekit_fe": { + "name": "care-livekit", + "version": "0.0.1", + "license": "ISC", + "dependencies": { + "@livekit/components-react": "^2.6.2", + "@livekit/components-styles": "^1.1.3", + "livekit-client": "^2.5.5" + }, + "devDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependencies": { + "react": "18.3.1", + "react-dom": "18.3.1" + } + }, "node_modules/@actions/core": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz", @@ -178,18 +200,18 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.7.tgz", - "integrity": "sha512-9ickoLz+hcXCeh7jrcin+/SLWm+GkxE2kTvoYyp38p4WkdFXfQJxDFGWp/YHjiKLPx06z2A7W8XKuqbReXDzsw==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.8.tgz", + "integrity": "sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.7.tgz", - "integrity": "sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.8.tgz", + "integrity": "sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -198,10 +220,10 @@ "@babel/helper-compilation-targets": "^7.25.7", "@babel/helper-module-transforms": "^7.25.7", "@babel/helpers": "^7.25.7", - "@babel/parser": "^7.25.7", + "@babel/parser": "^7.25.8", "@babel/template": "^7.25.7", "@babel/traverse": "^7.25.7", - "@babel/types": "^7.25.7", + "@babel/types": "^7.25.8", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -636,12 +658,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.7.tgz", - "integrity": "sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.8.tgz", + "integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==", "dev": true, "dependencies": { - "@babel/types": "^7.25.7" + "@babel/types": "^7.25.8" }, "bin": { "parser": "bin/babel-parser.js" @@ -741,69 +763,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-import-assertions": { "version": "7.25.7", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.7.tgz", @@ -834,30 +793,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-jsx": { "version": "7.25.7", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.7.tgz", @@ -873,108 +808,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-unicode-sets-regex": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", @@ -1007,14 +840,13 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.7.tgz", - "integrity": "sha512-4B6OhTrwYKHYYgcwErvZjbmH9X5TxQBsaBHdzEIB4l71gR5jh/tuHGlb9in47udL2+wVUcOz5XXhhfhVJwEpEg==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.8.tgz", + "integrity": "sha512-9ypqkozyzpG+HxlH4o4gdctalFGIjjdufzo7I2XPda0iBnZ6a+FO0rIEQcdSPXp02CkvGsII1exJhmROPQd5oA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.7", "@babel/helper-remap-async-to-generator": "^7.25.7", - "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/traverse": "^7.25.7" }, "engines": { @@ -1088,14 +920,13 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.25.7.tgz", - "integrity": "sha512-rvUUtoVlkDWtDWxGAiiQj0aNktTPn3eFynBcMC2IhsXweehwgdI9ODe+XjWw515kEmv22sSOTp/rxIRuTiB7zg==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.25.8.tgz", + "integrity": "sha512-e82gl3TCorath6YLf9xUwFehVvjvfqFhdOo4+0iVIVju+6XOi5XHkqB3P2AXnSwoeTX0HBoXq5gJFtvotJzFnQ==", "dev": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.25.7", - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-class-static-block": "^7.14.5" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1212,13 +1043,12 @@ } }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.7.tgz", - "integrity": "sha512-UvcLuual4h7/GfylKm2IAA3aph9rwvAM2XBA0uPKU3lca+Maai4jBjjEVUS568ld6kJcgbouuumCBhMd/Yz17w==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.8.tgz", + "integrity": "sha512-gznWY+mr4ZQL/EWPcbBQUP3BXS5FwZp8RUOw06BaRn8tQLzN4XLIxXejpHN9Qo8x8jjBmAAKp6FoS51AgkSA/A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1244,13 +1074,12 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.7.tgz", - "integrity": "sha512-h3MDAP5l34NQkkNulsTNyjdaR+OiB0Im67VU//sFupouP8Q6m9Spy7l66DcaAQxtmCqGdanPByLsnwFttxKISQ==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.8.tgz", + "integrity": "sha512-sPtYrduWINTQTW7FtOy99VCTWp4H23UX7vYcut7S4CIMEXU+54zKX9uCoGkLsWXteyaMXzVHgzWbLfQ1w4GZgw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1293,13 +1122,12 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.7.tgz", - "integrity": "sha512-Ot43PrL9TEAiCe8C/2erAjXMeVSnE/BLEx6eyrKLNFCCw5jvhTHKyHxdI1pA0kz5njZRYAnMO2KObGqOCRDYSA==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.8.tgz", + "integrity": "sha512-4OMNv7eHTmJ2YXs3tvxAfa/I43di+VcF+M4Wt66c88EAED1RoGaf1D64cL5FkRpNL+Vx9Hds84lksWvd/wMIdA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1324,13 +1152,12 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.7.tgz", - "integrity": "sha512-iImzbA55BjiovLyG2bggWS+V+OLkaBorNvc/yJoeeDQGztknRnDdYfp2d/UPmunZYEnZi6Lg8QcTmNMHOB0lGA==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.8.tgz", + "integrity": "sha512-f5W0AhSbbI+yY6VakT04jmxdxz+WsID0neG7+kQZbCOjuyJNdL5Nn4WIBm4hRpKnUcO9lP0eipUhFN12JpoH8g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1453,13 +1280,12 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.7.tgz", - "integrity": "sha512-FbuJ63/4LEL32mIxrxwYaqjJxpbzxPVQj5a+Ebrc8JICV6YX8nE53jY+K0RZT3um56GoNWgkS2BQ/uLGTjtwfw==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.8.tgz", + "integrity": "sha512-Z7WJJWdQc8yCWgAmjI3hyC+5PXIubH9yRKzkl9ZEG647O9szl9zvmKLzpbItlijBnVhTUf1cpyWBsZ3+2wjWPQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1469,13 +1295,12 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.7.tgz", - "integrity": "sha512-8CbutzSSh4hmD+jJHIA8vdTNk15kAzOnFLVVgBSMGr28rt85ouT01/rezMecks9pkU939wDInImwCKv4ahU4IA==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.8.tgz", + "integrity": "sha512-rm9a5iEFPS4iMIy+/A/PiS0QN0UyjPIeVvbU5EMZFKJZHt8vQnasbpo3T3EFcxzCeYO0BHfc4RqooCZc51J86Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1485,14 +1310,13 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.7.tgz", - "integrity": "sha512-1JdVKPhD7Y5PvgfFy0Mv2brdrolzpzSoUq2pr6xsR+m+3viGGeHEokFKsCgOkbeFOQxfB1Vt2F0cPJLRpFI4Zg==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.8.tgz", + "integrity": "sha512-LkUu0O2hnUKHKE7/zYOIjByMa4VRaV2CD/cdGz0AxU9we+VA3kDDggKEzI0Oz1IroG+6gUP6UmWEHBMWZU316g==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.25.7", "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-transform-parameters": "^7.25.7" }, "engines": { @@ -1519,13 +1343,12 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.7.tgz", - "integrity": "sha512-m9obYBA39mDPN7lJzD5WkGGb0GO54PPLXsbcnj1Hyeu8mSRz7Gb4b1A6zxNX32ZuUySDK4G6it8SDFWD1nCnqg==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.8.tgz", + "integrity": "sha512-EbQYweoMAHOn7iJ9GgZo14ghhb9tTjgOc88xFgYngifx7Z9u580cENCV159M4xDh3q/irbhSjZVpuhpC2gKBbg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1535,14 +1358,13 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.7.tgz", - "integrity": "sha512-h39agClImgPWg4H8mYVAbD1qP9vClFbEjqoJmt87Zen8pjqK8FTPUwrOXAvqu5soytwxrLMd2fx2KSCp2CHcNg==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.8.tgz", + "integrity": "sha512-q05Bk7gXOxpTHoQ8RSzGSh/LHVB9JEIkKnk3myAWwZHnYiTGYtbdrYkIsS8Xyh4ltKf7GNUSgzs/6P2bJtBAQg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.7", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1583,15 +1405,14 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.7.tgz", - "integrity": "sha512-LzA5ESzBy7tqj00Yjey9yWfs3FKy4EmJyKOSWld144OxkTji81WWnUT8nkLUn+imN/zHL8ZQlOu/MTUAhHaX3g==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.8.tgz", + "integrity": "sha512-8Uh966svuB4V8RHHg0QJOB32QK287NBksJOByoKmHMp1TAobNniNalIkI2i5IPj5+S9NYCG4VIjbEuiSN8r+ow==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.7", "@babel/helper-create-class-features-plugin": "^7.25.7", - "@babel/helper-plugin-utils": "^7.25.7", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + "@babel/helper-plugin-utils": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -1786,12 +1607,12 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.7.tgz", - "integrity": "sha512-Gibz4OUdyNqqLj+7OAvBZxOD7CklCtMA5/j0JgUEwOnaRULsPDXmic2iKxL2DX2vQduPR5wH2hjZas/Vr/Oc0g==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.8.tgz", + "integrity": "sha512-58T2yulDHMN8YMUxiLq5YmWUnlDCyY1FsHM+v12VMx+1/FlrUj5tY50iDCpofFQEM8fMYOaY9YRvym2jcjn1Dg==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.25.7", + "@babel/compat-data": "^7.25.8", "@babel/helper-compilation-targets": "^7.25.7", "@babel/helper-plugin-utils": "^7.25.7", "@babel/helper-validator-option": "^7.25.7", @@ -1801,45 +1622,30 @@ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.7", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.7", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", "@babel/plugin-syntax-import-assertions": "^7.25.7", "@babel/plugin-syntax-import-attributes": "^7.25.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.25.7", - "@babel/plugin-transform-async-generator-functions": "^7.25.7", + "@babel/plugin-transform-async-generator-functions": "^7.25.8", "@babel/plugin-transform-async-to-generator": "^7.25.7", "@babel/plugin-transform-block-scoped-functions": "^7.25.7", "@babel/plugin-transform-block-scoping": "^7.25.7", "@babel/plugin-transform-class-properties": "^7.25.7", - "@babel/plugin-transform-class-static-block": "^7.25.7", + "@babel/plugin-transform-class-static-block": "^7.25.8", "@babel/plugin-transform-classes": "^7.25.7", "@babel/plugin-transform-computed-properties": "^7.25.7", "@babel/plugin-transform-destructuring": "^7.25.7", "@babel/plugin-transform-dotall-regex": "^7.25.7", "@babel/plugin-transform-duplicate-keys": "^7.25.7", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.7", - "@babel/plugin-transform-dynamic-import": "^7.25.7", + "@babel/plugin-transform-dynamic-import": "^7.25.8", "@babel/plugin-transform-exponentiation-operator": "^7.25.7", - "@babel/plugin-transform-export-namespace-from": "^7.25.7", + "@babel/plugin-transform-export-namespace-from": "^7.25.8", "@babel/plugin-transform-for-of": "^7.25.7", "@babel/plugin-transform-function-name": "^7.25.7", - "@babel/plugin-transform-json-strings": "^7.25.7", + "@babel/plugin-transform-json-strings": "^7.25.8", "@babel/plugin-transform-literals": "^7.25.7", - "@babel/plugin-transform-logical-assignment-operators": "^7.25.7", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.8", "@babel/plugin-transform-member-expression-literals": "^7.25.7", "@babel/plugin-transform-modules-amd": "^7.25.7", "@babel/plugin-transform-modules-commonjs": "^7.25.7", @@ -1847,15 +1653,15 @@ "@babel/plugin-transform-modules-umd": "^7.25.7", "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.7", "@babel/plugin-transform-new-target": "^7.25.7", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.7", - "@babel/plugin-transform-numeric-separator": "^7.25.7", - "@babel/plugin-transform-object-rest-spread": "^7.25.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.8", + "@babel/plugin-transform-numeric-separator": "^7.25.8", + "@babel/plugin-transform-object-rest-spread": "^7.25.8", "@babel/plugin-transform-object-super": "^7.25.7", - "@babel/plugin-transform-optional-catch-binding": "^7.25.7", - "@babel/plugin-transform-optional-chaining": "^7.25.7", + "@babel/plugin-transform-optional-catch-binding": "^7.25.8", + "@babel/plugin-transform-optional-chaining": "^7.25.8", "@babel/plugin-transform-parameters": "^7.25.7", "@babel/plugin-transform-private-methods": "^7.25.7", - "@babel/plugin-transform-private-property-in-object": "^7.25.7", + "@babel/plugin-transform-private-property-in-object": "^7.25.8", "@babel/plugin-transform-property-literals": "^7.25.7", "@babel/plugin-transform-regenerator": "^7.25.7", "@babel/plugin-transform-reserved-words": "^7.25.7", @@ -1958,9 +1764,9 @@ } }, "node_modules/@babel/types": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.7.tgz", - "integrity": "sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz", + "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.25.7", @@ -1971,6 +1777,11 @@ "node": ">=6.9.0" } }, + "node_modules/@bufbuild/protobuf": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-1.10.0.tgz", + "integrity": "sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag==" + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -2539,9 +2350,9 @@ } }, "node_modules/@floating-ui/react": { - "version": "0.26.24", - "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.24.tgz", - "integrity": "sha512-2ly0pCkZIGEQUq5H8bBK0XJmc1xIK/RM3tvVzY3GBER7IOD1UgmC2Y2tjj4AuS+TC+vTE1KJv2053290jua0Sw==", + "version": "0.26.25", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.25.tgz", + "integrity": "sha512-hZOmgN0NTOzOuZxI1oIrDu3Gcl8WViIkvPMpB4xdd4QD6xAMtwgwr3VPoiyH/bLtRcS1cDnhxLSD1NsMJmwh/A==", "dependencies": { "@floating-ui/react-dom": "^2.1.2", "@floating-ui/utils": "^0.2.8", @@ -2596,9 +2407,9 @@ "integrity": "sha512-3iHuO8H0jPehftsMK0kgyJzPYU/g/oiTRw+wu/yltqSZ7wJPt3vfsJHkPiuRpQjbnnWygX+T3mkRGyK/eyZ/lw==" }, "node_modules/@headlessui/react": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.1.9.tgz", - "integrity": "sha512-ckWw7vlKtnoa1fL2X0fx1a3t/Li9MIKDVXn3SgG65YlxvDAsNrY39PPCxVM7sQRA7go2fJsuHSSauKFNaJHH7A==", + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.1.10.tgz", + "integrity": "sha512-6mLa2fjMDAFQi+/R10B+zU3edsUk/MDtENB2zHho0lqKU1uzhAfJLUduWds4nCo8wbl3vULtC5rJfZAQ1yqIng==", "dependencies": { "@floating-ui/react": "^0.26.16", "@react-aria/focus": "^3.17.1", @@ -2834,6 +2645,64 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@livekit/components-core": { + "version": "0.11.9", + "resolved": "https://registry.npmjs.org/@livekit/components-core/-/components-core-0.11.9.tgz", + "integrity": "sha512-LPE1BZ+YTaqsVqGy/GAlpiO5rEI8XpEaf1TQcGdZN1BCBas9hTHt7/aHMbHQJ0K5xuAFQx8is6dFe451T4qXIQ==", + "dependencies": { + "@floating-ui/dom": "1.6.11", + "loglevel": "1.9.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "livekit-client": "^2.5.7", + "tslib": "^2.6.2" + } + }, + "node_modules/@livekit/components-react": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@livekit/components-react/-/components-react-2.6.5.tgz", + "integrity": "sha512-G3BpBlKy+lWTV9MH3/oBTBC17Z8CWqZ9GnjcG/xmYI0IvqmY89tVWph7cj2Bq0taniA+mD3U9EMPr68fOb1m1g==", + "dependencies": { + "@livekit/components-core": "0.11.9", + "clsx": "2.1.1", + "usehooks-ts": "3.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@livekit/krisp-noise-filter": "^0.2.12", + "livekit-client": "^2.5.7", + "react": ">=18", + "react-dom": ">=18", + "tslib": "^2.6.2" + }, + "peerDependenciesMeta": { + "@livekit/krisp-noise-filter": { + "optional": true + } + } + }, + "node_modules/@livekit/components-styles": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@livekit/components-styles/-/components-styles-1.1.4.tgz", + "integrity": "sha512-QCupn7tQ/dy/WZclrfsgtDe8peiGYS6Ied1IGkKOysaXo04l90t62SIUTKyxgd0dNDhUDC0p34qCggGZs/44lQ==", + "engines": { + "node": ">=18" + } + }, + "node_modules/@livekit/protocol": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/@livekit/protocol/-/protocol-1.24.0.tgz", + "integrity": "sha512-9dCsqnkMn7lvbI4NGh18zhLDsrXyUcpS++TEFgEk5Xv1WM3R2kT3EzqgL1P/mr3jaabM6rJ8wZA/KJLuQNpF5w==", + "dependencies": { + "@bufbuild/protobuf": "^1.10.0" + } + }, "node_modules/@mapbox/node-pre-gyp": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", @@ -3556,11 +3425,11 @@ } }, "node_modules/@react-aria/focus": { - "version": "3.18.3", - "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.18.3.tgz", - "integrity": "sha512-WKUElg+5zS0D3xlVn8MntNnkzJql2J6MuzAMP8Sv5WTgFDse/XGR842dsxPTIyKKdrWVCRegCuwa4m3n/GzgJw==", + "version": "3.18.4", + "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.18.4.tgz", + "integrity": "sha512-91J35077w9UNaMK1cpMUEFRkNNz0uZjnSwiyBCFuRdaVuivO53wNC9XtWSDNDdcO5cGy87vfJRVAiyoCn/mjqA==", "dependencies": { - "@react-aria/interactions": "^3.22.3", + "@react-aria/interactions": "^3.22.4", "@react-aria/utils": "^3.25.3", "@react-types/shared": "^3.25.0", "@swc/helpers": "^0.5.0", @@ -3571,9 +3440,9 @@ } }, "node_modules/@react-aria/interactions": { - "version": "3.22.3", - "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.22.3.tgz", - "integrity": "sha512-RRUb/aG+P0IKTIWikY/SylB6bIbLZeztnZY2vbe7RAG5MgVaCgn5HQ45SI15GlTmhsFG8CnF6slJsUFJiNHpbQ==", + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.22.4.tgz", + "integrity": "sha512-E0vsgtpItmknq/MJELqYJwib+YN18Qag8nroqwjk1qOnBa9ROIkUhWJerLi1qs5diXq9LHKehZDXRlwPvdEFww==", "dependencies": { "@react-aria/ssr": "^3.9.6", "@react-aria/utils": "^3.25.3", @@ -3926,145 +3795,145 @@ ] }, "node_modules/@sentry-internal/browser-utils": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.33.1.tgz", - "integrity": "sha512-TW6/r+Gl5jiXv54iK1xZ3mlVgTS/jaBp4vcQ0xGMdgiQ3WchEPcFSeYovL+YHT3tSud0GZqVtDQCz+5i76puqA==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.34.0.tgz", + "integrity": "sha512-4AcYOzPzD1tL5eSRQ/GpKv5enquZf4dMVUez99/Bh3va8qiJrNP55AcM7UzZ7WZLTqKygIYruJTU5Zu2SpEAPQ==", "dependencies": { - "@sentry/core": "8.33.1", - "@sentry/types": "8.33.1", - "@sentry/utils": "8.33.1" + "@sentry/core": "8.34.0", + "@sentry/types": "8.34.0", + "@sentry/utils": "8.34.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/feedback": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.33.1.tgz", - "integrity": "sha512-qauMRTm3qDaLqZ3ibI03cj4gLF40y0ij65nj+cns6iWxGCtPrO8tjvXFWuQsE7Aye9dGMnBgmv7uN+NTUtC3RA==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.34.0.tgz", + "integrity": "sha512-aYSM2KPUs0FLPxxbJCFSwCYG70VMzlT04xepD1Y/tTlPPOja/02tSv2tyOdZbv8Uw7xslZs3/8Lhj74oYcTBxw==", "dependencies": { - "@sentry/core": "8.33.1", - "@sentry/types": "8.33.1", - "@sentry/utils": "8.33.1" + "@sentry/core": "8.34.0", + "@sentry/types": "8.34.0", + "@sentry/utils": "8.34.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.33.1.tgz", - "integrity": "sha512-fm4coIOjmanU29NOVN9MyaP4fUCOYytbtFqVSKRFNZQ/xAgNeySiBIbUd6IjujMmnOk9bY0WEUMcdm3Uotjdog==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.34.0.tgz", + "integrity": "sha512-EoMh9NYljNewZK1quY23YILgtNdGgrkzJ9TPsj6jXUG0LZ0Q7N7eFWd0xOEDBvFxrmI3cSXF1i4d1sBb+eyKRw==", "dependencies": { - "@sentry-internal/browser-utils": "8.33.1", - "@sentry/core": "8.33.1", - "@sentry/types": "8.33.1", - "@sentry/utils": "8.33.1" + "@sentry-internal/browser-utils": "8.34.0", + "@sentry/core": "8.34.0", + "@sentry/types": "8.34.0", + "@sentry/utils": "8.34.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.33.1.tgz", - "integrity": "sha512-nsxTFTPCT10Ty/v6+AiST3+yotGP1sUb8xqfKB9fPnS1hZHFryp0NnEls7xFjBsBbZPU1GpFkzrk/E6JFzixDQ==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.34.0.tgz", + "integrity": "sha512-x8KhZcCDpbKHqFOykYXiamX6x0LRxv6N1OJHoH+XCrMtiDBZr4Yo30d/MaS6rjmKGMtSRij30v+Uq+YWIgxUrg==", "dependencies": { - "@sentry-internal/replay": "8.33.1", - "@sentry/core": "8.33.1", - "@sentry/types": "8.33.1", - "@sentry/utils": "8.33.1" + "@sentry-internal/replay": "8.34.0", + "@sentry/core": "8.34.0", + "@sentry/types": "8.34.0", + "@sentry/utils": "8.34.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/tracing": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.119.1.tgz", - "integrity": "sha512-cI0YraPd6qBwvUA3wQdPGTy8PzAoK0NZiaTN1LM3IczdPegehWOaEG5GVTnpGnTsmBAzn1xnBXNBhgiU4dgcrQ==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.119.2.tgz", + "integrity": "sha512-V2W+STWrafyGJhQv3ulMFXYDwWHiU6wHQAQBShsHVACiFaDrJ2kPRet38FKv4dMLlLlP2xN+ss2e5zv3tYlTiQ==", "dev": true, "dependencies": { - "@sentry/core": "7.119.1", - "@sentry/types": "7.119.1", - "@sentry/utils": "7.119.1" + "@sentry/core": "7.119.2", + "@sentry/types": "7.119.2", + "@sentry/utils": "7.119.2" }, "engines": { "node": ">=8" } }, "node_modules/@sentry-internal/tracing/node_modules/@sentry/core": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.119.1.tgz", - "integrity": "sha512-YUNnH7O7paVd+UmpArWCPH4Phlb5LwrkWVqzFWqL3xPyCcTSof2RL8UmvpkTjgYJjJ+NDfq5mPFkqv3aOEn5Sw==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.119.2.tgz", + "integrity": "sha512-hQr3d2yWq/2lMvoyBPOwXw1IHqTrCjOsU1vYKhAa6w9vGbJZFGhKGGE2KEi/92c3gqGn+gW/PC7cV6waCTDuVA==", "dev": true, "dependencies": { - "@sentry/types": "7.119.1", - "@sentry/utils": "7.119.1" + "@sentry/types": "7.119.2", + "@sentry/utils": "7.119.2" }, "engines": { "node": ">=8" } }, "node_modules/@sentry-internal/tracing/node_modules/@sentry/types": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.119.1.tgz", - "integrity": "sha512-4G2mcZNnYzK3pa2PuTq+M2GcwBRY/yy1rF+HfZU+LAPZr98nzq2X3+mJHNJoobeHRkvVh7YZMPi4ogXiIS5VNQ==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.119.2.tgz", + "integrity": "sha512-ydq1tWsdG7QW+yFaTp0gFaowMLNVikIqM70wxWNK+u98QzKnVY/3XTixxNLsUtnAB4Y+isAzFhrc6Vb5GFdFeg==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/@sentry-internal/tracing/node_modules/@sentry/utils": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.119.1.tgz", - "integrity": "sha512-ju/Cvyeu/vkfC5/XBV30UNet5kLEicZmXSyuLwZu95hEbL+foPdxN+re7pCI/eNqfe3B2vz7lvz5afLVOlQ2Hg==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.119.2.tgz", + "integrity": "sha512-TLdUCvcNgzKP0r9YD7tgCL1PEUp42TObISridsPJ5rhpVGQJvpr+Six0zIkfDUxerLYWZoK8QMm9KgFlPLNQzA==", "dev": true, "dependencies": { - "@sentry/types": "7.119.1" + "@sentry/types": "7.119.2" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/browser": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.33.1.tgz", - "integrity": "sha512-c6zI/igexkLwZuGk+u8Rj26ChjxGgkhe6ZbKFsXCYaKAp5ep5X7HQRkkqgbxApiqlC0LduHdd/ymzh139JLg8w==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.34.0.tgz", + "integrity": "sha512-3HHG2NXxzHq1lVmDy2uRjYjGNf9NsJsTPlOC70vbQdOb+S49EdH/XMPy+J3ruIoyv6Cu0LwvA6bMOM6rHZOgNQ==", "dependencies": { - "@sentry-internal/browser-utils": "8.33.1", - "@sentry-internal/feedback": "8.33.1", - "@sentry-internal/replay": "8.33.1", - "@sentry-internal/replay-canvas": "8.33.1", - "@sentry/core": "8.33.1", - "@sentry/types": "8.33.1", - "@sentry/utils": "8.33.1" + "@sentry-internal/browser-utils": "8.34.0", + "@sentry-internal/feedback": "8.34.0", + "@sentry-internal/replay": "8.34.0", + "@sentry-internal/replay-canvas": "8.34.0", + "@sentry/core": "8.34.0", + "@sentry/types": "8.34.0", + "@sentry/utils": "8.34.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry/core": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.33.1.tgz", - "integrity": "sha512-3SS41suXLFzxL3OQvTMZ6q92ZapELVq2l2SoWlZopcamWhog2Ru0dp2vkunq97kFHb2TzKRTlFH4+4gbT8SJug==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.34.0.tgz", + "integrity": "sha512-adrXCTK/zsg5pJ67lgtZqdqHvyx6etMjQW3P82NgWdj83c8fb+zH+K79Z47pD4zQjX0ou2Ws5nwwi4wJbz4bfA==", "dependencies": { - "@sentry/types": "8.33.1", - "@sentry/utils": "8.33.1" + "@sentry/types": "8.34.0", + "@sentry/utils": "8.34.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry/integrations": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.119.1.tgz", - "integrity": "sha512-CGmLEPnaBqbUleVqrmGYjRjf5/OwjUXo57I9t0KKWViq81mWnYhaUhRZWFNoCNQHns+3+GPCOMvl0zlawt+evw==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.119.2.tgz", + "integrity": "sha512-dCuXKvbUE3gXVVa696SYMjlhSP6CxpMH/gl4Jk26naEB8Xjsn98z/hqEoXLg6Nab73rjR9c/9AdKqBbwVMHyrQ==", "dev": true, "dependencies": { - "@sentry/core": "7.119.1", - "@sentry/types": "7.119.1", - "@sentry/utils": "7.119.1", + "@sentry/core": "7.119.2", + "@sentry/types": "7.119.2", + "@sentry/utils": "7.119.2", "localforage": "^1.8.1" }, "engines": { @@ -4072,103 +3941,103 @@ } }, "node_modules/@sentry/integrations/node_modules/@sentry/core": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.119.1.tgz", - "integrity": "sha512-YUNnH7O7paVd+UmpArWCPH4Phlb5LwrkWVqzFWqL3xPyCcTSof2RL8UmvpkTjgYJjJ+NDfq5mPFkqv3aOEn5Sw==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.119.2.tgz", + "integrity": "sha512-hQr3d2yWq/2lMvoyBPOwXw1IHqTrCjOsU1vYKhAa6w9vGbJZFGhKGGE2KEi/92c3gqGn+gW/PC7cV6waCTDuVA==", "dev": true, "dependencies": { - "@sentry/types": "7.119.1", - "@sentry/utils": "7.119.1" + "@sentry/types": "7.119.2", + "@sentry/utils": "7.119.2" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/integrations/node_modules/@sentry/types": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.119.1.tgz", - "integrity": "sha512-4G2mcZNnYzK3pa2PuTq+M2GcwBRY/yy1rF+HfZU+LAPZr98nzq2X3+mJHNJoobeHRkvVh7YZMPi4ogXiIS5VNQ==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.119.2.tgz", + "integrity": "sha512-ydq1tWsdG7QW+yFaTp0gFaowMLNVikIqM70wxWNK+u98QzKnVY/3XTixxNLsUtnAB4Y+isAzFhrc6Vb5GFdFeg==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/@sentry/integrations/node_modules/@sentry/utils": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.119.1.tgz", - "integrity": "sha512-ju/Cvyeu/vkfC5/XBV30UNet5kLEicZmXSyuLwZu95hEbL+foPdxN+re7pCI/eNqfe3B2vz7lvz5afLVOlQ2Hg==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.119.2.tgz", + "integrity": "sha512-TLdUCvcNgzKP0r9YD7tgCL1PEUp42TObISridsPJ5rhpVGQJvpr+Six0zIkfDUxerLYWZoK8QMm9KgFlPLNQzA==", "dev": true, "dependencies": { - "@sentry/types": "7.119.1" + "@sentry/types": "7.119.2" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/node": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.119.1.tgz", - "integrity": "sha512-rpnoQCMxWh/ccjOe+qsmvXAdlTxQHXEWdaltSxnwj7QY+kOGKGP18WTQFLq/gdOBRw9aa6PEQGwhnLfhBXXaYg==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.119.2.tgz", + "integrity": "sha512-TPNnqxh+Myooe4jTyRiXrzrM2SH08R4+nrmBls4T7lKp2E5R/3mDSe/YTn5rRcUt1k1hPx1NgO/taG0DoS5cXA==", "dev": true, "dependencies": { - "@sentry-internal/tracing": "7.119.1", - "@sentry/core": "7.119.1", - "@sentry/integrations": "7.119.1", - "@sentry/types": "7.119.1", - "@sentry/utils": "7.119.1" + "@sentry-internal/tracing": "7.119.2", + "@sentry/core": "7.119.2", + "@sentry/integrations": "7.119.2", + "@sentry/types": "7.119.2", + "@sentry/utils": "7.119.2" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/node/node_modules/@sentry/core": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.119.1.tgz", - "integrity": "sha512-YUNnH7O7paVd+UmpArWCPH4Phlb5LwrkWVqzFWqL3xPyCcTSof2RL8UmvpkTjgYJjJ+NDfq5mPFkqv3aOEn5Sw==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.119.2.tgz", + "integrity": "sha512-hQr3d2yWq/2lMvoyBPOwXw1IHqTrCjOsU1vYKhAa6w9vGbJZFGhKGGE2KEi/92c3gqGn+gW/PC7cV6waCTDuVA==", "dev": true, "dependencies": { - "@sentry/types": "7.119.1", - "@sentry/utils": "7.119.1" + "@sentry/types": "7.119.2", + "@sentry/utils": "7.119.2" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/node/node_modules/@sentry/types": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.119.1.tgz", - "integrity": "sha512-4G2mcZNnYzK3pa2PuTq+M2GcwBRY/yy1rF+HfZU+LAPZr98nzq2X3+mJHNJoobeHRkvVh7YZMPi4ogXiIS5VNQ==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.119.2.tgz", + "integrity": "sha512-ydq1tWsdG7QW+yFaTp0gFaowMLNVikIqM70wxWNK+u98QzKnVY/3XTixxNLsUtnAB4Y+isAzFhrc6Vb5GFdFeg==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/@sentry/node/node_modules/@sentry/utils": { - "version": "7.119.1", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.119.1.tgz", - "integrity": "sha512-ju/Cvyeu/vkfC5/XBV30UNet5kLEicZmXSyuLwZu95hEbL+foPdxN+re7pCI/eNqfe3B2vz7lvz5afLVOlQ2Hg==", + "version": "7.119.2", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.119.2.tgz", + "integrity": "sha512-TLdUCvcNgzKP0r9YD7tgCL1PEUp42TObISridsPJ5rhpVGQJvpr+Six0zIkfDUxerLYWZoK8QMm9KgFlPLNQzA==", "dev": true, "dependencies": { - "@sentry/types": "7.119.1" + "@sentry/types": "7.119.2" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/types": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.33.1.tgz", - "integrity": "sha512-GjoAMvwtpIemoF/IiwZ7A60g4nQv3qwzR21GvJqDVUoKD0e8pv9OLX+HyXoUat4wEDGSuDUcUyUKD2G+od73QA==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.34.0.tgz", + "integrity": "sha512-zLRc60CzohGCo6zNsNeQ9JF3SiEeRE4aDCP9fDDdIVCOKovS+mn1rtSip0qd0Vp2fidOu0+2yY0ALCz1A3PJSQ==", "engines": { "node": ">=14.18" } }, "node_modules/@sentry/utils": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.33.1.tgz", - "integrity": "sha512-uzuYpiiJuFY3N4WNHMBWUQX5oNv2t/TbG0OHRp3Rr7yeu+HSfD542TIp9/gMZ+G0Cxd8AmVO3wkKIFbk0TL4Qg==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.34.0.tgz", + "integrity": "sha512-W1KoRlFUjprlh3t86DZPFxLfM6mzjRzshVfMY7vRlJFymBelJsnJ3A1lPeBZM9nCraOSiw6GtOWu6k5BAkiGIg==", "dependencies": { - "@sentry/types": "8.33.1" + "@sentry/types": "8.34.0" }, "engines": { "node": ">=14.18" @@ -4196,14 +4065,14 @@ } }, "node_modules/@swc/core": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.26.tgz", - "integrity": "sha512-f5uYFf+TmMQyYIoxkn/evWhNGuUzC730dFwAKGwBVHHVoPyak1/GvJUm6i1SKl+2Hrj9oN0i3WSoWWZ4pgI8lw==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.36.tgz", + "integrity": "sha512-bu7ymMX+LCJOSSrKank25Jaq66ymLVA9fOUuy4ck3/6rbXdLw+pIJPnIDKQ9uNcxww8KDxOuJk9Ui9pqR+aGFw==", "dev": true, "hasInstallScript": true, "dependencies": { "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.12" + "@swc/types": "^0.1.13" }, "engines": { "node": ">=10" @@ -4213,16 +4082,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.7.26", - "@swc/core-darwin-x64": "1.7.26", - "@swc/core-linux-arm-gnueabihf": "1.7.26", - "@swc/core-linux-arm64-gnu": "1.7.26", - "@swc/core-linux-arm64-musl": "1.7.26", - "@swc/core-linux-x64-gnu": "1.7.26", - "@swc/core-linux-x64-musl": "1.7.26", - "@swc/core-win32-arm64-msvc": "1.7.26", - "@swc/core-win32-ia32-msvc": "1.7.26", - "@swc/core-win32-x64-msvc": "1.7.26" + "@swc/core-darwin-arm64": "1.7.36", + "@swc/core-darwin-x64": "1.7.36", + "@swc/core-linux-arm-gnueabihf": "1.7.36", + "@swc/core-linux-arm64-gnu": "1.7.36", + "@swc/core-linux-arm64-musl": "1.7.36", + "@swc/core-linux-x64-gnu": "1.7.36", + "@swc/core-linux-x64-musl": "1.7.36", + "@swc/core-win32-arm64-msvc": "1.7.36", + "@swc/core-win32-ia32-msvc": "1.7.36", + "@swc/core-win32-x64-msvc": "1.7.36" }, "peerDependencies": { "@swc/helpers": "*" @@ -4234,9 +4103,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.26.tgz", - "integrity": "sha512-FF3CRYTg6a7ZVW4yT9mesxoVVZTrcSWtmZhxKCYJX9brH4CS/7PRPjAKNk6kzWgWuRoglP7hkjQcd6EpMcZEAw==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.36.tgz", + "integrity": "sha512-8vDczXzCgv3ceTPhEivlpGprN44YlrCK1nbfU9g2TrhV/Aiqi09W/eM5zLesdoM1Z3mJl492gc/8nlTkpDdusw==", "cpu": [ "arm64" ], @@ -4250,9 +4119,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.26.tgz", - "integrity": "sha512-az3cibZdsay2HNKmc4bjf62QVukuiMRh5sfM5kHR/JMTrLyS6vSw7Ihs3UTkZjUxkLTT8ro54LI6sV6sUQUbLQ==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.36.tgz", + "integrity": "sha512-Pa2Gao7+Wf5m3SsK4abKRtd48AtoUnJInvaC3d077swBfgZjbjUbQvcpdc2dOeQtWwo49rFqUZJonMsL0jnPgQ==", "cpu": [ "x64" ], @@ -4266,9 +4135,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.26.tgz", - "integrity": "sha512-VYPFVJDO5zT5U3RpCdHE5v1gz4mmR8BfHecUZTmD2v1JeFY6fv9KArJUpjrHEEsjK/ucXkQFmJ0jaiWXmpOV9Q==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.36.tgz", + "integrity": "sha512-3YsMWd7V+WZEjbfBnLkkz/olcRBa8nyoK0iIOnNARJBMcYaJxjkJSMZpmSojCnIVwvjA1N83CPAbUL+W+fCnHg==", "cpu": [ "arm" ], @@ -4282,9 +4151,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.26.tgz", - "integrity": "sha512-YKevOV7abpjcAzXrhsl+W48Z9mZvgoVs2eP5nY+uoMAdP2b3GxC0Df1Co0I90o2lkzO4jYBpTMcZlmUXLdXn+Q==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.36.tgz", + "integrity": "sha512-lqM3aBB7kJazJYOwHeA5OGNLqXoQPZ/76b3dV+XcjN1GhD0CcXz6mW5PRYVin6OSN1eKrKBKJjtDA1mqADDEvw==", "cpu": [ "arm64" ], @@ -4298,9 +4167,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.26.tgz", - "integrity": "sha512-3w8iZICMkQQON0uIcvz7+Q1MPOW6hJ4O5ETjA0LSP/tuKqx30hIniCGOgPDnv3UTMruLUnQbtBwVCZTBKR3Rkg==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.36.tgz", + "integrity": "sha512-bqei2YDzvUfG0pth5W2xJaj0eG4XWYk0d/NJ75vBX6bkIzK6dC8iuKQ41jOfUWonnrAs7rTDDJW0sTn/evvRdw==", "cpu": [ "arm64" ], @@ -4314,9 +4183,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.26.tgz", - "integrity": "sha512-c+pp9Zkk2lqb06bNGkR2Looxrs7FtGDMA4/aHjZcCqATgp348hOKH5WPvNLBl+yPrISuWjbKDVn3NgAvfvpH4w==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.36.tgz", + "integrity": "sha512-03maXTUyaBjeCxlDltmdzHje1ryQt1C4OWmmNgSSRXjLb+GNnAenwOJMSrcvHP/aNClD2pwsFCnYKDGy+sYE6w==", "cpu": [ "x64" ], @@ -4330,9 +4199,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.26.tgz", - "integrity": "sha512-PgtyfHBF6xG87dUSSdTJHwZ3/8vWZfNIXQV2GlwEpslrOkGqy+WaiiyE7Of7z9AvDILfBBBcJvJ/r8u980wAfQ==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.36.tgz", + "integrity": "sha512-XXysqLkvjtQnXm1zHqLhy00UYPv/gk5OtwR732X+piNisnEbcJBqI8Qp9O7YvLWllRcoP8IMBGDWLGdGLSpViA==", "cpu": [ "x64" ], @@ -4346,9 +4215,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.26.tgz", - "integrity": "sha512-9TNXPIJqFynlAOrRD6tUQjMq7KApSklK3R/tXgIxc7Qx+lWu8hlDQ/kVPLpU7PWvMMwC/3hKBW+p5f+Tms1hmA==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.36.tgz", + "integrity": "sha512-k7+dmb13a/zPw+E4XYfPmLZFWJgcOcBRKIjYl9nQErtYsgsg3Ji6TBbsvJVETy23lNHyewZ17V5Vq6NzaG0hzg==", "cpu": [ "arm64" ], @@ -4362,9 +4231,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.26.tgz", - "integrity": "sha512-9YngxNcG3177GYdsTum4V98Re+TlCeJEP4kEwEg9EagT5s3YejYdKwVAkAsJszzkXuyRDdnHUpYbTrPG6FiXrQ==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.36.tgz", + "integrity": "sha512-ridD3ay6YM2PEYHZXXFN+edYEv0FOynaqOBP+NSnGNHA35azItIjoIe+KNi4WltGtAjpKCHSpjGCNfna12wdYQ==", "cpu": [ "ia32" ], @@ -4378,9 +4247,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.7.26", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.26.tgz", - "integrity": "sha512-VR+hzg9XqucgLjXxA13MtV5O3C0bK0ywtLIBw/+a+O+Oc6mxFWHtdUeXDbIi5AiPbn0fjgVJMqYnyjGyyX8u0w==", + "version": "1.7.36", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.36.tgz", + "integrity": "sha512-j1z2Z1Ln9d0E3dHsPkC1K9XDh0ojhRPwV+GfRTu4D61PE+aYhYLvbJC6xPvL4/204QrStRS7eDu3m+BcDp3rgQ==", "cpu": [ "x64" ], @@ -4408,9 +4277,9 @@ } }, "node_modules/@swc/types": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.12.tgz", - "integrity": "sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.13.tgz", + "integrity": "sha512-JL7eeCk6zWCbiYQg2xQSdLXQJl8Qoc9rXmG2cEKvHe3CKwMHwHGpfOb8frzNLmbycOo6I51qxnLnn9ESf4I20Q==", "dev": true, "dependencies": { "@swc/counter": "^0.1.3" @@ -4504,9 +4373,9 @@ } }, "node_modules/@types/dom-webcodecs": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.12.tgz", - "integrity": "sha512-vEkwKEr0xAO2xwNNkYhaltT7jMGjrgAbfpRR3qKRN7eW3B7R7O5fm1scx2OKBY6wMACgjCewhu+ljbCdudY+5A==" + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.13.tgz", + "integrity": "sha512-O5hkiFIcjjszPIYyUSyvScyvrBoV3NOEEZx/pMlsu44TKzWNkLVBBxnxJz42in5n3QIolYOcBYFCPZZ0h8SkwQ==" }, "node_modules/@types/emscripten": { "version": "1.39.13", @@ -4634,9 +4503,9 @@ } }, "node_modules/@types/react": { - "version": "18.3.2", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.2.tgz", - "integrity": "sha512-Btgg89dAnqD4vV7R3hlwOxgqobUQKgx3MmrQRi0yYbs/P0ym8XozIAlkqVilPqHQwXs4e9Tf63rrCgl58BcO4w==", + "version": "18.3.11", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.11.tgz", + "integrity": "sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -4661,9 +4530,9 @@ } }, "node_modules/@types/react-dom": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", - "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", "devOptional": true, "dependencies": { "@types/react": "*" @@ -4938,39 +4807,39 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.11.tgz", - "integrity": "sha512-PwAdxs7/9Hc3ieBO12tXzmTD+Ln4qhT/56S+8DvrrZ4kLDn4Z/AMUr8tXJD0axiJBS0RKIoNaR0yMuQB9v9Udg==", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.12.tgz", + "integrity": "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw==", "dev": true, "dependencies": { "@babel/parser": "^7.25.3", - "@vue/shared": "3.5.11", + "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.11.tgz", - "integrity": "sha512-pyGf8zdbDDRkBrEzf8p7BQlMKNNF5Fk/Cf/fQ6PiUz9at4OaUfyXW0dGJTo2Vl1f5U9jSLCNf0EZJEogLXoeew==", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.12.tgz", + "integrity": "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg==", "dev": true, "dependencies": { - "@vue/compiler-core": "3.5.11", - "@vue/shared": "3.5.11" + "@vue/compiler-core": "3.5.12", + "@vue/shared": "3.5.12" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.11.tgz", - "integrity": "sha512-gsbBtT4N9ANXXepprle+X9YLg2htQk1sqH/qGJ/EApl+dgpUBdTv3yP7YlR535uHZY3n6XaR0/bKo0BgwwDniw==", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.12.tgz", + "integrity": "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw==", "dev": true, "dependencies": { "@babel/parser": "^7.25.3", - "@vue/compiler-core": "3.5.11", - "@vue/compiler-dom": "3.5.11", - "@vue/compiler-ssr": "3.5.11", - "@vue/shared": "3.5.11", + "@vue/compiler-core": "3.5.12", + "@vue/compiler-dom": "3.5.12", + "@vue/compiler-ssr": "3.5.12", + "@vue/shared": "3.5.12", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", "postcss": "^8.4.47", @@ -4978,19 +4847,19 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.11.tgz", - "integrity": "sha512-P4+GPjOuC2aFTk1Z4WANvEhyOykcvEd5bIj2KVNGKGfM745LaXGr++5njpdBTzVz5pZifdlR1kpYSJJpIlSePA==", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.12.tgz", + "integrity": "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA==", "dev": true, "dependencies": { - "@vue/compiler-dom": "3.5.11", - "@vue/shared": "3.5.11" + "@vue/compiler-dom": "3.5.12", + "@vue/shared": "3.5.12" } }, "node_modules/@vue/shared": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.11.tgz", - "integrity": "sha512-W8GgysJVnFo81FthhzurdRAWP/byq3q2qIw70e0JWblzVhjgOMiC2GyovXrZTFQJnFVryYaKGP3Tc9vYzYm6PQ==", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.12.tgz", + "integrity": "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg==", "dev": true }, "node_modules/@webassemblyjs/ast": { @@ -5171,9 +5040,9 @@ "optional": true }, "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", + "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", "bin": { "acorn": "bin/acorn" }, @@ -5731,11 +5600,11 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/barcode-detector": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/barcode-detector/-/barcode-detector-2.2.10.tgz", - "integrity": "sha512-fB6285Ahd6PIbru+PRw/CL+T1+dtPQmfCwBAwHmw+IWLLHrKH0q37qlAEHXWxPNM6bEmxgTMgGO+MJu/Si1uJQ==", + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/barcode-detector/-/barcode-detector-2.2.11.tgz", + "integrity": "sha512-N50XZ6Rav2sxTgHXOc38/mkpVJMan11GZ8Yqi1pPMZpTJSXuZ/FpIee6OtLehZX/Vs4ZOzGbp1DgXzFCfKggWA==", "dependencies": { - "@types/dom-webcodecs": "^0.1.12", + "@types/dom-webcodecs": "^0.1.13", "zxing-wasm": "1.2.14" } }, @@ -5961,9 +5830,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001667", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz", - "integrity": "sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==", + "version": "1.0.30001669", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz", + "integrity": "sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==", "funding": [ { "type": "opencollective", @@ -5994,6 +5863,10 @@ "node": ">=6" } }, + "node_modules/care-livekit": { + "resolved": "apps/care_livekit_fe", + "link": true + }, "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -6499,12 +6372,12 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/cypress": { - "version": "13.14.2", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.14.2.tgz", - "integrity": "sha512-lsiQrN17vHMB2fnvxIrKLAjOr9bPwsNbPZNrWf99s4u+DVmCY6U+w7O3GGG9FvP4EUVYaDu+guWeNLiUzBrqvA==", + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.15.0.tgz", + "integrity": "sha512-53aO7PwOfi604qzOkCSzNlWquCynLlKE/rmmpSPcziRH6LNfaDUAklQT6WJIsD8ywxlIy+uVZsnTMCCQVd2kTw==", "hasInstallScript": true, "dependencies": { - "@cypress/request": "^3.0.1", + "@cypress/request": "^3.0.4", "@cypress/xvfb": "^1.2.4", "@types/sinonjs__fake-timers": "8.1.1", "@types/sizzle": "^2.3.2", @@ -6567,9 +6440,9 @@ } }, "node_modules/cypress-split": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/cypress-split/-/cypress-split-1.24.0.tgz", - "integrity": "sha512-ZEFh1m6z+HwPWpB1h9YAF1L6K/wkPBR3vD+v8Rrg8BRm50sZ7oSx6Dw+sv6zfr5Pfqv247CnobLewdFBLlPIBQ==", + "version": "1.24.4", + "resolved": "https://registry.npmjs.org/cypress-split/-/cypress-split-1.24.4.tgz", + "integrity": "sha512-sKBFQB659Ss5B08GSESeMKXBEpPD2wKNGQR1HYbKT98rnM1x5E+MugzcicqEdsK4T2Ng0feuuZQkz8XniOA18A==", "dev": true, "dependencies": { "@actions/core": "^1.10.0", @@ -6577,7 +6450,7 @@ "console.table": "^0.10.0", "debug": "^4.3.4", "fast-shuffle": "^6.1.0", - "find-cypress-specs": "1.43.4", + "find-cypress-specs": "1.45.2", "globby": "^11.1.0", "humanize-duration": "^3.28.0" }, @@ -7051,6 +6924,18 @@ "node": ">=6.0.0" } }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -7119,9 +7004,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.33", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.33.tgz", - "integrity": "sha512-+cYTcFB1QqD4j4LegwLfpCNxifb6dDFUAwk6RsLusCwIaZI6or2f+q8rs5tTB2YC53HhOlIbEaqHMAAC8IOIwA==" + "version": "1.5.39", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.39.tgz", + "integrity": "sha512-4xkpSR6CjuiaNyvwiWDI85N9AxsvbPawB8xc7yzLPonYTuP19BVgYweKyUMFtHEZgIcHWMt1ks5Cqx2m+6/Grg==" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -7286,9 +7171,9 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", - "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.1.0.tgz", + "integrity": "sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==", "dev": true, "dependencies": { "call-bind": "^1.0.7", @@ -7298,12 +7183,12 @@ "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", + "globalthis": "^1.0.4", "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.3", "has-symbols": "^1.0.3", "internal-slot": "^1.0.7", - "iterator.prototype": "^1.1.2", + "iterator.prototype": "^1.1.3", "safe-array-concat": "^1.1.2" }, "engines": { @@ -8024,9 +7909,9 @@ } }, "node_modules/fast-uri": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.2.tgz", - "integrity": "sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", "dev": true }, "node_modules/fastq": { @@ -8164,16 +8049,16 @@ } }, "node_modules/find-cypress-specs": { - "version": "1.43.4", - "resolved": "https://registry.npmjs.org/find-cypress-specs/-/find-cypress-specs-1.43.4.tgz", - "integrity": "sha512-GAdz6lfBndbOq9OOJ3psThQ56hqgL8tZUCOLnl60d/l56bvHkC0TNwyqlLfBObiscirSZWSgyGL86jJkrpFMrA==", + "version": "1.45.2", + "resolved": "https://registry.npmjs.org/find-cypress-specs/-/find-cypress-specs-1.45.2.tgz", + "integrity": "sha512-D289NM0Dpqoz4+yl8oEtbioqm7zPKQo0hLcvwlg5Z9iBm7EioMIFiOYgluthDNPxUES/aJF+1xHRHAJpC3ejcA==", "dev": true, "dependencies": { "@actions/core": "^1.10.0", "arg": "^5.0.1", "console.table": "^0.10.0", "debug": "^4.3.3", - "find-test-names": "1.28.18", + "find-test-names": "1.28.30", "globby": "^11.1.0", "minimatch": "^3.0.4", "pluralize": "^8.0.0", @@ -8212,13 +8097,13 @@ } }, "node_modules/find-test-names": { - "version": "1.28.18", - "resolved": "https://registry.npmjs.org/find-test-names/-/find-test-names-1.28.18.tgz", - "integrity": "sha512-hhnGdkWK+qEA5Z02Tu0OqGQIUjFZNyOCE4WaJpbhW4hAF1+NZ7OCr0Bss9RCaj7BBtjoIjkU93utobQ8pg2iVg==", + "version": "1.28.30", + "resolved": "https://registry.npmjs.org/find-test-names/-/find-test-names-1.28.30.tgz", + "integrity": "sha512-b5PLJ5WnskdaYHBf+38FN/4TKh5lqwrltITkqxuARsN2bW6civrhqOXbVA+4727YNowYLt/jtIC9Dsn7eJSP6A==", "dev": true, "dependencies": { - "@babel/parser": "^7.23.0", - "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/parser": "^7.24.7", + "@babel/plugin-syntax-jsx": "^7.24.7", "acorn-walk": "^8.2.0", "debug": "^4.3.3", "globby": "^11.0.4", @@ -8332,9 +8217,9 @@ } }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -9178,9 +9063,9 @@ } }, "node_modules/i18next": { - "version": "23.15.2", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.15.2.tgz", - "integrity": "sha512-zcPSWzCvw6uKnuYHIqs4W7hTuB9e3AFcSdZgvCWoPXIZsBjBd4djN2/2uOHIB+1DFFkQnMBXvhNg7J3WyCuywQ==", + "version": "23.16.0", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.16.0.tgz", + "integrity": "sha512-Ni3CG6c14teOogY19YNRl+kYaE/Rb59khy0VyHVn4uOZ97E2E/Yziyi6r3C3s9+wacjdLZiq/LLYyx+Cgd+FCw==", "funding": [ { "type": "individual", @@ -9922,9 +9807,9 @@ "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" }, "node_modules/iterator.prototype": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", - "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.3.tgz", + "integrity": "sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==", "dev": true, "dependencies": { "define-properties": "^1.2.1", @@ -9932,6 +9817,9 @@ "has-symbols": "^1.0.3", "reflect.getprototypeof": "^1.0.4", "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/jackspeak": { @@ -10691,6 +10579,26 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/livekit-client": { + "version": "2.5.9", + "resolved": "https://registry.npmjs.org/livekit-client/-/livekit-client-2.5.9.tgz", + "integrity": "sha512-oDpK6SKYB1F+mNO+25DA0bF0cD2XoOJeD8ji4YQpzDBQv2IxeyKrQhoqXAqrYgIKuiMNkImSf+yg2v7EHSl4Og==", + "dependencies": { + "@livekit/protocol": "1.24.0", + "events": "^3.3.0", + "loglevel": "^1.8.0", + "sdp-transform": "^2.14.1", + "ts-debounce": "^4.0.0", + "tslib": "2.7.0", + "typed-emitter": "^2.1.0", + "webrtc-adapter": "^9.0.0" + } + }, + "node_modules/livekit-client/node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + }, "node_modules/load-plugin": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-6.0.3.tgz", @@ -10791,8 +10699,7 @@ "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, "node_modules/lodash.isplainobject": { "version": "4.0.6", @@ -10878,6 +10785,18 @@ "node": ">=8" } }, + "node_modules/loglevel": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.1.tgz", + "integrity": "sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, "node_modules/long": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", @@ -10915,9 +10834,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", + "version": "0.30.12", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" @@ -12823,9 +12742,9 @@ } }, "node_modules/nan": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", - "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==", + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz", + "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==", "optional": true }, "node_modules/nanoid": { @@ -13572,9 +13491,9 @@ } }, "node_modules/postcss-load-config/node_modules/yaml": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", - "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", + "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", "bin": { "yaml": "bin.mjs" }, @@ -14066,9 +13985,9 @@ } }, "node_modules/react-i18next": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.0.2.tgz", - "integrity": "sha512-z0W3/RES9Idv3MmJUcf0mDNeeMOUXe+xoL0kPfQPbDoZHmni/XsIoq5zgT2MCFUiau283GuBUK578uD/mkAbLQ==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.0.3.tgz", + "integrity": "sha512-BlO1P+oLKjjIxDBQ0GkAIMacgjfMbnvops+3Y5nZXF7UJ99v4KCWr0Na1azJXC8AMiNWp4kgUcFCJM7U9ZsUDg==", "dependencies": { "@babel/runtime": "^7.25.0", "html-parse-stringify": "^3.0.1" @@ -15762,6 +15681,14 @@ "resolved": "https://registry.npmjs.org/sdp/-/sdp-3.2.0.tgz", "integrity": "sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw==" }, + "node_modules/sdp-transform": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-2.14.2.tgz", + "integrity": "sha512-icY6jVao7MfKCieyo1AyxFYm1baiM+fA00qW/KrNNVlkxHAd34riEKuEkUe4bBb3gJwLJZM+xT60Yj1QL8rHiA==", + "bin": { + "sdp-verify": "checker.js" + } + }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -16585,18 +16512,18 @@ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" }, "node_modules/tailwind-merge": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.3.tgz", - "integrity": "sha512-d9ZolCAIzom1nf/5p4LdD5zvjmgSxY0BGgdSvmXIoMYAiPdAW/dSpP7joCDYFY7r/HkEa2qmPtkgsu0xjQeQtw==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.4.tgz", + "integrity": "sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q==", "funding": { "type": "github", "url": "https://github.com/sponsors/dcastil" } }, "node_modules/tailwindcss": { - "version": "3.4.13", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.13.tgz", - "integrity": "sha512-KqjHOJKogOUt5Bs752ykCeiwvi0fKVkr5oqsFNt/8px/tA8scFPIlkygsf6jXrfCqGHz7VflA6+yytWuM+XhFw==", + "version": "3.4.14", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", + "integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -16982,6 +16909,11 @@ "typescript": ">=4.2.0" } }, + "node_modules/ts-debounce": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ts-debounce/-/ts-debounce-4.0.0.tgz", + "integrity": "sha512-+1iDGY6NmOGidq7i7xZGA4cm8DAa6fqdYcvO5Z6yBevH++Bdo9Qt/mN0TzHUgcCcKv1gmh9+W5dHqz8pMWbCbg==" + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", @@ -17002,9 +16934,9 @@ } }, "node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==" }, "node_modules/tsx": { "version": "4.19.1", @@ -17149,6 +17081,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typed-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/typed-emitter/-/typed-emitter-2.1.0.tgz", + "integrity": "sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA==", + "optionalDependencies": { + "rxjs": "*" + } + }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -17156,9 +17096,9 @@ "dev": true }, "node_modules/typescript": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", - "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "devOptional": true, "bin": { "tsc": "bin/tsc", @@ -17642,6 +17582,20 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/usehooks-ts": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/usehooks-ts/-/usehooks-ts-3.1.0.tgz", + "integrity": "sha512-bBIa7yUyPhE1BCc0GmR96VU/15l/9gP1Ch5mYdLcFBaFGQsdmXkvjV0TtOqW1yUd6VjIwDunm+flSciCQXujiw==", + "dependencies": { + "lodash.debounce": "^4.0.8" + }, + "engines": { + "node": ">=16.15.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -17937,9 +17891,9 @@ } }, "node_modules/vite": { - "version": "5.4.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", - "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", + "version": "5.4.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.9.tgz", + "integrity": "sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==", "dev": true, "dependencies": { "esbuild": "^0.21.3", diff --git a/package.json b/package.json index 850bba2edae..7749374be44 100644 --- a/package.json +++ b/package.json @@ -26,12 +26,19 @@ ], "author": "Open Healthcare Network Contributors", "license": "MIT", + "workspaces": [ + "apps/*" + ], "scripts": { - "build:react": "cross-env NODE_ENV=production vite build", - "build": "npm run generate-build-meta && npm run supported-browsers && npm run build:react", "dev": "npm run supported-browsers && vite", + "local": "npm run supported-browsers && vite --mode docker", "preview": "cross-env NODE_ENV=production vite preview", - "generate-build-meta": "node ./scripts/generate-build-version.js", + "build:meta": "node ./scripts/generate-build-version.js", + "build:react": "cross-env NODE_ENV=production vite build", + "supported-browsers": "node ./scripts/generate-supported-browsers.mjs", + "build": "npm run install-all && npm run build:meta && npm run supported-browsers && npm run build:react", + "setup": "node scripts/setup-care-apps.js", + "install-all": "npm install && npm run setup && npm install", "test": "snyk test", "cypress:open": "cross-env NODE_ENV=development cypress open", "cypress:run": "cross-env NODE_ENV=development cypress run", @@ -40,8 +47,7 @@ "prepare": "husky install", "lint": "eslint ./src", "lint-fix": "eslint ./src --fix", - "format": "prettier ./src --write", - "supported-browsers": "node ./scripts/generate-supported-browsers.mjs" + "format": "prettier ./src --write" }, "dependencies": { "@fontsource/figtree": "^5.1.0", @@ -55,7 +61,7 @@ "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-toast": "^1.2.2", "@sentry/browser": "^8.33.0", - "@yudiel/react-qr-scanner": "^2.0.0-beta.3", + "@yudiel/react-qr-scanner": "^2.0.8", "axios": "^1.7.7", "bowser": "^2.11.0", "browser-image-compression": "^2.0.2", @@ -103,7 +109,7 @@ "@types/lodash-es": "^4.17.12", "@types/node": "^22.7.4", "@types/qrcode.react": "^1.0.5", - "@types/react": "18.3.2", + "@types/react": "^18.3.11", "@types/react-copy-to-clipboard": "^5.0.7", "@types/react-csv": "^1.1.10", "@types/react-dom": "^18.3.0", @@ -114,6 +120,7 @@ "autoprefixer": "^10.4.19", "cypress-localstorage-commands": "^2.2.5", "cypress-split": "^1.23.2", + "dotenv": "^16.4.5", "eslint-config-prettier": "^9.1.0", "eslint-plugin-i18next": "^6.0.9", "eslint-plugin-mdx": "^3.1.5", diff --git a/scripts/setup-care-apps.js b/scripts/setup-care-apps.js new file mode 100644 index 00000000000..4106775e63e --- /dev/null +++ b/scripts/setup-care-apps.js @@ -0,0 +1,113 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires +const { execSync } = require("child_process"); +// eslint-disable-next-line @typescript-eslint/no-var-requires +const fs = require("fs"); +// eslint-disable-next-line @typescript-eslint/no-var-requires +const path = require("path"); +// eslint-disable-next-line @typescript-eslint/no-var-requires +require("dotenv").config({ path: [".env.local", ".env"] }); + +console.log("Preinstall script running"); + +// Function to read apps.json or return an empty array if it doesn't exist +function readAppsConfig() { + const appsConfig = process.env.REACT_ENABLED_APPS + ? process.env.REACT_ENABLED_APPS.split(",").map((app) => ({ + branch: app.split("@")[1], + package: app.split("@")[0], + })) + : []; + console.log("Found apps: ", appsConfig); + return appsConfig; +} + +const appsConfig = readAppsConfig(); +const appsDir = path.join(__dirname, "..", "apps"); + +// Create apps directory if it doesn't exist +if (!fs.existsSync(appsDir)) { + fs.mkdirSync(appsDir); +} + +const installApp = (app) => { + const appDir = path.join(appsDir, app.package.split("/")[1]); + + console.log(`Cloning ${app.package}...`); + execSync( + `npx -y gitget ${app.package}${app.branch ? `#${app.branch}` : ""} apps/${app.package.split("/")[1]} `, + { + stdio: "inherit", + }, + ); + // Create a care-package.lock file + fs.writeFileSync( + path.join(appDir, "care-package.lock"), + JSON.stringify( + { + package: app.package, + branch: app.branch, + }, + null, + 2, + ), + ); +}; + +// Clone or pull care apps +appsConfig.forEach((app) => { + const appDir = path.join(appsDir, app.package.split("/")[1]); + if (fs.existsSync(appDir)) { + if (fs.existsSync(path.join(appDir, "care-package.lock"))) { + // verify if the branch and package match with the care-package.lock file + const lockFile = JSON.parse( + fs.readFileSync(path.join(appDir, "care-package.lock"), "utf8"), + ); + if (lockFile.package === app.package && lockFile.branch === app.branch) { + console.log(`Package already exists. Pulling latest changes...`); + execSync(`git -C "${appDir}" pull`, { stdio: "inherit" }); + return; + } else { + console.log(`Branch/package does not match. Recreating...`); + fs.rmSync(appDir, { recursive: true, force: true }); + } + } else { + console.log( + `Package already exists but care-package.lock file does not exist. Recreating...`, + ); + fs.rmSync(appDir, { recursive: true, force: true }); + } + } + + installApp(app); +}); + +console.log("All apps have been cloned or updated in apps directory."); + +const importApps = appsConfig.map((app) => ({ + ...app, + camelCaseName: app.package + .split("/")[1] + .replace(/[-_]/g, "") + .replace(/\b\w/g, (char, index) => + index === 0 ? char.toLowerCase() : char.toUpperCase(), + ), +})); + +// Generate pluginMap.ts +const pluginMapPath = path.join(__dirname, "..", "src", "pluginMap.ts"); +const pluginMapContent = `import { PluginManifest } from "./pluginTypes"; + +${importApps + .map( + (app) => + `import ${app.camelCaseName}Manifest from "@app-manifest/${app.package.split("/")[1]}";`, + ) + .join("\n")} + +export const pluginMap: PluginManifest[] = [ +${importApps.map((app) => ` ${app.camelCaseName}Manifest`).join(",\n")} +]; +`; + +fs.writeFileSync(pluginMapPath, pluginMapContent); +console.log("Generated pluginMap.ts"); diff --git a/src/App.tsx b/src/App.tsx index c02982fd6df..180bd92839c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,24 +4,28 @@ import Integrations from "./Integrations"; import Loading from "./Components/Common/Loading"; import HistoryAPIProvider from "./Providers/HistoryAPIProvider"; import AuthUserProvider from "./Providers/AuthUserProvider"; +import PluginEngine from "./PluginEngine"; import { FeatureFlagsProvider } from "./Utils/featureFlags"; import { Toaster } from "./Components/ui/toaster"; const App = () => { return ( }> - - }> - - - - + + + + }> + + + + - {/* Integrations */} - - - - + {/* Integrations */} + + + + + ); }; diff --git a/src/CAREUI/display/Timeline.tsx b/src/CAREUI/display/Timeline.tsx index ee21b337724..6701d9a7511 100644 --- a/src/CAREUI/display/Timeline.tsx +++ b/src/CAREUI/display/Timeline.tsx @@ -55,7 +55,7 @@ export const TimelineNode = (props: TimelineNodeProps) => { const { t } = useTranslation(); return ( -
  • +
    { {props.children}
    -
  • + ); }; diff --git a/src/CAREUI/icons/CareIcon.tsx b/src/CAREUI/icons/CareIcon.tsx index 3bb67629bc2..a45117cc675 100644 --- a/src/CAREUI/icons/CareIcon.tsx +++ b/src/CAREUI/icons/CareIcon.tsx @@ -1,13 +1,12 @@ import iconData from "./UniconPaths.json"; -import { transformIcons } from "./icon"; -import { useEffect } from "react"; +import "./icon.css"; export type IconName = keyof typeof iconData; export interface CareIconProps { icon: IconName; - className?: string | undefined; - onClick?: React.MouseEventHandler | undefined; + className?: string; + onClick?: React.MouseEventHandler; id?: string; } @@ -25,14 +24,32 @@ export default function CareIcon({ className, onClick, }: CareIconProps) { - const effectiveClassName = icon - ? `care-${icon} ${className ?? ""}` - : className; + // TODO: fill & strokeWidth are defined for only one icon + // Rethink Implementation + const [viewBox, path, fill, strokeWidth] = iconData[icon] as [ + number, + string, + boolean | undefined, + number | undefined, + ]; + + const svgClassName = `care-svg-icon__baseline ${className || ""}`.trim(); - useEffect(() => transformIcons(), [effectiveClassName]); return ( - - - + + + ); } diff --git a/src/CAREUI/icons/icon.js b/src/CAREUI/icons/icon.js deleted file mode 100644 index c917e664351..00000000000 --- a/src/CAREUI/icons/icon.js +++ /dev/null @@ -1,49 +0,0 @@ -import "./icon.css"; -import iconData from "./UniconPaths.json"; - -const xmlns = "http://www.w3.org/2000/svg"; - -const findIconName = (className) => { - const iconName = className.match(/care-([a-zA-Z0-9-]+)/); - return iconName ? iconName[1] : "default"; -}; - -const getIconData = (className) => { - const data = iconData[findIconName(className)]; - return typeof data === "undefined" ? iconData["default"] : data; -}; - -const createSvg = (className) => { - const icon = getIconData(className); - const el = document.createElementNS(xmlns, "svg"); - el.setAttribute( - "class", - className.replace("care", "care-svg-icon__baseline"), - ); - el.setAttribute("role", "img"); - el.setAttribute("xmlns", xmlns); - el.setAttribute("viewBox", `0 0 ${icon[0]} ${icon[0]}`); - - const path = document.createElementNS(xmlns, "path"); - if (icon[2] === false) { - path.setAttribute("stroke", "currentColor"); - path.setAttribute("stroke-width", `${icon[3]}`); - } - path.setAttribute("fill", icon[2] === false ? "none" : "currentColor"); - path.setAttribute("d", icon[1]); - el.appendChild(path); - return el; -}; - -export const transformIcons = () => { - const elements = Array.from(document.getElementsByClassName("care")); - elements.forEach((element) => { - if (element.tagName == "I") { - element.parentNode.replaceChild(createSvg(element.className), element); - } - }); -}; - -export const addListener = () => { - window.addEventListener("load", transformIcons); -}; diff --git a/src/CAREUI/interactive/LegendInput.tsx b/src/CAREUI/interactive/LegendInput.tsx index e164e4d1b4e..83486095f7a 100644 --- a/src/CAREUI/interactive/LegendInput.tsx +++ b/src/CAREUI/interactive/LegendInput.tsx @@ -2,6 +2,7 @@ import CareIcon from "../icons/CareIcon"; import { classNames } from "../../Utils/utils"; import { RefObject, useRef, useState, useEffect } from "react"; import { useTranslation } from "react-i18next"; + type InputProps = { id?: string; name: string; @@ -12,12 +13,12 @@ type InputProps = { required?: boolean; placeholder?: string; value?: string; - onChange?: (e: any) => void; - onFocus?: (e: any) => void; - onBlur?: (e: any) => void; - onKeyUp?: (e: any) => void; - onKeyDown?: (e: any) => void; - onKeyPress?: (e: any) => void; + onChange?: (e: React.ChangeEvent) => void; + onFocus?: (e: React.FocusEvent) => void; + onBlur?: (e: React.FocusEvent) => void; + onKeyUp?: (e: React.KeyboardEvent) => void; + onKeyDown?: (e: React.KeyboardEvent) => void; + onKeyPress?: (e: React.KeyboardEvent) => void; disabled?: boolean; error?: string; className?: string; diff --git a/src/Common/hooks/useCareApps.ts b/src/Common/hooks/useCareApps.ts new file mode 100644 index 00000000000..77b5489052e --- /dev/null +++ b/src/Common/hooks/useCareApps.ts @@ -0,0 +1,35 @@ +import { createContext, useContext } from "react"; +import { INavItem } from "@/Components/Common/Sidebar/Sidebar"; +import { PluginManifest } from "@/pluginTypes"; + +export const CareAppsContext = createContext([]); + +export const useCareApps = () => { + const ctx = useContext(CareAppsContext); + if (!ctx) { + throw new Error( + "'useCareApps' must be used within 'CareAppsProvider' only", + ); + } + return ctx; +}; + +export const useCareAppNavItems = () => { + const careApps = useCareApps(); + const navItems = careApps.reduce((acc, plugin) => { + return [...acc, ...(plugin.navItems || [])]; + }, []); + return navItems; +}; + +// If required; Reduce plugin.routes to a single pluginRoutes object of type Record JSX.Element> +export function usePluginRoutes() { + const careApps = useCareApps(); + const routes = careApps.reduce((acc, plugin) => { + return { ...acc, ...plugin.routes }; + }, {}); + if (!routes) { + throw new Error("'usePluginRoutes' must be used within 'AppRouter' only"); + } + return routes; +} diff --git a/src/Components/CameraFeed/CentralLiveMonitoring/index.tsx b/src/Components/CameraFeed/CentralLiveMonitoring/index.tsx index 3cca4c00ec4..95e3b98c818 100644 --- a/src/Components/CameraFeed/CentralLiveMonitoring/index.tsx +++ b/src/Components/CameraFeed/CentralLiveMonitoring/index.tsx @@ -66,7 +66,7 @@ export default function CentralLiveMonitoring(props: { facilityId: string }) { fullscreen={isFullscreen} onExit={() => setFullscreen(false)} > -
    +
    {data.results.map((asset) => (
    diff --git a/src/Components/Common/ErrorBoundary.tsx b/src/Components/Common/ErrorBoundary.tsx new file mode 100644 index 00000000000..47172a240ef --- /dev/null +++ b/src/Components/Common/ErrorBoundary.tsx @@ -0,0 +1,36 @@ +import React, { Component, ErrorInfo, ReactNode } from "react"; + +interface Props { + children: ReactNode; + fallback?: ReactNode; +} + +interface State { + hasError: boolean; +} + +class ErrorBoundary extends Component { + public state: State = { + hasError: false, + }; + + public static getDerivedStateFromError(_: Error): State { + // Update state so the next render will show the fallback UI. + return { hasError: true }; + } + + public componentDidCatch(error: Error, errorInfo: ErrorInfo) { + console.error("Uncaught error:", error, errorInfo); + } + + public render() { + if (this.state.hasError) { + // You can render any custom fallback UI + return this.props.fallback ||

    Sorry.. there was an error

    ; + } + + return this.props.children; + } +} + +export default ErrorBoundary; diff --git a/src/Components/Common/Sidebar/Sidebar.tsx b/src/Components/Common/Sidebar/Sidebar.tsx index 31efe00f1b1..4e3929b187f 100644 --- a/src/Components/Common/Sidebar/Sidebar.tsx +++ b/src/Components/Common/Sidebar/Sidebar.tsx @@ -8,11 +8,18 @@ import SlideOver from "../../../CAREUI/interactive/SlideOver"; import { classNames } from "../../../Utils/utils"; import { Link } from "raviger"; import careConfig from "@careConfig"; +import { useCareAppNavItems } from "@/Common/hooks/useCareApps"; export const SIDEBAR_SHRINK_PREFERENCE_KEY = "sidebarShrinkPreference"; const LOGO_COLLAPSE = "/images/care_logo_mark.svg"; +export interface INavItem { + text: string; + to?: string; + icon: IconName; +} + type StatelessSidebarProps = | { shrinkable: true; @@ -32,11 +39,7 @@ const StatelessSidebar = ({ setShrinked, onItemClick, }: StatelessSidebarProps) => { - const NavItems: { - text: string; - to: string; - icon: IconName; - }[] = [ + const BaseNavItems: INavItem[] = [ { text: "Facilities", to: "/facility", icon: "l-hospital" }, { text: "Patients", to: "/patients", icon: "l-user-injured" }, { text: "Assets", to: "/assets", icon: "l-shopping-cart-alt" }, @@ -47,6 +50,10 @@ const StatelessSidebar = ({ { text: "Notice Board", to: "/notice_board", icon: "l-meeting-board" }, ]; + const PluginNavItems = useCareAppNavItems(); + + const NavItems = [...BaseNavItems, ...PluginNavItems]; + const activeLink = useActiveLink(); const Item = shrinked ? ShrinkedSidebarItem : SidebarItem; @@ -151,7 +158,7 @@ const StatelessSidebar = ({ {...i} icon={} selected={i.to === activeLink} - do={() => onItemClick && onItemClick(false)} + onItemClick={() => onItemClick && onItemClick(false)} handleOverflow={handleOverflow} /> ); diff --git a/src/Components/Common/Sidebar/SidebarItem.tsx b/src/Components/Common/Sidebar/SidebarItem.tsx index 265119f936e..eeee4284e2f 100644 --- a/src/Components/Common/Sidebar/SidebarItem.tsx +++ b/src/Components/Common/Sidebar/SidebarItem.tsx @@ -10,37 +10,39 @@ type SidebarItemProps = { ref?: React.Ref; text: string; icon: SidebarIcon; + onItemClick?: () => void; external?: true | undefined; badgeCount?: number | undefined; selected?: boolean | undefined; handleOverflow?: any; -} & ({ to: string; do?: undefined } | { to?: string; do: () => void }); +} & ({ to?: string; do?: undefined } | { to?: string; do: () => void }); type SidebarItemBaseProps = SidebarItemProps & { shrinked?: boolean; - ref: Ref; }; -const SidebarItemBase = forwardRef( - ( - { shrinked, external, ...props }: SidebarItemBaseProps, - ref: Ref, - ) => { +const SidebarItemBase = forwardRef( + ({ shrinked, external, ...props }, ref) => { const { t } = useTranslation(); const { resetHistory } = useAppHistory(); return ( { + // On Review: Check if resetHistory is working as intended. + props.do?.(); + props.onItemClick?.(); + resetHistory(); + }} onMouseEnter={() => { props.handleOverflow(true); }} diff --git a/src/Components/Common/SortDropdown.tsx b/src/Components/Common/SortDropdown.tsx index b54edffa595..0c4fddec58c 100644 --- a/src/Components/Common/SortDropdown.tsx +++ b/src/Components/Common/SortDropdown.tsx @@ -29,6 +29,7 @@ export default function SortDropdownMenu(props: Props) { > {props.options.map(({ isAscending, value }) => (
    +
    ); } diff --git a/src/Components/Facility/HospitalList.tsx b/src/Components/Facility/FacilityList.tsx similarity index 99% rename from src/Components/Facility/HospitalList.tsx rename to src/Components/Facility/FacilityList.tsx index e7949440307..503f0fde34d 100644 --- a/src/Components/Facility/HospitalList.tsx +++ b/src/Components/Facility/FacilityList.tsx @@ -18,7 +18,7 @@ import routes from "../../Redux/api"; import CareIcon from "../../CAREUI/icons/CareIcon"; import Loading from "@/Components/Common/Loading"; -export const HospitalList = () => { +export const FacilityList = () => { const { qParams, updateQuery, diff --git a/src/Components/Notifications/ShowPushNotification.tsx b/src/Components/Notifications/ShowPushNotification.tsx index 2d2faa5ff5f..ca465f98df7 100644 --- a/src/Components/Notifications/ShowPushNotification.tsx +++ b/src/Components/Notifications/ShowPushNotification.tsx @@ -1,9 +1,8 @@ -import { DetailRoute } from "../../Routers/types"; import useQuery from "../../Utils/request/useQuery"; import routes from "../../Redux/api"; import { NotificationData } from "./models"; -export default function ShowPushNotification({ id }: DetailRoute) { +export default function ShowPushNotification({ id }: { id: string }) { useQuery(routes.getNotificationData, { pathParams: { id }, onResponse(res) { diff --git a/src/Components/Users/UserProfile.tsx b/src/Components/Users/UserProfile.tsx index b9af5b98f65..22f2a0e2607 100644 --- a/src/Components/Users/UserProfile.tsx +++ b/src/Components/Users/UserProfile.tsx @@ -469,10 +469,11 @@ export default function UserProfile() {

    - Personal Information + {t("personal_information")}

    - Local Body, District and State are Non Editable Settings. + {t("local_body")}, {t("district")}, {t("state")}{" "} + {t("are_non_editable_fields")}.

    - {showEdit ? "Cancel" : "Edit User Profile"} + {showEdit ? t("cancel") : t("edit_user_profile")} - Sign out + {t("sign_out")}
    @@ -498,7 +499,7 @@ export default function UserProfile() { id="username-profile-details" >
    - Username + {t("username")}
    {userData?.username || "-"} @@ -509,7 +510,7 @@ export default function UserProfile() { id="contactno-profile-details" >
    - Contact No + {t("phone_number")}
    {userData?.phone_number || "-"} @@ -521,7 +522,7 @@ export default function UserProfile() { id="whatsapp-profile-details" >
    - Whatsapp No + {t("whatsapp_number")}
    {userData?.alt_phone_number || "-"} @@ -532,7 +533,7 @@ export default function UserProfile() { id="emailid-profile-details" >
    - Email address + {t("email")}
    {userData?.email || "-"} @@ -543,7 +544,7 @@ export default function UserProfile() { id="firstname-profile-details" >
    - First Name + {t("first_name")}
    {userData?.first_name || "-"} @@ -554,7 +555,7 @@ export default function UserProfile() { id="lastname-profile-details" >
    - Last Name + {t("last_name")}
    {userData?.last_name || "-"} @@ -565,7 +566,7 @@ export default function UserProfile() { id="date_of_birth-profile-details" >
    - Date of Birth + {t("date_of_birth")}
    {userData?.date_of_birth @@ -575,7 +576,7 @@ export default function UserProfile() {
    - Access Level + {t("access_level")}
    {" "} @@ -587,7 +588,7 @@ export default function UserProfile() { id="gender-profile-details" >
    - Gender + {t("gender")}
    {userData?.gender || "-"} @@ -595,7 +596,7 @@ export default function UserProfile() {
    - Local Body + {t("local_body")}
    {userData?.local_body_object?.name || "-"} @@ -603,7 +604,7 @@ export default function UserProfile() {
    - District + {t("district")}
    {userData?.district_object?.name || "-"} @@ -611,7 +612,7 @@ export default function UserProfile() {
    - State + {t("state")}
    {userData?.state_object?.name || "-"} @@ -619,7 +620,7 @@ export default function UserProfile() {
    - Skills + {t("skills")}
    - Average weekly working hours + {t("average_weekly_working_hours")}
    {userData?.weekly_working_hours ?? "-"} @@ -656,7 +657,7 @@ export default function UserProfile() { id="videoconnectlink-profile-details" >
    - Video Connect Link + {t("video_conference_link")}
    {userData?.video_connect_link ? ( @@ -685,18 +686,18 @@ export default function UserProfile() { o.text} optionValue={(o) => o.text} - optionIcon={(o) => ( - {o.icon} - )} options={GENDER_TYPES} /> )}
    - +
    @@ -796,7 +798,7 @@ export default function UserProfile() {
    @@ -888,10 +890,10 @@ export default function UserProfile() {

    - Language Selection + {t("language_selection")}

    - Set your local language + {t("set_your_local_language")}

    @@ -903,10 +905,10 @@ export default function UserProfile() {

    - Software Update + {t("software_update")}

    - Check for an available update + {t("check_for_available_update")}

    @@ -915,7 +917,7 @@ export default function UserProfile() {
    - Update available + {t("update_available")}
    @@ -936,8 +938,8 @@ export default function UserProfile() { )} /> {updateStatus.isChecking - ? "Checking for update" - : "Check for update"} + ? t("checking_for_update") + : t("check_for_update")} )} diff --git a/src/Locale/en.json b/src/Locale/en.json index b4c18b685a9..0df3c961e10 100644 --- a/src/Locale/en.json +++ b/src/Locale/en.json @@ -25,6 +25,7 @@ "last_name": "Last Name", "email": "Email Address", "phone_number": "Phone Number", + "whatsapp_number": "Whatsapp Number", "district": "District", "gender": "Gender", "age": "Age", @@ -277,6 +278,29 @@ "unsupported_browser": "Unsupported Browser", "unsupported_browser_description": "Your browser ({{name}} version {{version}}) is not supported. Please update your browser to the latest version or switch to a supported browser for the best experience.", "add_remarks": "Add remarks", + "middleware_hostname": "Middleware Hostname", + "local_ipaddress": "Local IP Address", + "personal_information": "Personal Information", + "are_non_editable_fields": "are non-editable fields", + "edit_user_profile": "Edit Profile", + "skills": "Skills", + "access_level": "Access Level", + "qualification": "Qualification", + "years_of_experience": "Years of Experience", + "years_of_experience_of_the_doctor": "Years of Experience of the Doctor", + "medical_council_registration": "Medical Council Registration", + "doctor_s_medical_council_registration": "Doctor's Medical Council Registration", + "video_conference_link": "Video Conference Link", + "new_password_confirmation": "Confirm New Password", + "current_password": "Current Password", + "change_password": "Change Password", + "language_selection": "Language Selection", + "set_your_local_language": "Set your local language", + "software_update": "Software Update", + "check_for_available_update": "Check for available update", + "update_available": "Update Available", + "checking_for_update": "Checking for update", + "check_for_update": "Check for Update", "SORT_OPTIONS__-created_date": "Latest created date first", "SORT_OPTIONS__created_date": "Oldest created date first", "SORT_OPTIONS__-category_severity": "Highest Severity category first", @@ -293,9 +317,6 @@ "SORT_OPTIONS__-name": "Patient name Z-A", "SORT_OPTIONS__bed__name": "Bed No. 1-N", "SORT_OPTIONS__-bed__name": "Bed No. N-1", - "middleware_hostname": "Middleware Hostname", - "local_ipaddress": "Local IP Address", - "qualification": "Qualification", "CONSULTATION_TAB__UPDATES": "Overview", "CONSULTATION_TAB__FEED": "Feed", "CONSULTATION_TAB__SUMMARY": "Vitals", diff --git a/src/PluginEngine.tsx b/src/PluginEngine.tsx new file mode 100644 index 00000000000..3d47dba4d81 --- /dev/null +++ b/src/PluginEngine.tsx @@ -0,0 +1,51 @@ +/* eslint-disable i18next/no-literal-string */ +import React, { Suspense } from "react"; +import { CareAppsContext, useCareApps } from "./Common/hooks/useCareApps"; +import { pluginMap } from "./pluginTypes"; +import { UserAssignedModel } from "./Components/Users/models"; +import ErrorBoundary from "./Components/Common/ErrorBoundary"; + +export default function PluginEngine({ + children, +}: { + children: React.ReactNode; +}) { + return ( + Loading plugins...}> + + Error loading plugins + + } + > + + {children} + + + + ); +} + +export function PLUGIN_DoctorConnectButtons({ + user, +}: { + user: UserAssignedModel; +}) { + const plugins = useCareApps(); + return ( +
    + {plugins.map((plugin, index) => { + const DoctorConnectButtons = plugin.components.DoctorConnectButtons; + if (!DoctorConnectButtons) { + return null; + } + return ( +
    + +
    + ); + })} +
    + ); +} diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx index 4775674084e..f1130345f46 100644 --- a/src/Redux/api.tsx +++ b/src/Redux/api.tsx @@ -1129,7 +1129,7 @@ const routes = { path: "/api/v1/notification/notify/", method: "POST", TRes: Type(), - Tbody: Type(), + TBody: Type(), }, // FileUpload Create diff --git a/src/Routers/AppRouter.tsx b/src/Routers/AppRouter.tsx index 9d411d11950..df154ee7a5e 100644 --- a/src/Routers/AppRouter.tsx +++ b/src/Routers/AppRouter.tsx @@ -24,11 +24,26 @@ import HCXRoutes from "./routes/HCXRoutes"; import ShiftingRoutes from "./routes/ShiftingRoutes"; import AssetRoutes from "./routes/AssetRoutes"; import ResourceRoutes from "./routes/ResourceRoutes"; -import { DetailRoute } from "./types"; +import { usePluginRoutes } from "@/Common/hooks/useCareApps"; import careConfig from "@careConfig"; import IconIndex from "../CAREUI/icons/Index"; -const Routes = { +export type RouteParams = + T extends `${string}:${infer Param}/${infer Rest}` + ? { [K in Param | keyof RouteParams]: string } + : T extends `${string}:${infer Param}` + ? { [K in Param]: string } + : Record; + +export type RouteFunction = ( + params: RouteParams, +) => JSX.Element; + +export type AppRoutes = { + [K in string]: RouteFunction; +}; + +const Routes: AppRoutes = { "/": () => , ...AssetRoutes, @@ -40,15 +55,13 @@ const Routes = { ...ShiftingRoutes, ...UserRoutes, - "/notifications/:id": ({ id }: DetailRoute) => ( - - ), + "/notifications/:id": ({ id }) => , "/notice_board": () => , - "/abdm/health-information/:id": ({ id }: { id: string }) => ( + "/abdm/health-information/:id": ({ id }) => ( ), - "/facility/:facilityId/abdm": ({ facilityId }: any) => ( + "/facility/:facilityId/abdm": ({ facilityId }) => ( ), @@ -61,6 +74,8 @@ const Routes = { }; export default function AppRouter() { + const pluginRoutes = usePluginRoutes(); + let routes = Routes; if (careConfig.hcx.enabled) { @@ -68,7 +83,15 @@ export default function AppRouter() { } useRedirect("/user", "/users"); + + // Merge in Plugin Routes + routes = { + ...routes, + ...pluginRoutes, + }; + const pages = useRoutes(routes) || ; + const path = usePath(); const [sidebarOpen, setSidebarOpen] = useState(false); diff --git a/src/Routers/routes/AssetRoutes.tsx b/src/Routers/routes/AssetRoutes.tsx index d3bd96ca437..ee0537d6c58 100644 --- a/src/Routers/routes/AssetRoutes.tsx +++ b/src/Routers/routes/AssetRoutes.tsx @@ -2,20 +2,23 @@ import AssetConfigure from "../../Components/Assets/AssetConfigure"; import AssetManage from "../../Components/Assets/AssetManage"; import AssetsList from "../../Components/Assets/AssetsList"; import AssetCreate from "../../Components/Facility/AssetCreate"; +import { AppRoutes } from "../AppRouter"; -export default { +const AssetRoutes: AppRoutes = { "/assets": () => , - - "/facility/:facilityId/assets/new": (params: any) => ( - - ), - "/facility/:facilityId/assets/:assetId/update": (params: any) => ( - + "/facility/:facilityId/assets/new": ({ facilityId }) => ( + ), - "/facility/:facilityId/assets/:assetId": (params: any) => ( - + "/facility/:facilityId/assets/:assetId/update": ({ facilityId, assetId }) => ( + ), - "/facility/:facilityId/assets/:assetId/configure": (params: any) => ( - + "/facility/:facilityId/assets/:assetId": ({ facilityId, assetId }) => ( + ), + "/facility/:facilityId/assets/:assetId/configure": ({ + facilityId, + assetId, + }) => , }; + +export default AssetRoutes; diff --git a/src/Routers/routes/ConsultationRoutes.tsx b/src/Routers/routes/ConsultationRoutes.tsx index 598fd06adc3..77efe1081bc 100644 --- a/src/Routers/routes/ConsultationRoutes.tsx +++ b/src/Routers/routes/ConsultationRoutes.tsx @@ -5,30 +5,29 @@ import ManagePrescriptions from "../../Components/Medicine/ManagePrescriptions"; import { DailyRoundListDetails } from "../../Components/Patient/DailyRoundListDetails"; import { DailyRounds } from "../../Components/Patient/DailyRounds"; import { ConsultationDetails } from "../../Components/Facility/ConsultationDetails"; -import TreatmentSummary, { - ITreatmentSummaryProps, -} from "../../Components/Facility/TreatmentSummary"; +import TreatmentSummary from "../../Components/Facility/TreatmentSummary"; import ConsultationDoctorNotes from "../../Components/Facility/ConsultationDoctorNotes"; import PatientConsentRecords from "../../Components/Patient/PatientConsentRecords"; import CriticalCareEditor from "../../Components/LogUpdate/CriticalCareEditor"; import PrescriptionsPrintPreview from "../../Components/Medicine/PrintPreview"; import CriticalCarePreview from "../../Components/LogUpdate/CriticalCarePreview"; import FileUploadPage from "../../Components/Patient/FileUploadPage"; +import { AppRoutes } from "../AppRouter"; -export default { +const consultationRoutes: AppRoutes = { "/facility/:facilityId/patient/:patientId/consultation": ({ facilityId, patientId, - }: any) => , + }) => , "/facility/:facilityId/patient/:patientId/consultation/:id/update": ({ facilityId, patientId, id, - }: any) => ( + }) => ( ), "/facility/:facilityId/patient/:patientId/consultation/:id/consent-records": - ({ facilityId, patientId, id }: any) => ( + ({ facilityId, patientId, id }) => ( ( + }) => ( ), "/facility/:facilityId/patient/:patientId/consultation/:consultationId/prescriptions": - (path: any) => , + (path) => , "/facility/:facilityId/patient/:patientId/consultation/:consultationId/prescriptions/print": () => , "/facility/:facilityId/patient/:patientId/consultation/:id/investigation": ({ facilityId, patientId, id, - }: any) => ( + }) => ( ), "/facility/:facilityId/patient/:patientId/consultation/:id/investigation/:sessionId": - ({ facilityId, patientId, id, sessionId }: any) => ( + ({ facilityId, patientId, id, sessionId }) => ( ( + }) => ( ), "/facility/:facilityId/patient/:patientId/consultation/:consultationId/daily-rounds/:id/update": - ({ facilityId, patientId, consultationId, id }: any) => ( + ({ facilityId, patientId, consultationId, id }) => ( ), "/facility/:facilityId/patient/:patientId/consultation/:consultationId/daily-rounds/:id": - ({ facilityId, patientId, consultationId, id }: any) => ( + ({ facilityId, patientId, consultationId, id }) => ( ), - "/facility/:facilityId/patient/:patientId/consultation/:consultationId/daily_rounds/:id": - (params: { - facilityId: string; - patientId: string; - consultationId: string; - id: string; - }) => , + ({ facilityId, patientId, consultationId, id }) => ( + + ), "/facility/:facilityId/patient/:patientId/consultation/:consultationId/daily_rounds/:id/update": - (params: { - facilityId: string; - patientId: string; - consultationId: string; - id: string; - }) => , + ({ facilityId, patientId, consultationId, id }) => ( + + ), "/facility/:facilityId/patient/:patientId/consultation/:consultationId": ({ facilityId, patientId, consultationId, - }: any) => ( + }) => ( ), - "/consultation/:consultationId": ({ consultationId }: any) => ( + "/consultation/:consultationId": ({ consultationId }) => ( ), "/facility/:facilityId/patient/:patientId/consultation/:consultationId/treatment-summary": - ({ facilityId, patientId, consultationId }: ITreatmentSummaryProps) => ( + ({ facilityId, patientId, consultationId }) => ( ), "/facility/:facilityId/patient/:patientId/consultation/:consultationId/notes": - ({ facilityId, patientId, consultationId }: any) => ( + ({ facilityId, patientId, consultationId }) => ( ), "/facility/:facilityId/patient/:patientId/consultation/:consultationId/:tab": - ({ facilityId, patientId, consultationId, tab }: any) => ( + ({ facilityId, patientId, consultationId, tab }) => ( ), }; + +export default consultationRoutes; diff --git a/src/Routers/routes/FacilityInventoryRoutes.tsx b/src/Routers/routes/FacilityInventoryRoutes.tsx index 17e93b2bc60..99123d8f737 100644 --- a/src/Routers/routes/FacilityInventoryRoutes.tsx +++ b/src/Routers/routes/FacilityInventoryRoutes.tsx @@ -3,22 +3,25 @@ import InventoryList from "../../Components/Facility/InventoryList"; import InventoryLog from "../../Components/Facility/InventoryLog"; import MinQuantityList from "../../Components/Facility/MinQuantityList"; import { SetInventoryForm } from "../../Components/Facility/SetInventoryForm"; +import { AppRoutes } from "../AppRouter"; -export default { - "/facility/:facilityId/inventory": ({ facilityId }: any) => ( +const FacilityInventoryRoutes: AppRoutes = { + "/facility/:facilityId/inventory": ({ facilityId }) => ( ), - "/facility/:facilityId/inventory/min_quantity/set": ({ facilityId }: any) => ( + "/facility/:facilityId/inventory/min_quantity/set": ({ facilityId }) => ( ), - "/facility/:facilityId/inventory/min_quantity/list": ({ - facilityId, - }: any) => , - "/facility/:facilityId/inventory/min_quantity": ({ facilityId }: any) => ( + "/facility/:facilityId/inventory/min_quantity/list": ({ facilityId }) => ( + + ), + "/facility/:facilityId/inventory/min_quantity": ({ facilityId }) => ( ), "/facility/:facilityId/inventory/:inventoryId": ({ facilityId, inventoryId, - }: any) => , + }) => , }; + +export default FacilityInventoryRoutes; diff --git a/src/Routers/routes/FacilityLocationRoutes.tsx b/src/Routers/routes/FacilityLocationRoutes.tsx index 5d547ebd466..c2e1add4b10 100644 --- a/src/Routers/routes/FacilityLocationRoutes.tsx +++ b/src/Routers/routes/FacilityLocationRoutes.tsx @@ -6,41 +6,42 @@ import LocationManagement from "../../Components/Facility/LocationManagement"; import CentralLiveMonitoring from "../../Components/CameraFeed/CentralLiveMonitoring"; import { AuthorizeUserRoute } from "../../Utils/AuthorizeFor"; import { CameraFeedPermittedUserTypes } from "../../Utils/permissions"; +import { AppRoutes } from "../AppRouter"; -export default { - "/facility/:facilityId/location": ({ facilityId }: any) => ( +const FacilityLocationRoutes: AppRoutes = { + "/facility/:facilityId/location": ({ facilityId }) => ( ), "/facility/:facilityId/location/:locationId/beds": ({ facilityId, locationId, - }: any) => , - "/facility/:facilityId/inventory/add": ({ facilityId }: any) => ( + }) => , + "/facility/:facilityId/inventory/add": ({ facilityId }) => ( ), - "/facility/:facilityId/location/add": ({ facilityId }: any) => ( + "/facility/:facilityId/location/add": ({ facilityId }) => ( ), "/facility/:facilityId/location/:locationId/update": ({ facilityId, locationId, - }: any) => ( - - ), + }) => , "/facility/:facilityId/location/:locationId/beds/add": ({ facilityId, locationId, - }: any) => , + }) => , "/facility/:facilityId/location/:locationId/beds/:bedId/update": ({ facilityId, locationId, bedId, - }: any) => ( + }) => ( ), - "/facility/:facilityId/live-monitoring": (props: any) => ( + "/facility/:facilityId/live-monitoring": ({ facilityId }) => ( - + ), }; + +export default FacilityLocationRoutes; diff --git a/src/Routers/routes/FacilityRoutes.tsx b/src/Routers/routes/FacilityRoutes.tsx index 2c711cf48cb..16b202ae0ce 100644 --- a/src/Routers/routes/FacilityRoutes.tsx +++ b/src/Routers/routes/FacilityRoutes.tsx @@ -2,48 +2,47 @@ import { FacilityConfigure } from "../../Components/Facility/FacilityConfigure"; import { FacilityCreate } from "../../Components/Facility/FacilityCreate"; import { FacilityHome } from "../../Components/Facility/FacilityHome"; import FacilityUsers from "../../Components/Facility/FacilityUsers"; -import { HospitalList } from "../../Components/Facility/HospitalList"; +import { FacilityList } from "../../Components/Facility/FacilityList"; import { TriageForm } from "../../Components/Facility/TriageForm"; import ResourceCreate from "../../Components/Resource/ResourceCreate"; import CentralNursingStation from "../../Components/Facility/CentralNursingStation"; import FacilityLocationRoutes from "./FacilityLocationRoutes"; import FacilityInventoryRoutes from "./FacilityInventoryRoutes"; import DischargedPatientsList from "../../Components/Facility/DischargedPatientsList"; +import { AppRoutes } from "../AppRouter"; -export default { - "/facility": () => , +const FacilityRoutes: AppRoutes = { + "/facility": () => , "/facility/create": () => , - "/facility/:facilityId/update": ({ facilityId }: any) => ( + "/facility/:facilityId/update": ({ facilityId }) => ( ), - "/facility/:facilityId/configure": ({ facilityId }: any) => ( + "/facility/:facilityId/configure": ({ facilityId }) => ( ), - "/facility/:facilityId/cns": ({ facilityId }: any) => ( + "/facility/:facilityId/cns": ({ facilityId }) => ( ), - "/facility/:facilityId": ({ facilityId }: any) => ( + "/facility/:facilityId": ({ facilityId }) => ( ), - "/facility/:id/discharged-patients": ({ id }: any) => ( + "/facility/:id/discharged-patients": ({ id }) => ( ), - - "/facility/:facilityId/users": ({ facilityId }: any) => ( + "/facility/:facilityId/users": ({ facilityId }) => ( ), - "/facility/:facilityId/resource/new": ({ facilityId }: any) => ( + "/facility/:facilityId/resource/new": ({ facilityId }) => ( ), - - // Triage related routes - "/facility/:facilityId/triage": ({ facilityId }: any) => ( + "/facility/:facilityId/triage": ({ facilityId }) => ( ), - "/facility/:facilityId/triage/:id": ({ facilityId, id }: any) => ( + "/facility/:facilityId/triage/:id": ({ facilityId, id }) => ( ), - ...FacilityLocationRoutes, ...FacilityInventoryRoutes, }; + +export default FacilityRoutes; diff --git a/src/Routers/routes/HCXRoutes.tsx b/src/Routers/routes/HCXRoutes.tsx index 80378b24621..929cc3f12bb 100644 --- a/src/Routers/routes/HCXRoutes.tsx +++ b/src/Routers/routes/HCXRoutes.tsx @@ -1,10 +1,15 @@ -import ConsultationClaims, { - IConsultationClaimsProps, -} from "../../Components/Facility/ConsultationClaims"; +import ConsultationClaims from "../../Components/Facility/ConsultationClaims"; +import { AppRoutes } from "../AppRouter"; -export default { +const HCXRoutes: AppRoutes = { "/facility/:facilityId/patient/:patientId/consultation/:consultationId/claims": - (pathParams: IConsultationClaimsProps) => ( - + ({ facilityId, patientId, consultationId }) => ( + ), }; + +export default HCXRoutes; diff --git a/src/Routers/routes/PatientRoutes.tsx b/src/Routers/routes/PatientRoutes.tsx index fcfc9b04e37..45ff044e4d2 100644 --- a/src/Routers/routes/PatientRoutes.tsx +++ b/src/Routers/routes/PatientRoutes.tsx @@ -3,44 +3,44 @@ import { PatientManager } from "../../Components/Patient/ManagePatients"; import { PatientHome } from "../../Components/Patient/PatientHome"; import PatientNotes from "../../Components/Patient/PatientNotes"; import { PatientRegister } from "../../Components/Patient/PatientRegister"; -import { DetailRoute } from "../types"; import DeathReport from "../../Components/DeathReport/DeathReport"; import { InsuranceDetails } from "../../Components/Patient/InsuranceDetails"; import FileUploadPage from "../../Components/Patient/FileUploadPage"; +import { AppRoutes } from "../AppRouter"; -export default { +const PatientRoutes: AppRoutes = { "/patients": () => , - "/patient/:id": ({ id }: DetailRoute) => , - "/patient/:id/investigation_reports": ({ id }: DetailRoute) => ( + "/patient/:id": ({ id }) => , + "/patient/:id/investigation_reports": ({ id }) => ( ), - - // Facility Scoped Routes - "/facility/:facilityId/patient": ({ facilityId }: any) => ( + "/facility/:facilityId/patient": ({ facilityId }) => ( ), - "/facility/:facilityId/patient/:id": ({ facilityId, id }: any) => ( + "/facility/:facilityId/patient/:id": ({ facilityId, id }) => ( ), - "/facility/:facilityId/patient/:id/insurance": ({ facilityId, id }: any) => ( + "/facility/:facilityId/patient/:id/insurance": ({ facilityId, id }) => ( ), - "/facility/:facilityId/patient/:id/update": ({ facilityId, id }: any) => ( + "/facility/:facilityId/patient/:id/update": ({ facilityId, id }) => ( ), "/facility/:facilityId/patient/:patientId/notes": ({ facilityId, patientId, - }: any) => , + }) => , "/facility/:facilityId/patient/:patientId/files": ({ facilityId, patientId, - }: any) => ( + }) => ( ), - "/death_report/:id": ({ id }: any) => , + "/death_report/:id": ({ id }) => , }; + +export default PatientRoutes; diff --git a/src/Routers/routes/ResourceRoutes.tsx b/src/Routers/routes/ResourceRoutes.tsx index 6636d0d83ea..d75c933f760 100644 --- a/src/Routers/routes/ResourceRoutes.tsx +++ b/src/Routers/routes/ResourceRoutes.tsx @@ -3,17 +3,17 @@ import { ResourceDetailsUpdate } from "../../Components/Resource/ResourceDetails import ListView from "../../Components/Resource/ListView"; import BoardView from "../../Components/Resource/ResourceBoardView"; import { Redirect } from "raviger"; -import { DetailRoute } from "../types"; +import { AppRoutes } from "../AppRouter"; const getDefaultView = () => localStorage.getItem("defaultResourceView") === "list" ? "list" : "board"; -export default { +const ResourceRoutes: AppRoutes = { "/resource": () => , "/resource/board": () => , "/resource/list": () => , - "/resource/:id": ({ id }: DetailRoute) => , - "/resource/:id/update": ({ id }: DetailRoute) => ( - - ), + "/resource/:id": ({ id }) => , + "/resource/:id/update": ({ id }) => , }; + +export default ResourceRoutes; diff --git a/src/Routers/routes/SampleRoutes.tsx b/src/Routers/routes/SampleRoutes.tsx index 290a34fd4eb..cf296790a81 100644 --- a/src/Routers/routes/SampleRoutes.tsx +++ b/src/Routers/routes/SampleRoutes.tsx @@ -2,24 +2,22 @@ import { SampleDetails } from "../../Components/Patient/SampleDetails"; import SampleReport from "../../Components/Patient/SamplePreview"; import { SampleTest } from "../../Components/Patient/SampleTest"; import SampleViewAdmin from "../../Components/Patient/SampleViewAdmin"; -import { DetailRoute, RouteParams } from "../types"; +import { AppRoutes } from "../AppRouter"; -export default { +const SampleRoutes: AppRoutes = { "/sample": () => , - "/sample/:id": ({ id }: DetailRoute) => , + "/sample/:id": ({ id }) => , "/patient/:patientId/test_sample/:sampleId/icmr_sample": ({ patientId, sampleId, - }: RouteParams<"patientId" | "sampleId">) => ( - - ), + }) => , "/facility/:facilityId/patient/:patientId/sample-test": ({ facilityId, patientId, - }: RouteParams<"facilityId" | "patientId">) => ( - + }) => , + "/facility/:facilityId/patient/:patientId/sample/:id": ({ id }) => ( + ), - "/facility/:facilityId/patient/:patientId/sample/:id": ({ - id, - }: DetailRoute) => , }; + +export default SampleRoutes; diff --git a/src/Routers/routes/ShiftingRoutes.tsx b/src/Routers/routes/ShiftingRoutes.tsx index f2e12de4f25..dc11ff2b8ee 100644 --- a/src/Routers/routes/ShiftingRoutes.tsx +++ b/src/Routers/routes/ShiftingRoutes.tsx @@ -4,18 +4,21 @@ import { ShiftDetailsUpdate } from "../../Components/Shifting/ShiftDetailsUpdate import ListView from "../../Components/Shifting/ListView"; import BoardView from "../../Components/Shifting/BoardView"; import { Redirect } from "raviger"; +import { AppRoutes } from "../AppRouter"; const getDefaultView = () => localStorage.getItem("defaultShiftView") === "list" ? "list" : "board"; -export default { +const ShiftingRoutes: AppRoutes = { "/shifting": () => , "/shifting/board": () => , "/shifting/list": () => , - "/shifting/:id": ({ id }: any) => , - "/shifting/:id/update": ({ id }: any) => , + "/shifting/:id": ({ id }) => , + "/shifting/:id/update": ({ id }) => , "/facility/:facilityId/patient/:patientId/shift/new": ({ facilityId, patientId, - }: any) => , + }) => , }; + +export default ShiftingRoutes; diff --git a/src/Routers/routes/UserRoutes.tsx b/src/Routers/routes/UserRoutes.tsx index 56877ca4c78..24f355b201b 100644 --- a/src/Routers/routes/UserRoutes.tsx +++ b/src/Routers/routes/UserRoutes.tsx @@ -1,9 +1,12 @@ import ManageUsers from "../../Components/Users/ManageUsers"; import { UserAdd } from "../../Components/Users/UserAdd"; import UserProfile from "../../Components/Users/UserProfile"; +import { AppRoutes } from "../AppRouter"; -export default { +const UserRoutes: AppRoutes = { "/users": () => , "/users/add": () => , "/user/profile": () => , }; + +export default UserRoutes; diff --git a/src/Utils/useTimer.tsx b/src/Utils/useTimer.tsx index 6a8d8320c5e..f7a03ffefa0 100644 --- a/src/Utils/useTimer.tsx +++ b/src/Utils/useTimer.tsx @@ -27,7 +27,7 @@ export const useTimer = (autoStart = false) => { const [time, setTime] = useState(0); useEffect(() => { - let interval: number; + let interval: ReturnType; if (running) { interval = setInterval(() => { setTime((prevTime) => prevTime + 1); diff --git a/src/pluginTypes.ts b/src/pluginTypes.ts new file mode 100644 index 00000000000..26a07e4f141 --- /dev/null +++ b/src/pluginTypes.ts @@ -0,0 +1,54 @@ +import { LazyExoticComponent } from "react"; +import { UserAssignedModel } from "./Components/Users/models"; +import { AppRoutes } from "./Routers/AppRouter"; +import { INavItem } from "./Components/Common/Sidebar/Sidebar"; +import { pluginMap } from "./pluginMap"; + +// Define the available plugins +export type AvailablePlugin = "@apps/care_livekit_fe"; + +export type AvailablePluginManifest = "@app-manifest/care_livekit_fe"; + +export type DoctorConnectButtonComponentType = React.FC<{ + user: UserAssignedModel; +}>; + +// Define supported plugin components +export type SupportedPluginComponents = { + DoctorConnectButtons: DoctorConnectButtonComponentType; +}; + +// Create a type for lazy-loaded components +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type LazyComponent> = LazyExoticComponent; + +// Define PluginComponentMap with lazy-loaded components +export type PluginComponentMap = { + [K in keyof SupportedPluginComponents]?: LazyComponent< + SupportedPluginComponents[K] + >; +}; + +type SupportedPluginExtensions = + | "DoctorConnectButtons" + | "PatientExternalRegistration"; + +export type PluginManifest = { + plugin: string; + routes: AppRoutes; + extends: SupportedPluginExtensions[]; + components: PluginComponentMap; + navItems: INavItem[]; +}; + +// Create a type that ensures only available plugins can be used +export type EnabledPluginConfig = { + plugin: string; + manifestPath: AvailablePluginManifest; + path: AvailablePlugin; + manifest: Promise; + // Components are a dictionary, with the key being the component name, and the value being the component type + components: PluginComponentMap; +}; + +export { pluginMap }; diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index 7657f7da19e..f339922bfae 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -31,6 +31,7 @@ interface ImportMetaEnv { readonly REACT_JWT_TOKEN_REFRESH_INTERVAL?: string; readonly REACT_MIN_ENCOUNTER_DATE?: string; readonly REACT_ALLOWED_LOCALES?: string; + readonly REACT_ENABLED_APPS?: string; // Plugins related envs... readonly REACT_PLAUSIBLE_SERVER_URL?: string; diff --git a/tsconfig.json b/tsconfig.json index 531d6f800e1..51ffeb4a0ae 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,9 +19,12 @@ "baseUrl": ".", "paths": { "@/*": ["./src/*"], + "@core/*": ["src/*"], + "@apps/*": ["apps/*/src"], + "@app-manifest/*": ["apps/*/src/manifest.ts"], "@careConfig": ["./care.config.ts"] } }, - "include": ["src", "care.config.ts"], + "include": ["src/**/*", "apps/**/*", "care.config.ts"], "exclude": ["src/**/*.gen.tsx"] } diff --git a/vite.config.mts b/vite.config.mts index acb0cdf727b..905374eb923 100644 --- a/vite.config.mts +++ b/vite.config.mts @@ -1,10 +1,12 @@ -import path from "node:path"; +import path from "path"; import { createRequire } from "node:module"; import { VitePWA } from "vite-plugin-pwa"; import react from "@vitejs/plugin-react-swc"; import checker from "vite-plugin-checker"; import { viteStaticCopy } from "vite-plugin-static-copy"; import { treeShakeCareIcons } from "./plugins/treeShakeCareIcons"; +import fs from "fs"; +import { defineConfig } from "vite"; const pdfWorkerPath = path.join( path.dirname( @@ -22,8 +24,56 @@ const cdnUrls = "http://localhost:4566", ].join(" "); +function getPluginAliases() { + const pluginsDir = path.resolve(__dirname, "apps"); + // Make sure the `apps` folder exists + if (!fs.existsSync(pluginsDir)) { + return {}; + } + const pluginFolders = fs.readdirSync(pluginsDir); + + const aliases = {}; + + pluginFolders.forEach((pluginFolder) => { + const pluginSrcPath = path.join(pluginsDir, pluginFolder, "src"); + if (fs.existsSync(pluginSrcPath)) { + aliases[`@apps/${pluginFolder}`] = pluginSrcPath; + aliases[`@app-manifest/${pluginFolder}`] = path.join( + pluginSrcPath, + "manifest.ts", + ); + } + }); + + return aliases; +} + +function getPluginDependencies() { + const pluginsDir = path.resolve(__dirname, "apps"); + // Make sure the `apps` folder exists + if (!fs.existsSync(pluginsDir)) { + return []; + } + const pluginFolders = fs.readdirSync(pluginsDir); + + const dependencies = new Set(); + + pluginFolders.forEach((pluginFolder) => { + const packageJsonPath = path.join(pluginsDir, pluginFolder, "package.json"); + if (fs.existsSync(packageJsonPath)) { + const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")); + const pluginDependencies = packageJson.dependencies + ? Object.keys(packageJson.dependencies) + : []; + pluginDependencies.forEach((dep) => dependencies.add(dep)); + } + }); + + return Array.from(dependencies); +} + /** @type {import('vite').UserConfig} */ -export default { +export default defineConfig({ envPrefix: "REACT_", plugins: [ viteStaticCopy({ @@ -86,10 +136,15 @@ export default { ], resolve: { alias: { + ...getPluginAliases(), "@": path.resolve(__dirname, "./src"), "@careConfig": path.resolve(__dirname, "./care.config.ts"), + "@core": path.resolve(__dirname, "src/"), }, }, + optimizeDeps: { + include: getPluginDependencies(), + }, build: { outDir: "build", assetsDir: "bundle", @@ -118,4 +173,4 @@ export default { }, port: 4000, }, -}; +}); From 2993e5a5dae22129de63df8bc15e9c12ab313100 Mon Sep 17 00:00:00 2001 From: Gigin George Date: Wed, 16 Oct 2024 16:25:34 +0530 Subject: [PATCH 3/9] Remove ThemedFavIcon --- src/App.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/App.tsx b/src/App.tsx index 180bd92839c..0b2d20e805a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,7 +11,6 @@ import { Toaster } from "./Components/ui/toaster"; const App = () => { return ( }> - }> From 5a37ff1a2eaa2316f2fef4e640af5ecb9ca31f4d Mon Sep 17 00:00:00 2001 From: Shivank Kacker Date: Wed, 16 Oct 2024 16:46:50 +0530 Subject: [PATCH 4/9] Updated README: updated CARE logo (#8801) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7ea8fe1a221..2504bf47fb7 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@

    - - CARE Logo + + CARE Logo

    From bbb7503279395d6c18e1e88b8ab96ac278963545 Mon Sep 17 00:00:00 2001 From: Vinu Date: Wed, 16 Oct 2024 16:52:57 +0530 Subject: [PATCH 5/9] Update styling for the side nav (#8789) Co-authored-by: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> --- cypress/e2e/auth_spec/auth.cy.ts | 1 + .../patient_spec/PatientBedManagement.cy.ts | 2 +- .../patient_spec/PatientDoctorConnect.cy.ts | 3 +- .../e2e/patient_spec/PatientDoctorNotes.cy.ts | 2 +- cypress/e2e/users_spec/UsersCreation.cy.ts | 2 + cypress/pageobject/Login/LoginPage.ts | 2 + .../Patient/PatientDoctorConnect.ts | 4 +- .../pageobject/Patient/PatientDoctorNotes.ts | 6 + cypress/pageobject/Users/ManageUserPage.ts | 1 + package-lock.json | 461 ++++++++++++++++++ package.json | 2 + public/favicon.ico | Bin 6439 -> 15086 bytes src/CAREUI/icons/UniconPaths.json | 12 + src/Components/Common/Breadcrumbs.tsx | 4 +- src/Components/Common/Sidebar/Sidebar.tsx | 111 +++-- src/Components/Common/Sidebar/SidebarItem.tsx | 6 +- .../Common/Sidebar/SidebarUserCard.tsx | 93 ++-- src/Components/Facility/FacilityList.tsx | 2 +- src/Components/Notifications/NoticeBoard.tsx | 2 +- src/Components/Patient/ManagePatients.tsx | 2 +- src/Components/Resource/ResourceBoardView.tsx | 2 +- src/Components/ui/dropdown-menu.tsx | 203 ++++++++ src/Components/ui/tooltip.tsx | 28 ++ src/Locale/en.json | 18 +- 24 files changed, 863 insertions(+), 106 deletions(-) create mode 100644 src/Components/ui/dropdown-menu.tsx create mode 100644 src/Components/ui/tooltip.tsx diff --git a/cypress/e2e/auth_spec/auth.cy.ts b/cypress/e2e/auth_spec/auth.cy.ts index a535668ef01..b2bd7b634c0 100644 --- a/cypress/e2e/auth_spec/auth.cy.ts +++ b/cypress/e2e/auth_spec/auth.cy.ts @@ -6,6 +6,7 @@ describe("Authorisation/Authentication", () => { it("Try login as admin with correct password", () => { cy.loginByApi("devdistrictadmin", "Coronasafe@123"); cy.awaitUrl("/facility"); + cy.get("#user-profile-name").click(); cy.get("#sign-out-button").contains("Sign Out").click(); cy.url().should("include", "/"); }); diff --git a/cypress/e2e/patient_spec/PatientBedManagement.cy.ts b/cypress/e2e/patient_spec/PatientBedManagement.cy.ts index d9453806c9f..1964f913a03 100644 --- a/cypress/e2e/patient_spec/PatientBedManagement.cy.ts +++ b/cypress/e2e/patient_spec/PatientBedManagement.cy.ts @@ -10,7 +10,7 @@ describe("Patient swtich bed functionality", () => { const patientConsultationPage = new PatientConsultationPage(); const switchBedOne = "Dummy Bed 4"; const switchBedTwo = "Dummy Bed 1"; - const switchBedThree = "Dummy Bed 3"; + const switchBedThree = "Dummy Bed 7"; const switchPatientOne = "Dummy Patient 6"; const switchPatientTwo = "Dummy Patient 7"; diff --git a/cypress/e2e/patient_spec/PatientDoctorConnect.cy.ts b/cypress/e2e/patient_spec/PatientDoctorConnect.cy.ts index 64d47db2cf1..c1362c328c0 100644 --- a/cypress/e2e/patient_spec/PatientDoctorConnect.cy.ts +++ b/cypress/e2e/patient_spec/PatientDoctorConnect.cy.ts @@ -8,7 +8,6 @@ describe("Patient Doctor Connect in consultation page", () => { const doctorconnect = new DoctorConnect(); const patientName = "Dummy Patient 11"; const doctorUser = "Dev Doctor"; - const doctorUserNumber = "+919876543219"; const nurseUser = "Dev Staff"; const teleIcuUser = "Dev Doctor Two"; @@ -37,7 +36,7 @@ describe("Patient Doctor Connect in consultation page", () => { "#doctor-connect-home-doctor", doctorUser, ); - doctorconnect.verifyCopiedContent(doctorUserNumber); + doctorconnect.verifyCopiedContent(); // verify the whatsapp and phone number icon presence doctorconnect.verifyIconVisible("#whatsapp-icon"); doctorconnect.verifyIconVisible("#phone-icon"); diff --git a/cypress/e2e/patient_spec/PatientDoctorNotes.cy.ts b/cypress/e2e/patient_spec/PatientDoctorNotes.cy.ts index 94300cdb5c6..9a21eaea51f 100644 --- a/cypress/e2e/patient_spec/PatientDoctorNotes.cy.ts +++ b/cypress/e2e/patient_spec/PatientDoctorNotes.cy.ts @@ -37,7 +37,7 @@ describe("Patient Discussion notes in the consultation page", () => { cy.verifyNotification(discussionNotesSuccessMessage); cy.closeNotification(); // verify the auto-switching of tab to nurse notes if the user is a nurse - cy.get("#sign-out-button").contains("Sign Out").click(); + patientDoctorNotes.signout(); loginPage.loginManuallyAsNurse(); loginPage.ensureLoggedIn(); cy.visit("/patients"); diff --git a/cypress/e2e/users_spec/UsersCreation.cy.ts b/cypress/e2e/users_spec/UsersCreation.cy.ts index 0f592318888..2c5797fefa7 100644 --- a/cypress/e2e/users_spec/UsersCreation.cy.ts +++ b/cypress/e2e/users_spec/UsersCreation.cy.ts @@ -67,6 +67,7 @@ describe("User Creation", () => { it("Update the existing user profile and verify its reflection", () => { userCreationPage.clickElementById("user-profile-name"); + userCreationPage.clickElementById("profile-button"); userCreationPage.verifyElementContainsText( "username-profile-details", "devdistrictadmin", @@ -129,6 +130,7 @@ describe("User Creation", () => { it("Update the existing user profile Form Mandatory File Error", () => { userCreationPage.clickElementById("user-profile-name"); + userCreationPage.clickElementById("profile-button"); userCreationPage.clickElementById("edit-cancel-profile-button"); userCreationPage.clearIntoElementById("firstName"); userCreationPage.clearIntoElementById("lastName"); diff --git a/cypress/pageobject/Login/LoginPage.ts b/cypress/pageobject/Login/LoginPage.ts index 7ea94d54737..06bd165c9ac 100644 --- a/cypress/pageobject/Login/LoginPage.ts +++ b/cypress/pageobject/Login/LoginPage.ts @@ -30,6 +30,8 @@ class LoginPage { } ensureLoggedIn(): void { + cy.get("#user-profile-name").click(); + cy.get("#sign-out-button").scrollIntoView(); cy.get("#sign-out-button").contains("Sign Out").should("exist"); } } diff --git a/cypress/pageobject/Patient/PatientDoctorConnect.ts b/cypress/pageobject/Patient/PatientDoctorConnect.ts index b8c33bb4b24..9933c3a1dec 100644 --- a/cypress/pageobject/Patient/PatientDoctorConnect.ts +++ b/cypress/pageobject/Patient/PatientDoctorConnect.ts @@ -10,8 +10,8 @@ export class DoctorConnect { }); } - verifyCopiedContent(text: string) { - cy.get("@clipboardStub").should("be.calledWith", text); + verifyCopiedContent() { + cy.get("@clipboardStub").should("be.calledWithMatch", /^\+91\d{10}$/); } verifyIconVisible(selector: string) { diff --git a/cypress/pageobject/Patient/PatientDoctorNotes.ts b/cypress/pageobject/Patient/PatientDoctorNotes.ts index 9538b0eed3b..157f35d47d9 100644 --- a/cypress/pageobject/Patient/PatientDoctorNotes.ts +++ b/cypress/pageobject/Patient/PatientDoctorNotes.ts @@ -26,4 +26,10 @@ export class PatientDoctorNotes { .its("response.statusCode") .should("eq", 201); } + + signout() { + cy.get("#user-profile-name").click(); + cy.get("#sign-out-button").scrollIntoView(); + cy.get("#sign-out-button").contains("Sign Out").click(); + } } diff --git a/cypress/pageobject/Users/ManageUserPage.ts b/cypress/pageobject/Users/ManageUserPage.ts index efa0d90142c..470862693a8 100644 --- a/cypress/pageobject/Users/ManageUserPage.ts +++ b/cypress/pageobject/Users/ManageUserPage.ts @@ -75,6 +75,7 @@ export class ManageUserPage { navigateToProfile() { cy.intercept("GET", "**/api/v1/users/**").as("getUsers"); cy.get("#user-profile-name").click(); + cy.get("#profile-button").click(); cy.wait("@getUsers").its("response.statusCode").should("eq", 200); } diff --git a/package-lock.json b/package-lock.json index e5bae3c6d02..aa99337d8d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,9 +19,11 @@ "@hello-pangea/dnd": "^17.0.0", "@pnotify/core": "^5.2.0", "@pnotify/mobile": "^5.2.0", + "@radix-ui/react-dropdown-menu": "^2.1.2", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-toast": "^1.2.2", + "@radix-ui/react-tooltip": "^1.1.3", "@sentry/browser": "^8.33.0", "@yudiel/react-qr-scanner": "^2.0.8", "axios": "^1.7.7", @@ -3121,6 +3123,28 @@ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", + "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", + "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-collection": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", @@ -3188,6 +3212,20 @@ } } }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", + "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", + "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-dismissable-layer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.1.tgz", @@ -3214,6 +3252,72 @@ } } }, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.2.tgz", + "integrity": "sha512-GVZMR+eqK8/Kes0a36Qrv+i20bAPXSn8rCBTHx30w+3ECnR5o3xixAlqcVaYvLeyKUsm0aqyhWfmUcqufM8nYA==", + "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-menu": "2.1.2", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "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-focus-guards": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz", + "integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==", + "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-focus-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz", + "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "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-icons": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.0.tgz", @@ -3222,6 +3326,107 @@ "react": "^16.x || ^17.x || ^18.x" } }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", + "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", + "dependencies": { + "@radix-ui/react-use-layout-effect": "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-menu": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.2.tgz", + "integrity": "sha512-lZ0R4qR2Al6fZ4yCCZzu/ReTFrylHFxIqy7OezIpWF4bL0o9biKo0pFIvkaew3TyZ9Fy5gYVrR5zCGZBVbO1zg==", + "dependencies": { + "@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-presence": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-roving-focus": "1.1.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-callback-ref": "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-popper": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", + "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-rect": "1.1.0", + "@radix-ui/react-use-size": "1.1.0", + "@radix-ui/rect": "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-popper/node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "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-portal": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.2.tgz", @@ -3290,6 +3495,50 @@ } } }, + "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", + "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==", + "dependencies": { + "@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.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "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/node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "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-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", @@ -3340,6 +3589,39 @@ } } }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.3.tgz", + "integrity": "sha512-Z4w1FIS0BqVFI2c1jZvb/uDVJijJjJ2ZMuPV81oVgTZ7g3BZxobplnMVvXtFWgtozdvYJ+MFWtwkM5S2HnAong==", + "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-dismissable-layer": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.0", + "@radix-ui/react-portal": "1.1.2", + "@radix-ui/react-presence": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-visually-hidden": "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-use-callback-ref": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", @@ -3402,6 +3684,40 @@ } } }, + "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", + "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", + "dependencies": { + "@radix-ui/rect": "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-use-size": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", + "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", + "dependencies": { + "@radix-ui/react-use-layout-effect": "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-visually-hidden": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz", @@ -3424,6 +3740,11 @@ } } }, + "node_modules/@radix-ui/rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", + "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" + }, "node_modules/@react-aria/focus": { "version": "3.18.4", "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.18.4.tgz", @@ -5272,6 +5593,17 @@ "node": ">=14.0.0" } }, + "node_modules/aria-hidden": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", + "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/array-buffer-byte-length": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", @@ -6737,6 +7069,11 @@ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, "node_modules/detective-amd": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/detective-amd/-/detective-amd-6.0.0.tgz", @@ -8409,6 +8746,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/get-own-enumerable-property-symbols": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", @@ -9228,6 +9573,14 @@ "node": ">= 0.10" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/is-alphabetical": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", @@ -14672,6 +15025,73 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" }, + "node_modules/react-remove-scroll": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.0.tgz", + "integrity": "sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==", + "dependencies": { + "react-remove-scroll-bar": "^2.3.6", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz", + "integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==", + "dependencies": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "dependencies": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-webcam": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/react-webcam/-/react-webcam-7.2.0.tgz", @@ -17557,6 +17977,26 @@ "requires-port": "^1.0.0" } }, + "node_modules/use-callback-ref": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz", + "integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/use-keyboard-shortcut": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/use-keyboard-shortcut/-/use-keyboard-shortcut-1.1.6.tgz", @@ -17574,6 +18014,27 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/use-sidecar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/use-sync-external-store": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", diff --git a/package.json b/package.json index 7749374be44..4c57b3e0ee1 100644 --- a/package.json +++ b/package.json @@ -57,9 +57,11 @@ "@hello-pangea/dnd": "^17.0.0", "@pnotify/core": "^5.2.0", "@pnotify/mobile": "^5.2.0", + "@radix-ui/react-dropdown-menu": "^2.1.2", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-toast": "^1.2.2", + "@radix-ui/react-tooltip": "^1.1.3", "@sentry/browser": "^8.33.0", "@yudiel/react-qr-scanner": "^2.0.8", "axios": "^1.7.7", diff --git a/public/favicon.ico b/public/favicon.ico index 67a5686e32ffe2212a032deb9ee098827e52f887..d712ea36545e74e1b50e9097c54194bf8e17a6a4 100644 GIT binary patch literal 15086 zcmeHOTW=dh6dpTCn~UwlP8;XaII&#^=T=e@r%4m%QYvyms?<;rNL0`?5f!LFq9P>d zLxHLf`~nd0&VMNMHvny_KJgFQ7odQkI-GC4>x}K0b=GlQn{K6(SJxBaED zquToqa(CPD7CJiGs+8zLn9?7ND02^T5_GW9`L`unoQ@BU`VY7xhtFOeR*D^WE2qLn z=a1OHaFAae@oyjU)7*#p_O&>cT4LO5A9gf8xcoI^Z7I*dZGZdm!|ng-d7ahQp7s6{ zne3po&t_=tbG6KEj!+=lME<@;rF2iW7ahM~qw_~>VCe9{4IHKMAt!%MUmT>(?^d+3 zv^`FBt@`h${mviiczg$j9S3l9`K$Ak+x~93ca05qO{yEfMPod*J3MKqX8CdM0SH75~ z3pdrWaODKG#+u0&X;cbyu+jM=_Q07QCAPtdxq+jOzf>>VWUu>9bP`SGBGjjoSwaBN`Y``P@?8NY1ojF>KexBc__h}(ap`ChfZzrCrWwEoqSHh-*K zOHqB$tIZ$K!A6&Vkl%rk*GKGrJL*5ky~(q^lzJ_pl#ZbQ@!qQ*k9Dxo`6G5-e%Hs! ztou3Q@1R|Z;g(DPf8dWjuyVCWrQ?7*_8=>bTQ0o2!Y4khRsPKVI`-h1|NR=ghx^9) z0i1ydh*jqQpoZ?@0ds!YIKPoOgpxTwlj%!1hl0HHca;e^?V!KQ=Vxw!zbA7O?%&F_ zzzslgyW^ZzKg$A3_M8@<;Zpqb@L8c#{0wjN9O1VE?^_v++rTuaWw4*dS(C@iVT$kf z2bOZ>eW!7LWb8kj;$y!Ob52=GJbwc0f1KcBofhX^VrM!j_M$0#jXJwETnz@W9pU?W z8)^7_U%_51>Y&r$=<1#0^BRg4pLH(2qj$-+{n5Vzyfzga@MWcIJV;}2#0s82>Y$Tt zv95&}HqXQs-^cqY6PFTn`rVqWMS{i+6Qx5!neq| zF5CNe@hj8*$ld+Z9dvRno+BsDMJcw}Nzuh{Rt8pjD78LN&?is_oopLrU&P3d3oLWI zFrI%suTP)7da_{s;@tHq&gr@D57v7nSUrS^#kv1m(mfWU#*T)9n5cu!vO@`9#3&UXemJ{; zTxp5j92+{z4kdhTu%Sc$cl`ZPBxW&8Sr2S{1IcxjyuQQVfYXfsw7x&5&2M0ExWi(7 zk6C%?AWC2u_ibP+76d9;g>?%4uV%(tMRuJ+wQkfR-elenS^jk>4@HZ(X!@4gw}AVE zrNAHGy%TRG48gU^#`IPCcc((xxg4%5<&WWC$3QkT^;2L$%Dg5yc Zh#^Q7L4uE7Qa})CA{G#kqCTZaF(M!( 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 Apa1{> diff --git a/src/CAREUI/icons/UniconPaths.json b/src/CAREUI/icons/UniconPaths.json index 1a76c51570d..64f97d72d65 100644 --- a/src/CAREUI/icons/UniconPaths.json +++ b/src/CAREUI/icons/UniconPaths.json @@ -247,6 +247,10 @@ 24, "M7,11H17a1,1,0,0,0,0-2H13V5.41l.79.8a1,1,0,0,0,1.42,0,1,1,0,0,0,0-1.42l-2.5-2.5a1,1,0,0,0-.33-.21,1,1,0,0,0-.76,0,1,1,0,0,0-.33.21l-2.5,2.5a1,1,0,0,0,1.42,1.42l.79-.8V9H7a1,1,0,0,0,0,2Zm10,2H7a1,1,0,0,0,0,2h4v3.59l-.79-.8a1,1,0,0,0-1.42,1.42l2.5,2.5a1,1,0,0,0,.33.21.94.94,0,0,0,.76,0,1,1,0,0,0,.33-.21l2.5-2.5a1,1,0,0,0-1.42-1.42l-.79.8V15h4a1,1,0,0,0,0-2Z" ], + "l-arrow-bar-right": [ + 24, + "M8.4 12c0 .4.3.7.7.7h8.3l-3.1 3.1c-.3.3-.3.7 0 1s.7.3 1 0l4.3-4.3c.3-.3.3-.7 0-1 0 0 0 0 0 0l-4.3-4.3c-.3-.3-.7-.3-1 0s-.3.7 0 1l3.1 3.1h-8.3c-.4 0-.7.3-.7.7M4.9 22c-.4 0-.7-.3-.7-.7V2.7c0-.4.3-.7.7-.7s.7.3.7.7v18.6c0 .4-.3.7-.7.7" + ], "l-arrow-circle-down": [ 24, "M11.29,15.71a1,1,0,0,0,.33.21,1,1,0,0,0,.76,0,1,1,0,0,0,.33-.21l3-3a1,1,0,0,0-1.42-1.42L13,12.59V9a1,1,0,0,0-2,0v3.59l-1.29-1.3a1,1,0,0,0-1.42,0,1,1,0,0,0,0,1.42ZM12,22A10,10,0,1,0,2,12,10,10,0,0,0,12,22ZM12,4a8,8,0,1,1-8,8A8,8,0,0,1,12,4Z" @@ -2795,6 +2799,14 @@ 24, "M2.5,10.56l9,5.2a1,1,0,0,0,1,0l9-5.2a1,1,0,0,0,0-1.73l-9-5.2a1,1,0,0,0-1,0l-9,5.2a1,1,0,0,0,0,1.73ZM12,5.65l7,4-7,4.05L5,9.69Zm8.5,7.79L12,18.35,3.5,13.44a1,1,0,0,0-1.37.36,1,1,0,0,0,.37,1.37l9,5.2a1,1,0,0,0,1,0l9-5.2a1,1,0,0,0,.37-1.37A1,1,0,0,0,20.5,13.44Z" ], + "l-layout-sidebar": [ + 24, + "M0 4.5C0 2.8 1.3 1.5 3 1.5h18c1.7 0 3 1.3 3 3v15c0 1.7-1.3 3-3 3H3c-1.7 0-3-1.3-3-3V4.5ZM7.5 3v18h13.5c.8 0 1.5-.7 1.5-1.5V4.5c0-.8-.7-1.5-1.5-1.5H7.5ZM6 3h-3c-.8 0-1.5.7-1.5 1.5v15c0 .8.7 1.5 1.5 1.5h3V3Z" + ], + "l-layout-sidebar-alt": [ + 24, + "M21 1.5H3C1.3 1.5 0 2.8 0 4.5v15c0 1.7 1.3 3 3 3h18c1.7 0 3-1.3 3-3V4.5c0-1.7-1.3-3-3-3ZM22.5 19.5c0 .8-.7 1.5-1.5 1.5H3c-.8 0-1.5-.7-1.5-1.5V4.5c0-.8.7-1.5 1.5-1.5h18c.8 0 1.5.7 1.5 1.5v15ZM10.5 6v12c0 .8-.7 1.5-1.5 1.5h-3c-.8 0-1.5-.7-1.5-1.5V6c0-.8.7-1.5 1.5-1.5h3c.8 0 1.5.7 1.5 1.5Z" + ], "l-left-arrow-from-left": [ 24, "M17,11H5.41l2.3-2.29A1,1,0,1,0,6.29,7.29l-4,4a1,1,0,0,0-.21.33,1,1,0,0,0,0,.76,1,1,0,0,0,.21.33l4,4a1,1,0,0,0,1.42,0,1,1,0,0,0,0-1.42L5.41,13H17a1,1,0,0,0,0-2Zm4-7a1,1,0,0,0-1,1V19a1,1,0,0,0,2,0V5A1,1,0,0,0,21,4Z" diff --git a/src/Components/Common/Breadcrumbs.tsx b/src/Components/Common/Breadcrumbs.tsx index aaee7ac0b64..be35cf6862d 100644 --- a/src/Components/Common/Breadcrumbs.tsx +++ b/src/Components/Common/Breadcrumbs.tsx @@ -63,7 +63,7 @@ export default function Breadcrumbs({ return (
  • @@ -90,7 +90,7 @@ export default function Breadcrumbs({
  • + + +

    {shrinked ? t("expand_sidebar") : t("collapse_sidebar")}

    +
    + + + ); +}; diff --git a/src/Components/Common/Sidebar/SidebarItem.tsx b/src/Components/Common/Sidebar/SidebarItem.tsx index eeee4284e2f..6db51bbac3a 100644 --- a/src/Components/Common/Sidebar/SidebarItem.tsx +++ b/src/Components/Common/Sidebar/SidebarItem.tsx @@ -29,9 +29,9 @@ const SidebarItemBase = forwardRef( return ( ( {t(props.text)} diff --git a/src/Components/Common/Sidebar/SidebarUserCard.tsx b/src/Components/Common/Sidebar/SidebarUserCard.tsx index 4630438ab70..825507ffb25 100644 --- a/src/Components/Common/Sidebar/SidebarUserCard.tsx +++ b/src/Components/Common/Sidebar/SidebarUserCard.tsx @@ -5,6 +5,13 @@ import CareIcon from "../../../CAREUI/icons/CareIcon"; import { formatName, formatDisplayName } from "../../../Utils/utils"; import useAuthUser, { useAuthContext } from "../../../Common/hooks/useAuthUser"; import { Avatar } from "@/Components/Common/Avatar"; +import { Button } from "@/Components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/Components/ui/dropdown-menu"; interface SidebarUserCardProps { shrinked: boolean; @@ -16,41 +23,59 @@ const SidebarUserCard: React.FC = ({ shrinked }) => { const { signOut } = useAuthContext(); return ( -
    - -
    -
    - -
    - {!shrinked && ( - - {formatName(user)} - - )} -
    - -
    -
    - - {!shrinked && ( -
    - {t("sign_out")} +
    + + +
    -
    +
    + +
    +
    + + + +
    {t("profile")}
    +
    + + +
    {t("sign_out")}
    +
    +
    +
    + + +
    ); }; diff --git a/src/Components/Facility/FacilityList.tsx b/src/Components/Facility/FacilityList.tsx index 503f0fde34d..9143ec29355 100644 --- a/src/Components/Facility/FacilityList.tsx +++ b/src/Components/Facility/FacilityList.tsx @@ -145,7 +145,7 @@ export const FacilityList = () => { return ( { if (loading) return ; return ( - +
    {notices}
    ); diff --git a/src/Components/Patient/ManagePatients.tsx b/src/Components/Patient/ManagePatients.tsx index 46dad347dd5..5259909bebe 100644 --- a/src/Components/Patient/ManagePatients.tsx +++ b/src/Components/Patient/ManagePatients.tsx @@ -786,7 +786,7 @@ export const PatientManager = () => { return (
    , + React.ComponentPropsWithoutRef & { + inset?: boolean; + } +>(({ className, inset, children, ...props }, ref) => ( + + {children} + + +)); +DropdownMenuSubTrigger.displayName = + DropdownMenuPrimitive.SubTrigger.displayName; + +const DropdownMenuSubContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DropdownMenuSubContent.displayName = + DropdownMenuPrimitive.SubContent.displayName; + +const DropdownMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, sideOffset = 4, ...props }, ref) => ( + + + +)); +DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName; + +const DropdownMenuItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean; + } +>(({ className, inset, ...props }, ref) => ( + +)); +DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName; + +const DropdownMenuCheckboxItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, checked, ...props }, ref) => ( + + + + + + + {children} + +)); +DropdownMenuCheckboxItem.displayName = + DropdownMenuPrimitive.CheckboxItem.displayName; + +const DropdownMenuRadioItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + {children} + +)); +DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName; + +const DropdownMenuLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean; + } +>(({ className, inset, ...props }, ref) => ( + +)); +DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName; + +const DropdownMenuSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName; + +const DropdownMenuShortcut = ({ + className, + ...props +}: React.HTMLAttributes) => { + return ( + + ); +}; +DropdownMenuShortcut.displayName = "DropdownMenuShortcut"; + +export { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuCheckboxItem, + DropdownMenuRadioItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuGroup, + DropdownMenuPortal, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuRadioGroup, +}; diff --git a/src/Components/ui/tooltip.tsx b/src/Components/ui/tooltip.tsx new file mode 100644 index 00000000000..be192b1fb66 --- /dev/null +++ b/src/Components/ui/tooltip.tsx @@ -0,0 +1,28 @@ +import * as React from "react"; +import * as TooltipPrimitive from "@radix-ui/react-tooltip"; + +import { cn } from "@/lib/utils"; + +const TooltipProvider = TooltipPrimitive.Provider; + +const Tooltip = TooltipPrimitive.Root; + +const TooltipTrigger = TooltipPrimitive.Trigger; + +const TooltipContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, sideOffset = 4, ...props }, ref) => ( + +)); +TooltipContent.displayName = TooltipPrimitive.Content.displayName; + +export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }; diff --git a/src/Locale/en.json b/src/Locale/en.json index 0df3c961e10..94e9bd0f3a9 100644 --- a/src/Locale/en.json +++ b/src/Locale/en.json @@ -88,8 +88,8 @@ "state": "State", "location": "Location", "ward": "Ward", - "Notice Board": "Notice Board", - "Assets": "Assets", + "notice_board": "Notice Board", + "assets": "Assets", "Notifications": "Notifications", "Submit": "Submit", "Cancel": "Cancel", @@ -416,14 +416,10 @@ "help_entered-in-error": "The statement was entered in error and is not valid.", "search_icd11_placeholder": "Search for ICD-11 Diagnoses", "icd11_as_recommended": "As per ICD-11 recommended by WHO", - "Facilities": "Facilities", - "Patients": "Patients", - "Sample Test": "Sample Test", - "Shifting": "Shifting", - "Resource": "Resource", - "Users": "Users", - "Profile": "Profile", - "Dashboard": "Dashboard", + "patients": "Patients", + "sample_test": "Sample Test", + "resource": "Resource", + "profile": "Profile", "return_to_care": "Return to CARE", "404_message": "It appears that you have stumbled upon a page that either does not exist or has been moved to another URL. Make sure you have entered the correct link!", "error_404": "Error 404", @@ -1050,5 +1046,7 @@ "patient_details": "Patient Details", "width": "Width ({{unit}})", "length": "Length ({{unit}})", + "expand_sidebar": "Expand Sidebar", + "collapse_sidebar": "Collapse Sidebar", "linked_skills": "Linked Skills" } \ No newline at end of file From 1c1db13c63337df7e5f2585023e00cf230b2e1b9 Mon Sep 17 00:00:00 2001 From: Aditya Jindal Date: Wed, 16 Oct 2024 17:39:46 +0530 Subject: [PATCH 6/9] Fixing: Switch Blood Pressure and temperature dropdown to use TextFormField with type="number" instead of a dropdown #8644 (#8728) --- .../e2e/patient_spec/PatientLogUpdate.cy.ts | 4 +- .../pageobject/Patient/PatientLogupdate.ts | 10 +- .../Common/BloodPressureFormField.tsx | 87 ++++------ .../Common/TemperatureFormField.tsx | 155 ++++++++++-------- src/Components/Patient/DailyRounds.tsx | 24 ++- src/Locale/en.json | 6 + 6 files changed, 155 insertions(+), 131 deletions(-) diff --git a/cypress/e2e/patient_spec/PatientLogUpdate.cy.ts b/cypress/e2e/patient_spec/PatientLogUpdate.cy.ts index 7faaeed5a9f..3907784b4b7 100644 --- a/cypress/e2e/patient_spec/PatientLogUpdate.cy.ts +++ b/cypress/e2e/patient_spec/PatientLogUpdate.cy.ts @@ -302,9 +302,9 @@ describe("Patient Log Update in Normal, Critical and TeleIcu", () => { patientRhythm, ]); patientLogupdate.clickUpdateDetail(); - patientLogupdate.clickClearButtonInElement("#systolic"); + patientLogupdate.clearIntoElementById("#systolic"); patientLogupdate.typeSystolic(patientModifiedSystolic); - patientLogupdate.clickClearButtonInElement("#diastolic"); + patientLogupdate.clearIntoElementById("#diastolic"); patientLogupdate.typeDiastolic(patientModifiedDiastolic); cy.submitButton("Continue"); cy.verifyNotification("Brief Update updated successfully"); diff --git a/cypress/pageobject/Patient/PatientLogupdate.ts b/cypress/pageobject/Patient/PatientLogupdate.ts index 857fe7dd972..d7b49fde05e 100644 --- a/cypress/pageobject/Patient/PatientLogupdate.ts +++ b/cypress/pageobject/Patient/PatientLogupdate.ts @@ -43,11 +43,11 @@ class PatientLogupdate { } typeSystolic(systolic: string) { - cy.typeAndSelectOption("#systolic", systolic); + cy.get("#systolic").click().type(systolic); } typeDiastolic(diastolic: string) { - cy.typeAndSelectOption("#diastolic", diastolic); + cy.get("#diastolic").click().type(diastolic); } typePulse(pulse: string) { @@ -55,7 +55,7 @@ class PatientLogupdate { } typeTemperature(temperature: string) { - cy.typeAndSelectOption("#temperature", temperature); + cy.get("#temperature").click().type(temperature); } typeRespiratory(respiratory: string) { @@ -93,8 +93,8 @@ class PatientLogupdate { cy.wait(3000); } - clickClearButtonInElement(elementId: string) { - cy.get(elementId).find("#clear-button").click(); + clearIntoElementById(elementId) { + cy.get(elementId).click().clear(); } clickVitals() { diff --git a/src/Components/Common/BloodPressureFormField.tsx b/src/Components/Common/BloodPressureFormField.tsx index e6fff756d0f..beddd34cf38 100644 --- a/src/Components/Common/BloodPressureFormField.tsx +++ b/src/Components/Common/BloodPressureFormField.tsx @@ -1,13 +1,13 @@ import { useTranslation } from "react-i18next"; import { FieldValidator } from "../Form/FieldValidators"; import FormField from "../Form/FormFields/FormField"; -import RangeAutocompleteFormField from "../Form/FormFields/RangeAutocompleteFormField"; import { FieldChangeEvent, FormFieldBaseProps, useFormFieldPropsResolver, } from "../Form/FormFields/Utils"; import { BloodPressure } from "../Patient/models"; +import TextFormField from "../Form/FormFields/TextFormField"; type Props = FormFieldBaseProps; @@ -16,12 +16,13 @@ export default function BloodPressureFormField(props: Props) { const field = useFormFieldPropsResolver(props); const map = meanArterialPressure(props.value)?.toFixed(); - const handleChange = (event: FieldChangeEvent) => { + const handleChange = (event: FieldChangeEvent) => { + const value = event.value ? parseInt(event.value, 10) : ""; const bp = { systolic: field.value?.systolic, diastolic: field.value?.diastolic, }; - bp[event.name as keyof BloodPressure] = event.value; + bp[event.name as keyof BloodPressure] = value || undefined; field.handleChange(Object.values(bp).filter(Boolean).length ? bp : null); }; @@ -32,63 +33,35 @@ export default function BloodPressureFormField(props: Props) { labelSuffix: map && MAP: {map}, }} > -
    - + - / - / +
    @@ -102,14 +75,20 @@ export const meanArterialPressure = (bp?: BloodPressure | null) => { return (2 * bp.diastolic + bp.systolic) / 3; }; -export const BloodPressureValidator: FieldValidator = (bp) => { +export const BloodPressureValidator: FieldValidator = ( + bp, + t, +) => { if (Object.values(bp).every((v) => v == null)) { return; } - if (bp.diastolic == null) { - return "Diastolic is missing. Either specify both or clear both."; + if (bp.systolic == null || bp.diastolic == null) { + return t("blood_pressure_error.missing"); + } + if (bp.systolic > 250 || bp.diastolic > 250) { + return t("blood_pressure_error.exceed"); } - if (bp.systolic == null) { - return "Systolic is missing. Either specify both or clear both."; + if (bp.systolic < bp.diastolic) { + return t("blood_pressure_error.systolic_less_than_diastolic"); } }; diff --git a/src/Components/Common/TemperatureFormField.tsx b/src/Components/Common/TemperatureFormField.tsx index 236d87826e9..7b2d7124f09 100644 --- a/src/Components/Common/TemperatureFormField.tsx +++ b/src/Components/Common/TemperatureFormField.tsx @@ -1,77 +1,100 @@ -import { useState } from "react"; -import { FormFieldBaseProps } from "../Form/FormFields/Utils"; -import RangeAutocompleteFormField from "../Form/FormFields/RangeAutocompleteFormField"; +import { useState, useEffect } from "react"; +import { FieldChangeEvent, FormFieldBaseProps } from "../Form/FormFields/Utils"; +import { fahrenheitToCelsius, celsiusToFahrenheit } from "@/Utils/utils"; import CareIcon from "../../CAREUI/icons/CareIcon"; import ButtonV2 from "./components/ButtonV2"; -import { fahrenheitToCelsius } from "../../Utils/utils"; +import TextFormField from "../Form/FormFields/TextFormField"; type TemperatureUnit = "celsius" | "fahrenheit"; -type Props = FormFieldBaseProps & { - placeholder?: string; -}; +type TemperatureFormFieldProps = FormFieldBaseProps; -export default function TemperatureFormField(props: Props) { +export default function TemperatureFormField({ + onChange, + id, + label, + error, + value, + name, +}: TemperatureFormFieldProps) { const [unit, setUnit] = useState("fahrenheit"); + const [inputValue, setInputValue] = useState(value || ""); + + useEffect(() => { + if (value) { + const initialTemperature = + unit === "celsius" + ? fahrenheitToCelsius(parseFloat(value)).toFixed(1) + : value; + setInputValue(initialTemperature); + } + }, [value, unit]); + + const handleUnitChange = () => { + setUnit(unit === "celsius" ? "fahrenheit" : "celsius"); + if (inputValue) { + const convertedValue = + unit === "celsius" + ? celsiusToFahrenheit(parseFloat(inputValue)).toFixed(1) + : fahrenheitToCelsius(parseFloat(inputValue)).toFixed(1); + setInputValue(convertedValue); + } + }; + + const handleInputChange = (e: FieldChangeEvent) => { + const newValue = e.value; + + const regex = /^-?\d*\.?\d{0,1}$/; + if (regex.test(newValue)) { + setInputValue(newValue); + } + }; + + const handleBlur = () => { + if (!inputValue) return; + const parsedValue = parseFloat(inputValue); + if (isNaN(parsedValue)) return; + + const finalValue = + unit === "celsius" + ? celsiusToFahrenheit(parsedValue).toString() + : parsedValue.toString(); + + setInputValue(finalValue); + onChange({ name, value: finalValue }); + }; return ( - , - className: "text-danger-500", - }, - { - value: 96.6, - label: "Low", - icon: , - className: "text-warning-500", - }, - { - value: 97.6, - label: "Normal", - icon: , - className: "text-primary-500", - }, - { - value: 99.6, - label: "High", - icon: , - className: "text-warning-500", - }, - { - value: 101.6, - label: "High", - icon: , - className: "text-danger-500", - }, - ]} - optionLabel={(value) => { - const val = unit === "celsius" ? fahrenheitToCelsius(value) : value; - return val.toFixed(1); - }} - labelSuffix={ - setUnit(unit === "celsius" ? "fahrenheit" : "celsius")} - > - - - } - /> +
    + + + + + +
    ); } diff --git a/src/Components/Patient/DailyRounds.tsx b/src/Components/Patient/DailyRounds.tsx index bf25d48f6bf..3e10383e78a 100644 --- a/src/Components/Patient/DailyRounds.tsx +++ b/src/Components/Patient/DailyRounds.tsx @@ -1,5 +1,4 @@ import { navigate } from "raviger"; - import dayjs from "dayjs"; import { useCallback, useEffect, useState } from "react"; import { @@ -126,7 +125,6 @@ export const DailyRounds = (props: any) => { return state; } }; - const [state, dispatch] = useAutoSaveReducer( DailyRoundsFormReducer, initialState, @@ -249,7 +247,9 @@ export const DailyRounds = (props: any) => { } return; case "bp": { - const error = state.form.bp && BloodPressureValidator(state.form.bp); + const error = + state.form.bp && BloodPressureValidator(state.form.bp, t); + if (error) { errors.bp = error; invalidForm = true; @@ -258,6 +258,23 @@ export const DailyRounds = (props: any) => { return; } + case "temperature": { + const temperatureInputValue = state.form["temperature"]; + + if ( + temperatureInputValue && + (temperatureInputValue < 95 || temperatureInputValue > 106) + ) { + errors[field] = t("out_of_range_error", { + start: "95°F (35°C)", + end: "106°F (41.1°C)", + }); + invalidForm = true; + scrollTo("temperature"); + } + return; + } + case "investigations": { for (const investigation of state.form.investigations) { if (!investigation.type?.length) { @@ -773,7 +790,6 @@ export const DailyRounds = (props: any) => { /> )} - {["NORMAL", "TELEMEDICINE", "DOCTORS_LOG"].includes( state.form.rounds_type, ) && ( diff --git a/src/Locale/en.json b/src/Locale/en.json index 94e9bd0f3a9..5f2652fa91b 100644 --- a/src/Locale/en.json +++ b/src/Locale/en.json @@ -813,6 +813,12 @@ "map_acronym": "M.A.P.", "systolic": "Systolic", "diastolic": "Diastolic", + "blood_pressure_error": { + "missing": "Field is required. Either specify both or clear both.", + "exceed": "Value cannot exceed 250 mmHg.", + "systolic_less_than_diastolic": "Systolic must be greater than diastolic." + }, + "out_of_range_error": "Value must be between {{ start }} and {{ end }}.", "pain": "Pain", "pain_chart_description": "Mark region and intensity of pain", "bradycardia": "Bradycardia", From 7491447557fdf9ab43842005b56c49a20df2f351 Mon Sep 17 00:00:00 2001 From: Jacob John Jeevan <40040905+Jacobjeevan@users.noreply.github.com> Date: Wed, 16 Oct 2024 17:40:46 +0530 Subject: [PATCH 7/9] Map mobile view fix (#8793) --- src/Components/Common/GLocationPicker.tsx | 2 +- src/Components/Facility/FacilityCreate.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Common/GLocationPicker.tsx b/src/Components/Common/GLocationPicker.tsx index 0b03d2775ce..1c9c8f963b6 100644 --- a/src/Components/Common/GLocationPicker.tsx +++ b/src/Components/Common/GLocationPicker.tsx @@ -83,7 +83,7 @@ const GLocationPicker = ({ }; return ( -
    +
    { leaveFrom="opacity-100 translate-y-0" leaveTo="opacity-0 translate-y-1" > - + Date: Wed, 16 Oct 2024 17:44:44 +0530 Subject: [PATCH 8/9] Added Infinite Scrolling and Previous Item Persistence in Notifications (#8771) --- .../Notifications/NotificationsList.tsx | 54 ++++++++++++------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/src/Components/Notifications/NotificationsList.tsx b/src/Components/Notifications/NotificationsList.tsx index de9618809b4..30c380fe9a6 100644 --- a/src/Components/Notifications/NotificationsList.tsx +++ b/src/Components/Notifications/NotificationsList.tsx @@ -1,5 +1,5 @@ import { navigate } from "raviger"; -import { useEffect, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import Spinner from "../Common/Spinner"; import { NOTIFICATION_EVENTS } from "../../Common/constants"; import { Error, Success, Warn } from "../../Utils/Notifications.js"; @@ -183,6 +183,7 @@ export default function NotificationsList({ const [isSubscribed, setIsSubscribed] = useState(""); const [isSubscribing, setIsSubscribing] = useState(false); const [showUnread, setShowUnread] = useState(false); + const observerRef = useRef(null); const { t } = useTranslation(); useEffect(() => { @@ -194,6 +195,26 @@ export default function NotificationsList({ if (open) document.addEventListener("keydown", handleKeyDown); return () => document.removeEventListener("keydown", handleKeyDown); }, [open]); + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + if (entries[0].isIntersecting && data.length < totalCount) { + setOffset((prevOffset) => prevOffset + RESULT_LIMIT); + } + }, + { threshold: 1.0 }, + ); + + if (observerRef.current) { + observer.observe(observerRef.current); + } + + return () => { + if (observerRef.current) { + observer.unobserve(observerRef.current); + } + }; + }, [data, totalCount]); useEffect(() => { let intervalId: ReturnType; if (isSubscribing) { @@ -374,7 +395,15 @@ export default function NotificationsList({ }) .then((res) => { if (res && res.data) { - setData(res.data.results); + setData((prev) => { + const newNotifications = res?.data?.results || []; + const allNotifications = + offset === 0 ? newNotifications : [...prev, ...newNotifications]; + const uniqueNotifications = Array.from( + new Set(allNotifications.map((n) => n.id)), + ).map((id) => allNotifications.find((n) => n.id === id)); + return uniqueNotifications; + }); setUnreadCount( res.data.results?.reduce( (acc: number, result: any) => acc + (result.read_at ? 0 : 1), @@ -391,7 +420,9 @@ export default function NotificationsList({ }); intialSubscriptionState(); }, [reload, open, offset, eventFilter, isSubscribed]); - + useEffect(() => { + setOffset(0); + }, [eventFilter, showUnread]); if (!offset && isLoading) { manageResults = (
    @@ -414,27 +445,12 @@ export default function NotificationsList({ setShowNotifications={setOpen} /> ))} +
    {isLoading && (
    )} - {!showUnread && - totalCount > RESULT_LIMIT && - offset < totalCount - RESULT_LIMIT && ( -
    - setOffset((prev) => prev + RESULT_LIMIT)} - > - {isLoading ? t("loading") : t("load_more")} - -
    - )} ); } else if (data && data.length === 0) { From 7e25fc6a5b7baf1156b8db8aaf394752d0c1303b Mon Sep 17 00:00:00 2001 From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> Date: Wed, 16 Oct 2024 14:24:53 +0200 Subject: [PATCH 9/9] fixed the favicon (#8803) --- public/favicon.ico | Bin 15086 -> 161630 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/public/favicon.ico b/public/favicon.ico index d712ea36545e74e1b50e9097c54194bf8e17a6a4..51fe5064a91773fc5c8e5001cb20f61ac00b4bca 100644 GIT binary patch literal 161630 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 literal 15086 zcmeHOTW=dh6dpTCn~UwlP8;XaII&#^=T=e@r%4m%QYvyms?<;rNL0`?5f!LFq9P>d zLxHLf`~nd0&VMNMHvny_KJgFQ7odQkI-GC4>x}K0b=GlQn{K6(SJxBaED zquToqa(CPD7CJiGs+8zLn9?7ND02^T5_GW9`L`unoQ@BU`VY7xhtFOeR*D^WE2qLn z=a1OHaFAae@oyjU)7*#p_O&>cT4LO5A9gf8xcoI^Z7I*dZGZdm!|ng-d7ahQp7s6{ zne3po&t_=tbG6KEj!+=lME<@;rF2iW7ahM~qw_~>VCe9{4IHKMAt!%MUmT>(?^d+3 zv^`FBt@`h${mviiczg$j9S3l9`K$Ak+x~93ca05qO{yEfMPod*J3MKqX8CdM0SH75~ z3pdrWaODKG#+u0&X;cbyu+jM=_Q07QCAPtdxq+jOzf>>VWUu>9bP`SGBGjjoSwaBN`Y``P@?8NY1ojF>KexBc__h}(ap`ChfZzrCrWwEoqSHh-*K zOHqB$tIZ$K!A6&Vkl%rk*GKGrJL*5ky~(q^lzJ_pl#ZbQ@!qQ*k9Dxo`6G5-e%Hs! ztou3Q@1R|Z;g(DPf8dWjuyVCWrQ?7*_8=>bTQ0o2!Y4khRsPKVI`-h1|NR=ghx^9) z0i1ydh*jqQpoZ?@0ds!YIKPoOgpxTwlj%!1hl0HHca;e^?V!KQ=Vxw!zbA7O?%&F_ zzzslgyW^ZzKg$A3_M8@<;Zpqb@L8c#{0wjN9O1VE?^_v++rTuaWw4*dS(C@iVT$kf z2bOZ>eW!7LWb8kj;$y!Ob52=GJbwc0f1KcBofhX^VrM!j_M$0#jXJwETnz@W9pU?W z8)^7_U%_51>Y&r$=<1#0^BRg4pLH(2qj$-+{n5Vzyfzga@MWcIJV;}2#0s82>Y$Tt zv95&}HqXQs-^cqY6PFTn`rVqWMS{i+6Qx5!neq| zF5CNe@hj8*$ld+Z9dvRno+BsDMJcw}Nzuh{Rt8pjD78LN&?is_oopLrU&P3d3oLWI zFrI%suTP)7da_{s;@tHq&gr@D57v7nSUrS^#kv1m(mfWU#*T)9n5cu!vO@`9#3&UXemJ{; zTxp5j92+{z4kdhTu%Sc$cl`ZPBxW&8Sr2S{1IcxjyuQQVfYXfsw7x&5&2M0ExWi(7 zk6C%?AWC2u_ibP+76d9;g>?%4uV%(tMRuJ+wQkfR-elenS^jk>4@HZ(X!@4gw}AVE zrNAHGy%TRG48gU^#`IPCcc((xxg4%5<&WWC$3QkT^;2L$%Dg5yc Z