diff --git a/.cursorrules b/.cursorrules
new file mode 100644
index 0000000..b653a4c
--- /dev/null
+++ b/.cursorrules
@@ -0,0 +1,17 @@
+You are an expert developer specializing in React, Vite, and TypeScript, with deep knowledge of microfrontend architecture. You are assisting with development in a Vite-based project that will be used as a microfrontend module within the Open Health Care Network (OHCN) Care Frontend system (github.com/ohcnetwork/care_fe).
+
+Key considerations for your responses:
+1. All code should be written in TypeScript with proper type definitions
+2. Follow React best practices and modern hooks-based patterns
+3. Ensure compatibility with Vite's module federation for microfrontend architecture
+4. Follow accessibility guidelines for healthcare applications
+5. Use proper code organization that aligns with microfrontend architecture
+
+When providing solutions:
+- Include TypeScript types/interfaces where applicable
+- Explain architectural decisions and their impact on the microfrontend setup
+- Consider state management patterns that work well in a microfrontend context
+- Provide guidance on testing strategies when relevant
+- Include comments explaining complex logic or integration points
+
+The code being developed will be part of a larger EMR system, so maintain focus on healthcare-specific requirements with the main Care Frontend application.
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 02331a2..7663cf2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -47,3 +47,6 @@ vite.config.ts.timestamp-*
# Temporary files
*.tmp
*.bak
+
+# Ignore core symlink
+/core
diff --git a/package-lock.json b/package-lock.json
index d542744..798ba02 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,7 +11,8 @@
"dependencies": {
"@livekit/components-react": "^2.6.2",
"@livekit/components-styles": "^1.1.3",
- "livekit-client": "^2.5.5"
+ "livekit-client": "^2.5.5",
+ "raviger": "^4.1.2"
},
"devDependencies": {
"@originjs/vite-plugin-federation": "^1.3.6",
@@ -1201,6 +1202,17 @@
"node": "^10 || ^12 || >=14"
}
},
+ "node_modules/raviger": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/raviger/-/raviger-4.1.2.tgz",
+ "integrity": "sha512-w5SodiqNhlFLl5zpvZxICdT+ORM+b0YI6w0jlJJS/yzOM1MRIN1nGQvOzds/tWKrN0V1vUBzttkEv7djHQUMdA==",
+ "engines": {
+ "node": ">=12"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/react": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
diff --git a/package.json b/package.json
index 406edc4..2a29af2 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,8 @@
"dependencies": {
"@livekit/components-react": "^2.6.2",
"@livekit/components-styles": "^1.1.3",
- "livekit-client": "^2.5.5"
+ "livekit-client": "^2.5.5",
+ "raviger": "^4.1.2"
},
"peerDependencies": {
"react": "18.3.1",
diff --git a/src/api/README.md b/src/api/README.md
new file mode 100644
index 0000000..ca3e223
--- /dev/null
+++ b/src/api/README.md
@@ -0,0 +1,144 @@
+# CARE's data fetching utilities: `useQuery` and `request`
+
+There are two main ways to fetch data in CARE: `useQuery` and `request`. Both of these utilities are built on top of [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch).
+
+## `useQuery`
+
+`useQuery` is a React hook that allows you to fetch data and automatically update the UI when the data changes. It is
+a wrapper around `request` that is designed to be used in React components. Only "GET" requests are supported with `useQuery`. For other request methods (mutations), use `request`.
+
+### Usage
+
+```jsx
+import { useQuery } from "@care/request";
+import FooRoutes from "@foo/routes";
+
+export default function FooDetails({ children, id }) {
+ const { res, data, loading, error } = useQuery(FooRoutes.getFoo, {
+ pathParams: { id },
+ });
+
+ /* 🪄 Here typeof data is automatically inferred from the specified route. */
+
+ if (loading) return ;
+
+ if (res.status === 403) {
+ navigate("/forbidden");
+ return null;
+ }
+
+ if (error) {
+ return ;
+ }
+
+ return (
+
+ {data.id}
+ {data.name}
+
+ );
+}
+```
+
+### API
+
+```ts
+useQuery(route: Route, options?: QueryOptions): ReturnType;
+```
+
+#### `route`
+
+A route object that specifies the endpoint to fetch data from.
+
+```ts
+const FooRoutes = {
+ getFoo: {
+ path: "/api/v1/foo/{id}/", // 👈 The path to the endpoint. Slug parameters can be specified using curly braces.
+
+ method: "GET", // 👈 The HTTP method to use. Optional; defaults to "GET".
+ TRes: Type(), // 👈 The type of the response body (for type inference).
+ TBody: Type(), // 👈 The type of the request body (for type inference).
+ noAuth: true, // 👈 Whether to skip adding the Authorization header to the request.
+ },
+} as const; // 👈 This is important for type inference to work properly.
+```
+
+#### `options`
+
+An object that specifies options for the request.
+
+```ts
+const options = {
+ prefetch: true, // 👈 Whether to prefetch the data when the component mounts.
+ refetchOnWindowFocus: true, // 👈 Whether to refetch the data when the window regains focus.
+
+ // The following options are passed directly to the underlying `request` function.
+
+ pathParams: { id: "123" }, // 👈 The slug parameters to use in the path.
+ // If you accidentally forget to specify a slug parameter an error will be
+ // thrown before the request is made.
+
+ query: { limit: 10 }, // 👈 The query parameters to be added to the request URL.
+ body: { name: "foo" }, // 👈 The body to be sent with the request. Should be compatible with the TBody type of the route.
+ headers: { "X-Foo": "bar" }, // 👈 Additional headers to be sent with the request. (Coming soon...)
+
+ silent: true, // 👈 Whether to suppress notifications for this request.
+ // This is useful for requests that are made in the background.
+
+ reattempts: 3, // 👈 The number of times to retry the request if it fails.
+ // Reattempts are only made if the request fails due to a network error. Responses with
+ // status codes in the 400s and 500s are not retried.
+
+ onResponse: (res) => {
+ // 👈 An optional callback that is called after the response is received.
+ if (res.status === 403) {
+ navigate("/forbidden");
+ }
+ },
+ // This is useful for handling responses with status codes in the 400s and 500s for a specific request.
+};
+```
+
+#### `ReturnType`
+
+The `useQuery` hook returns an object with the following properties:
+
+```ts
+{
+ res: Type | undefined; // 👈 The response object. `undefined` if the request has not been made yet.
+
+ data: TRes | null; // 👈 The response body. `null` if the request has not been made yet.
+
+ error: any; // 👈 The error that occurred while making the request if any.
+
+ loading: boolean; // 👈 Whether the request is currently in progress.
+
+ refetch: () => void; // 👈 A function that can be called to refetch the data.
+ // Ideal for revalidating stale data after a mutation.
+}
+```
+
+## `request`
+
+`request` is a function that allows you to fetch data. It is a wrapper around `fetch` that adds some useful features. It can be used in both React components and non-React code. For fetching data in React components, prefer using `useQuery`. For mutations, use `request`.
+
+### `request` usage
+
+```ts
+import { request } from "@care/request";
+import FooRoutes from "@foo/routes";
+
+export default async function updateFoo(id: string, object: Foo) {
+ const { res, data } = await request(FooRoutes.updateFoo, {
+ pathParams: { id },
+ body: object, // 👈 The body is automatically serialized to JSON. Should be compatible with the TBody type of the route.
+ });
+
+ if (res.status === 403) {
+ navigate("/forbidden");
+ return null;
+ }
+
+ return data;
+}
+```
diff --git a/src/api/api.tsx b/src/api/api.tsx
index 3b77d54..2e8ff55 100644
--- a/src/api/api.tsx
+++ b/src/api/api.tsx
@@ -1,4 +1,46 @@
-import { Type } from "@/Redux/api";
+/**
+ * A fake function that returns an empty object casted to type T
+ * @returns Empty object as type T
+ */
+export function Type(): T {
+ return {} as T;
+}
+
+export interface JwtTokenObtainPair {
+ access: string;
+ refresh: string;
+}
+
+export const USER_TYPE_OPTIONS = [
+ { id: "Pharmacist", role: "Pharmacist", readOnly: false },
+ { id: "Volunteer", role: "Volunteer", readOnly: false },
+ { id: "StaffReadOnly", role: "Staff", readOnly: true },
+ { id: "Staff", role: "Staff", readOnly: false },
+ // { id: "NurseReadOnly", role: "Nurse", readOnly: true },
+ { id: "Nurse", role: "Nurse", readOnly: false },
+ { id: "Doctor", role: "Doctor", readOnly: false },
+ { id: "WardAdmin", role: "Ward Admin", readOnly: false },
+ { id: "LocalBodyAdmin", role: "Local Body Admin", readOnly: false },
+ { id: "DistrictLabAdmin", role: "District Lab Admin", readOnly: false },
+ { id: "DistrictReadOnlyAdmin", role: "District Admin", readOnly: true },
+ { id: "DistrictAdmin", role: "District Admin", readOnly: false },
+ { id: "StateLabAdmin", role: "State Lab Admin", readOnly: false },
+ { id: "StateReadOnlyAdmin", role: "State Admin", readOnly: true },
+ { id: "StateAdmin", role: "State Admin", readOnly: false },
+] as const;
+
+export type UserRole = (typeof USER_TYPE_OPTIONS)[number]["id"];
+
+export type UserBareMinimum = {
+ id: number;
+ username: string;
+ first_name: string;
+ last_name: string;
+ email: string;
+ user_type: UserRole;
+ last_login: string | undefined;
+ read_profile_picture_url?: string;
+};
export interface LiveKitTokenRequest {
source: string;
@@ -12,6 +54,12 @@ export interface LiveKitTokenResponse {
}
const routes = {
+ // User Endpoints
+ currentUser: {
+ path: "/api/v1/users/getcurrentuser/",
+ TRes: Type(),
+ },
+ // Livekit Endpoints
livekit: {
create_room: {
path: "/api/care_livekit/create_room/",
diff --git a/src/api/request.ts b/src/api/request.ts
new file mode 100644
index 0000000..730b53e
--- /dev/null
+++ b/src/api/request.ts
@@ -0,0 +1,104 @@
+import careConfig from "@careConfig";
+
+import handleResponse from "@/api/handleResponse";
+import { RequestOptions, RequestResult, Route } from "@/api/types";
+import { makeHeaders, makeUrl } from "@/api/utils";
+
+type ControllerXORControllerRef =
+ | {
+ controller?: AbortController;
+ controllerRef?: undefined;
+ }
+ | {
+ controller?: undefined;
+ controllerRef: React.MutableRefObject;
+ };
+
+type Options = RequestOptions &
+ ControllerXORControllerRef;
+
+export default async function request(
+ { path, method, noAuth }: Route,
+ {
+ query,
+ body,
+ pathParams,
+ controller,
+ controllerRef,
+ onResponse,
+ silent,
+ reattempts = 3,
+ }: Options = {}
+): Promise> {
+ if (controllerRef) {
+ controllerRef.current?.abort();
+ controllerRef.current = new AbortController();
+ }
+
+ const signal = controller?.signal ?? controllerRef?.current?.signal;
+ const url = `${careConfig.apiUrl}${makeUrl(path, query, pathParams)}`;
+
+ const options: RequestInit = { method, signal };
+
+ if (body) {
+ options.body = JSON.stringify(body);
+ }
+
+ let result: RequestResult = {
+ res: undefined,
+ data: undefined,
+ error: undefined,
+ };
+
+ for (let i = 0; i < reattempts + 1; i++) {
+ options.headers = makeHeaders(noAuth ?? false);
+
+ try {
+ const res = await fetch(url, options);
+
+ const data = await getResponseBody(res);
+
+ result = {
+ res,
+ data: res.ok ? data : undefined,
+ error: res.ok ? undefined : (data as Record),
+ };
+
+ onResponse?.(result);
+ handleResponse(result, silent);
+
+ return result;
+ } catch (error: any) {
+ result = { error, res: undefined, data: undefined };
+ }
+ }
+
+ console.error(
+ `Request failed after ${reattempts + 1} attempts`,
+ result.error
+ );
+ return result;
+}
+
+async function getResponseBody(res: Response): Promise {
+ if (!(res.headers.get("content-length") !== "0")) {
+ return null as TData;
+ }
+
+ const isJson = res.headers.get("content-type")?.includes("application/json");
+ const isImage = res.headers.get("content-type")?.includes("image");
+
+ if (isImage) {
+ return (await res.blob()) as TData;
+ }
+
+ if (!isJson) {
+ return (await res.text()) as TData;
+ }
+
+ try {
+ return await res.json();
+ } catch {
+ return (await res.text()) as TData;
+ }
+}
diff --git a/src/api/types.ts b/src/api/types.ts
new file mode 100644
index 0000000..aed066a
--- /dev/null
+++ b/src/api/types.ts
@@ -0,0 +1,44 @@
+type QueryParamValue = string | number | boolean | null | undefined;
+
+export type QueryParams = Record;
+
+interface RouteBase {
+ path: string;
+ TRes: TData;
+ noAuth?: boolean;
+}
+
+export interface QueryRoute extends RouteBase {
+ method?: "GET";
+}
+
+export interface MutationRoute extends RouteBase {
+ method: "POST" | "PUT" | "PATCH" | "DELETE";
+ TBody?: TBody;
+}
+
+export type Route =
+ | QueryRoute
+ | MutationRoute;
+
+export interface RequestResult {
+ res: Response | undefined;
+ data: TData | undefined;
+ error: undefined | Record;
+}
+
+export interface RequestOptions {
+ query?: QueryParams;
+ body?: TBody;
+ pathParams?: Record;
+ onResponse?: (res: RequestResult) => void;
+ silent?: boolean;
+ reattempts?: number;
+}
+
+export interface PaginatedResponse {
+ count: number;
+ next: string | null;
+ previous: string | null;
+ results: TItem[];
+}
diff --git a/src/api/useMutation.ts b/src/api/useMutation.ts
new file mode 100644
index 0000000..6be494a
--- /dev/null
+++ b/src/api/useMutation.ts
@@ -0,0 +1,38 @@
+import React from "react";
+
+import request from "@/api/request";
+import { MutationRoute, RequestOptions, RequestResult } from "@/api/types";
+import { mergeRequestOptions } from "@/api/utils";
+
+export default function useMutation(
+ route: MutationRoute,
+ options: RequestOptions
+) {
+ const [response, setResponse] = React.useState>();
+ const [isProcessing, setIsProcessing] = React.useState(false);
+
+ const controllerRef = React.useRef();
+
+ const runQuery = React.useCallback(
+ async (overrides?: RequestOptions) => {
+ controllerRef.current?.abort();
+
+ const controller = new AbortController();
+ controllerRef.current = controller;
+
+ const resolvedOptions =
+ options && overrides
+ ? mergeRequestOptions(options, overrides)
+ : overrides ?? options;
+
+ setIsProcessing(true);
+ const response = await request(route, { ...resolvedOptions, controller });
+ setResponse(response);
+ setIsProcessing(false);
+ return response;
+ },
+ [route, JSON.stringify(options)]
+ );
+
+ return { ...response, isProcessing, mutate: runQuery };
+}
diff --git a/src/api/useQuery.ts b/src/api/useQuery.ts
new file mode 100644
index 0000000..c42abe7
--- /dev/null
+++ b/src/api/useQuery.ts
@@ -0,0 +1,60 @@
+import { useCallback, useEffect, useRef, useState } from "react";
+
+import request from "@/api/request";
+import { QueryRoute, RequestOptions, RequestResult } from "@/api/types";
+import { mergeRequestOptions } from "@/api/utils";
+
+export interface QueryOptions extends RequestOptions {
+ prefetch?: boolean;
+ refetchOnWindowFocus?: boolean;
+ key?: string;
+}
+
+export default function useQuery(
+ route: QueryRoute,
+ options?: QueryOptions
+) {
+ const [response, setResponse] = useState>();
+ const [loading, setLoading] = useState(false);
+
+ const controllerRef = useRef();
+
+ const runQuery = useCallback(
+ async (overrides?: QueryOptions) => {
+ controllerRef.current?.abort();
+
+ const controller = new AbortController();
+ controllerRef.current = controller;
+
+ const resolvedOptions =
+ options && overrides
+ ? mergeRequestOptions(options, overrides)
+ : overrides ?? options;
+
+ setLoading(true);
+ const response = await request(route, { ...resolvedOptions, controller });
+ setResponse(response);
+ setLoading(false);
+ return response;
+ },
+ [route, JSON.stringify(options)]
+ );
+
+ useEffect(() => {
+ if (options?.prefetch ?? true) {
+ runQuery();
+ }
+ }, [runQuery, options?.prefetch]);
+
+ useEffect(() => {
+ if (options?.refetchOnWindowFocus) {
+ const onFocus = () => runQuery();
+
+ window.addEventListener("focus", onFocus);
+
+ return () => window.removeEventListener("focus", onFocus);
+ }
+ }, [runQuery, options?.refetchOnWindowFocus]);
+
+ return { ...response, loading, refetch: runQuery };
+}
diff --git a/src/api/utils.ts b/src/api/utils.ts
new file mode 100644
index 0000000..d9cad9f
--- /dev/null
+++ b/src/api/utils.ts
@@ -0,0 +1,110 @@
+import { Dispatch, SetStateAction } from "react";
+
+import { LocalStorageKeys } from "@/common/constants";
+
+import { QueryParams, RequestOptions } from "@/api/types";
+
+export function makeUrl(
+ path: string,
+ query?: QueryParams,
+ pathParams?: Record
+) {
+ if (pathParams) {
+ path = Object.entries(pathParams).reduce(
+ (acc, [key, value]) => acc.replace(`{${key}}`, `${value}`),
+ path
+ );
+ }
+
+ ensurePathNotMissingReplacements(path);
+
+ if (query) {
+ path += `?${makeQueryParams(query)}`;
+ }
+
+ return path;
+}
+
+const makeQueryParams = (query: QueryParams) => {
+ const qParams = new URLSearchParams();
+
+ Object.entries(query).forEach(([key, value]) => {
+ if (value !== undefined) {
+ qParams.set(key, `${value}`);
+ }
+ });
+
+ return qParams.toString();
+};
+
+const ensurePathNotMissingReplacements = (path: string) => {
+ const missingParams = path.match(/\{.*\}/g);
+
+ if (missingParams) {
+ const msg = `Missing path params: ${missingParams.join(
+ ", "
+ )}. Path: ${path}`;
+ Notification.Error({ msg });
+ throw new Error(msg);
+ }
+};
+
+export function makeHeaders(noAuth: boolean) {
+ const headers = new Headers({
+ "Content-Type": "application/json",
+ Accept: "application/json",
+ });
+
+ if (!noAuth) {
+ const token = getAuthorizationHeader();
+
+ if (token) {
+ headers.append("Authorization", token);
+ }
+ }
+
+ return headers;
+}
+
+export function getAuthorizationHeader() {
+ const bearerToken = localStorage.getItem(LocalStorageKeys.accessToken);
+
+ if (bearerToken) {
+ return `Bearer ${bearerToken}`;
+ }
+
+ return null;
+}
+
+export function mergeRequestOptions(
+ options: RequestOptions,
+ overrides: RequestOptions
+): RequestOptions {
+ return {
+ ...options,
+ ...overrides,
+
+ query: { ...options.query, ...overrides.query },
+ body: (options.body || overrides.body) && {
+ ...(options.body ?? {}),
+ ...(overrides.body ?? {}),
+ },
+ pathParams: { ...options.pathParams, ...overrides.pathParams },
+
+ onResponse: (res) => {
+ options.onResponse?.(res);
+ overrides.onResponse?.(res);
+ },
+ silent: overrides.silent ?? options.silent,
+ };
+}
+
+export function handleUploadPercentage(
+ event: ProgressEvent,
+ setUploadPercent: Dispatch>
+) {
+ if (event.lengthComputable) {
+ const percentComplete = Math.round((event.loaded / event.total) * 100);
+ setUploadPercent(percentComplete);
+ }
+}
diff --git a/src/common/constants.ts b/src/common/constants.ts
new file mode 100644
index 0000000..3715f5d
--- /dev/null
+++ b/src/common/constants.ts
@@ -0,0 +1,1719 @@
+import { IconName } from "@/CAREUI/icons/CareIcon";
+
+import { SortOption } from "@/components/Common/SortDropdown";
+import {
+ PatientCategory,
+ SpokeRelationship,
+} from "@/components/Facility/models";
+import { PhoneNumberValidator } from "@/components/Form/FieldValidators";
+
+import { dateQueryString } from "@/Utils/utils";
+
+import { SchemaType } from "./schemaParser";
+
+export const RESULTS_PER_PAGE_LIMIT = 14;
+export const PAGINATION_LIMIT = 36;
+
+/**
+ * Contains local storage keys that are potentially used in multiple places.
+ */
+export const LocalStorageKeys = {
+ accessToken: "care_access_token",
+ refreshToken: "care_refresh_token",
+};
+export interface OptionsType {
+ id: number | string;
+ text: string;
+ label?: string;
+ desc?: string;
+ disabled?: boolean;
+}
+
+export const USER_TYPE_OPTIONS = [
+ { id: "Pharmacist", role: "Pharmacist", readOnly: false },
+ { id: "Volunteer", role: "Volunteer", readOnly: false },
+ { id: "StaffReadOnly", role: "Staff", readOnly: true },
+ { id: "Staff", role: "Staff", readOnly: false },
+ // { id: "NurseReadOnly", role: "Nurse", readOnly: true },
+ { id: "Nurse", role: "Nurse", readOnly: false },
+ { id: "Doctor", role: "Doctor", readOnly: false },
+ { id: "WardAdmin", role: "Ward Admin", readOnly: false },
+ { id: "LocalBodyAdmin", role: "Local Body Admin", readOnly: false },
+ { id: "DistrictLabAdmin", role: "District Lab Admin", readOnly: false },
+ { id: "DistrictReadOnlyAdmin", role: "District Admin", readOnly: true },
+ { id: "DistrictAdmin", role: "District Admin", readOnly: false },
+ { id: "StateLabAdmin", role: "State Lab Admin", readOnly: false },
+ { id: "StateReadOnlyAdmin", role: "State Admin", readOnly: true },
+ { id: "StateAdmin", role: "State Admin", readOnly: false },
+] as const;
+
+export const USER_LAST_ACTIVE_OPTIONS = [
+ { id: 1, text: "24 hours" },
+ { id: 7, text: "7 days" },
+ { id: 30, text: "30 days" },
+ { id: 90, text: "90 days" },
+ { id: 365, text: "1 Year" },
+ { id: "never", text: "Never" },
+];
+
+export type UserRole = (typeof USER_TYPE_OPTIONS)[number]["id"];
+
+export const USER_TYPES = USER_TYPE_OPTIONS.map((o) => o.id);
+
+export const DOWNLOAD_TYPES: Array = [
+ "Facility List",
+ "Facility Capacity List",
+ "Facility Doctors List",
+ "Facility Triage Data",
+];
+
+export const TEST_TYPE_CHOICES: Array = [
+ { id: 10, text: "UNK" },
+ { id: 20, text: "ANTIGEN" },
+ { id: 30, text: "RTPCR" },
+ { id: 40, text: "CBNAAT" },
+ { id: 50, text: "TRUENAT" },
+ { id: 60, text: "RTLAMP" },
+ { id: 70, text: "POCPCR" },
+];
+
+export const DISTRICT_CHOICES: Array = [
+ { id: 1, text: "Thiruvananthapuram" },
+ { id: 2, text: "Kollam" },
+ { id: 3, text: "Pathanamthitta" },
+ { id: 4, text: "Alappuzha" },
+ { id: 5, text: "Kottayam" },
+ { id: 6, text: "Idukki" },
+ { id: 7, text: "Ernakulam" },
+ { id: 8, text: "Thrissur" },
+ { id: 9, text: "Palakkad" },
+ { id: 10, text: "Malappuram" },
+ { id: 11, text: "Kozhikode" },
+ { id: 12, text: "Wayanad" },
+ { id: 13, text: "Kannur" },
+ { id: 14, text: "Kasaragod" },
+];
+
+export const VEHICLE_TYPES: Array = [
+ { id: 1, text: "Basic" },
+ { id: 2, text: "Cardiac" },
+ { id: 3, text: "Hearse" },
+];
+
+export const FACILITY_TYPES: Array = [
+ // { id: 1, text: "Educational Inst" },
+ // { id: 4, text: "Hostel" },
+ // { id: 5, text: "Hotel" },
+ // { id: 6, text: "Lodge" },
+ { id: 800, text: "Primary Health Centres" },
+ { id: 802, text: "Family Health Centres" },
+ { id: 803, text: "Community Health Centres" },
+ { id: 840, text: "Women and Child Health Centres" },
+ { id: 830, text: "Taluk Hospitals" },
+ { id: 860, text: "District Hospitals" },
+ { id: 870, text: "Govt Medical College Hospitals" },
+ { id: 9, text: "Govt Labs" },
+ { id: 10, text: "Private Labs" },
+ { id: 7, text: "TeleMedicine" },
+ { id: 2, text: "Private Hospital" },
+ { id: 910, text: "Autonomous healthcare facility" },
+ { id: 1300, text: "Shifting Centre" },
+ { id: 1500, text: "Request Approving Center" },
+ { id: 1510, text: "Request Fulfilment Center" },
+ { id: 3, text: "Other" },
+
+ // { id: 8, text: "Govt Hospital" },
+ // { id: 801, text: "24x7 Public Health Centres" },
+ // { id: 820, text: "Urban Primary Health Center" },
+ // { id: 831, text: "Taluk Headquarters Hospitals" },
+ // { id: 850, text: "General hospitals" },
+
+ // { id: 900, text: "Co-operative hospitals" },
+
+ // { id: 950, text: "Corona Testing Labs" },
+ // { id: 1000, text: "Corona Care Centre" },
+
+ // { id: 1010, text: "COVID-19 Domiciliary Care Center" },
+ // { id: 1100, text: "First Line Treatment Centre" },
+ // { id: 1200, text: "Second Line Treatment Center" },
+ // { id: 1400, text: "Covid Management Center" },
+ // { id: 1600, text: "District War Room" },
+];
+
+export const SHIFTING_CHOICES_WARTIME: Array = [
+ { id: 10, text: "PENDING", label: "SHIFTING APPROVAL PENDING" },
+ { id: 15, text: "ON HOLD" },
+ { id: 20, text: "APPROVED" },
+ { id: 30, text: "REJECTED" },
+ { id: 40, text: "DESTINATION APPROVED" },
+ { id: 50, text: "DESTINATION REJECTED" },
+ { id: 55, text: "TRANSPORTATION TO BE ARRANGED" },
+ { id: 60, text: "PATIENT TO BE PICKED UP" },
+ { id: 70, text: "TRANSFER IN PROGRESS" },
+ { id: 80, text: "COMPLETED" },
+ { id: 90, text: "PATIENT EXPIRED" },
+ { id: 100, text: "CANCELLED" },
+];
+
+export const SHIFTING_CHOICES_PEACETIME: Array = [
+ { id: 20, text: "APPROVED", label: "PATIENTS TO BE SHIFTED" },
+ { id: 40, text: "DESTINATION APPROVED" },
+ // { id: 50, text: "DESTINATION REJECTED" },
+ { id: 60, text: "PATIENT TO BE PICKED UP", label: "TRANSPORTATION ARRANGED" },
+ { id: 70, text: "TRANSFER IN PROGRESS" },
+ { id: 80, text: "COMPLETED" },
+ { id: 90, text: "PATIENT EXPIRED" },
+ { id: 100, text: "CANCELLED" },
+];
+
+export const SHIFTING_VEHICLE_CHOICES: Array = [
+ { id: 10, text: "D Level Ambulance" },
+ { id: 20, text: "All double chambered Ambulance with EMT" },
+ { id: 30, text: "Ambulance without EMT" },
+ { id: 50, text: "Car" },
+ { id: 50, text: "Auto-rickshaw" },
+];
+
+export const SHIFTING_FILTER_ORDER: Array = [
+ { id: 1, text: "created_date", desc: "ASC Created Date" },
+ { id: 2, text: "-created_date", desc: "DESC Created Date" },
+ { id: 3, text: "modified_date", desc: "ASC Modified Date" },
+ { id: 4, text: "-modified_date", desc: "DESC Modified Date" },
+];
+
+export const PATIENT_SORT_OPTIONS: SortOption[] = [
+ { isAscending: false, value: "-created_date" },
+ { isAscending: true, value: "created_date" },
+ { isAscending: false, value: "-category_severity" },
+ { isAscending: true, value: "category_severity" },
+ { isAscending: false, value: "-modified_date" },
+ { isAscending: true, value: "modified_date" },
+ {
+ isAscending: true,
+ value: "facility__name,last_consultation__current_bed__bed__name",
+ },
+ {
+ isAscending: false,
+ value: "facility__name,-last_consultation__current_bed__bed__name",
+ },
+ { isAscending: false, value: "-review_time" },
+ { isAscending: true, value: "review_time" },
+ { isAscending: true, value: "name" },
+ { isAscending: false, value: "-name" },
+];
+
+export const EVENTS_SORT_OPTIONS: SortOption[] = [
+ { isAscending: false, value: "-created_date" },
+ { isAscending: true, value: "created_date" },
+ { isAscending: false, value: "-taken_at" },
+ { isAscending: true, value: "taken_at" },
+];
+
+export const DISCHARGED_PATIENT_SORT_OPTIONS: SortOption[] = [
+ { isAscending: false, value: "-created_date" },
+ { isAscending: true, value: "created_date" },
+ { isAscending: false, value: "-modified_date" },
+ { isAscending: true, value: "modified_date" },
+ { isAscending: true, value: "name" },
+ { isAscending: false, value: "-name" },
+];
+
+export const BED_TYPES = [100, 200, 300, 400, 500];
+
+export const DOCTOR_SPECIALIZATION: Array = [
+ { id: 1, text: "General Medicine" },
+ { id: 2, text: "Pulmonology" },
+ { id: 3, text: "Intensivist" },
+ { id: 4, text: "Pediatrician" },
+ { id: 6, text: "Anesthesiologist" },
+ { id: 7, text: "Cardiac Surgeon" },
+ { id: 8, text: "Cardiologist" },
+ { id: 9, text: "Dentist" },
+ { id: 10, text: "Dermatologist" },
+ { id: 11, text: "Diabetologist" },
+ { id: 12, text: "Emergency Medicine Physician" },
+ { id: 13, text: "Endocrinologist" },
+ { id: 14, text: "Family Physician" },
+ { id: 15, text: "Gastroenterologist" },
+ { id: 16, text: "General Surgeon" },
+ { id: 17, text: "Geriatrician" },
+ { id: 18, text: "Hematologist" },
+ { id: 19, text: "Immunologist" },
+ { id: 20, text: "Infectious Disease Specialist" },
+ { id: 21, text: "MBBS doctor" },
+ { id: 22, text: "Medical Officer" },
+ { id: 23, text: "Nephrologist" },
+ { id: 24, text: "Neuro Surgeon" },
+ { id: 25, text: "Neurologist" },
+ { id: 26, text: "Obstetrician and Gynecologist" },
+ { id: 27, text: "Oncologist" },
+ { id: 28, text: "Oncology Surgeon" },
+ { id: 29, text: "Ophthalmologist" },
+ {
+ id: 30,
+ text: "Oral and Maxillofacial Surgeon",
+ },
+ { id: 31, text: "Orthopedic" },
+ { id: 32, text: "Orthopedic Surgeon" },
+ { id: 33, text: "Otolaryngologist (ENT)" },
+ { id: 34, text: "Palliative care Physician" },
+ { id: 35, text: "Pathologist" },
+ { id: 36, text: "Pediatric Surgeon" },
+ { id: 37, text: "Physician" },
+ { id: 38, text: "Plastic Surgeon" },
+ { id: 39, text: "Psychiatrist" },
+ { id: 40, text: "Pulmonologist" },
+ { id: 41, text: "Radio technician" },
+ { id: 42, text: "Radiologist" },
+ { id: 43, text: "Rheumatologist" },
+ { id: 44, text: "Sports Medicine Specialist" },
+ { id: 45, text: "Thoraco-Vascular Surgeon" },
+ {
+ id: 46,
+ text: "Transfusion Medicine Specialist",
+ },
+ { id: 47, text: "Urologist" },
+ { id: 48, text: "Nurse" },
+ { id: 5, text: "Others" },
+];
+
+export const MEDICAL_HISTORY_CHOICES: Array = [
+ { id: 1, text: "NO" },
+ { id: 2, text: "Diabetes" },
+ { id: 3, text: "Heart Disease" },
+ { id: 4, text: "HyperTension" },
+ { id: 5, text: "Kidney Diseases" },
+ { id: 6, text: "Lung Diseases/Asthma" },
+ { id: 7, text: "Cancer" },
+ { id: 8, text: "OTHER" },
+];
+
+export const REVIEW_AT_CHOICES: Array = [
+ { id: -1, text: "No Review" },
+ { id: 10, text: "10 mins" },
+ { id: 15, text: "15 mins" },
+ { id: 30, text: "30 mins" },
+ { id: 60, text: "1 hr" },
+ { id: 2 * 60, text: "2 hr" },
+ { id: 3 * 60, text: "3 hr" },
+ { id: 4 * 60, text: "4 hr" },
+ { id: 6 * 60, text: "6 hr" },
+ { id: 8 * 60, text: "8 hr" },
+ { id: 12 * 60, text: "12 hr" },
+ { id: 24 * 60, text: "24 hr" },
+ { id: 36 * 60, text: "36 hr" },
+ { id: 2 * 24 * 60, text: "2 days" },
+ { id: 3 * 24 * 60, text: "3 days" },
+ { id: 5 * 24 * 60, text: "5 days" },
+ { id: 7 * 24 * 60, text: "7 days" },
+ { id: 10 * 24 * 60, text: "10 days" },
+ { id: 14 * 24 * 60, text: "2 weeks" },
+ { id: 21 * 24 * 60, text: "3 weeks" },
+ { id: 25 * 24 * 60, text: "25 days" },
+ { id: 30 * 24 * 60, text: "1 month" },
+];
+
+export const DISCHARGE_REASONS = [
+ { id: 1, text: "Recovered" },
+ { id: 2, text: "Referred" },
+ { id: 3, text: "Expired" },
+ { id: 4, text: "LAMA" },
+] as const;
+
+export const CONSCIOUSNESS_LEVEL = [
+ { id: 20, value: "UNRESPONSIVE" },
+ { id: 15, value: "RESPONDS_TO_PAIN" },
+ { id: 10, value: "RESPONDS_TO_VOICE" },
+ { id: 5, value: "ALERT" },
+ { id: 25, value: "AGITATED_OR_CONFUSED" },
+ {
+ id: 30,
+ value: "ONSET_OF_AGITATION_AND_CONFUSION",
+ },
+] as const;
+
+export const PUPIL_REACTION_OPTIONS = [
+ { id: 0, value: "UNKNOWN" },
+ { id: 5, value: "BRISK" },
+ { id: 10, value: "SLUGGISH" },
+ { id: 15, value: "FIXED" },
+ { id: 20, value: "CANNOT_BE_ASSESSED" },
+] as const;
+
+export const LIMB_RESPONSE_OPTIONS = [
+ { id: 0, value: "UNKNOWN" },
+ { id: 5, value: "STRONG" },
+ { id: 10, value: "MODERATE" },
+ { id: 15, value: "WEAK" },
+ { id: 20, value: "FLEXION" },
+ { id: 25, value: "EXTENSION" },
+ { id: 30, value: "NONE" },
+] as const;
+
+export const OXYGEN_MODALITY_OPTIONS = [
+ { value: "NASAL_PRONGS" },
+ { value: "SIMPLE_FACE_MASK" },
+ { value: "NON_REBREATHING_MASK" },
+ { value: "HIGH_FLOW_NASAL_CANNULA" },
+] as const;
+
+export const GENDER_TYPES = [
+ { id: 1, text: "Male", icon: "M" },
+ { id: 2, text: "Female", icon: "F" },
+ { id: 3, text: "Transgender", icon: "TRANS" },
+] as const;
+
+export const SAMPLE_TEST_RESULT = [
+ { id: 1, text: "POSITIVE" },
+ { id: 2, text: "NEGATIVE" },
+ { id: 3, text: "AWAITING" },
+ { id: 4, text: "INVALID" },
+];
+
+export const CONSULTATION_SUGGESTION = [
+ { id: "HI", text: "Home Isolation", deprecated: true }, // # Deprecated. Preserving option for backward compatibility (use only for readonly operations)
+ { id: "A", text: "Admission" },
+ { id: "R", text: "Refer to another Hospital", editDisabled: true },
+ { id: "OP", text: "OP Consultation" },
+ { id: "DC", text: "Domiciliary Care" },
+ { id: "DD", text: "Declare Death", editDisabled: true },
+] as const;
+
+export type ConsultationSuggestionValue =
+ (typeof CONSULTATION_SUGGESTION)[number]["id"];
+
+export const ADMITTED_TO = [
+ { id: "1", text: "Isolation" },
+ { id: "2", text: "ICU" },
+ { id: "6", text: "Bed with oxygen support" },
+ { id: "7", text: "Regular" },
+ { id: "None", text: "No bed assigned" },
+];
+
+export const RESPIRATORY_SUPPORT = [
+ { id: "NIV", value: "NON_INVASIVE" },
+ { id: "IV", value: "INVASIVE" },
+ { id: "O2", value: "OXYGEN_SUPPORT" },
+ { id: "NONE", value: "UNKNOWN" },
+] as const;
+
+export const VENTILATOR_MODE_OPTIONS = [
+ "VCV",
+ "PCV",
+ "PRVC",
+ "APRV",
+ "VC_SIMV",
+ "PC_SIMV",
+ "PRVC_SIMV",
+ "ASV",
+ "PSV",
+] as const;
+
+export const INSULIN_INTAKE_FREQUENCY_OPTIONS = [
+ "UNKNOWN",
+ "OD",
+ "BD",
+ "TD",
+] as const;
+
+export type PatientCategoryID =
+ | "Comfort"
+ | "Stable"
+ | "Moderate"
+ | "Critical"
+ | "ActivelyDying";
+
+export const PATIENT_CATEGORIES: {
+ id: PatientCategoryID;
+ text: PatientCategory;
+ description: string;
+ twClass: string;
+}[] = [
+ {
+ id: "Comfort", // Comfort Care is discontinued
+ text: "Comfort Care",
+ twClass: "patient-comfort",
+ description: "End of life care",
+ },
+ {
+ id: "Stable",
+ text: "Mild",
+ twClass: "patient-stable",
+ description: "Urgent: not life-threatening",
+ },
+ {
+ id: "Moderate",
+ text: "Moderate",
+ twClass: "patient-abnormal",
+ description: "Emergency: could be life-threatening",
+ },
+ {
+ id: "Critical",
+ text: "Critical",
+ twClass: "patient-critical",
+ description: "Immediate: life-threatening",
+ },
+ {
+ id: "ActivelyDying",
+ text: "Actively Dying",
+ twClass: "patient-activelydying",
+ description: "",
+ },
+];
+
+export const PATIENT_FILTER_CATEGORIES = PATIENT_CATEGORIES;
+
+export const SAMPLE_TEST_STATUS = [
+ { id: 1, text: "REQUEST_SUBMITTED", desc: "Request Submitted" },
+ { id: 2, text: "APPROVED", desc: "Approved for Sample Collection" },
+ { id: 3, text: "DENIED", desc: "Request Denied" },
+ {
+ id: 4,
+ text: "SENT_TO_COLLECTON_CENTRE",
+ desc: "Sample taken and sent to collection centre",
+ },
+ { id: 5, text: "RECEIVED_AND_FORWARED", desc: "Received And Forwarded" },
+ { id: 6, text: "RECEIVED_AT_LAB", desc: "Received At Lab" },
+ { id: 7, text: "COMPLETED", desc: "Test Completed" },
+];
+
+export const SAMPLE_FLOW_RULES = {
+ REQUEST_SUBMITTED: ["APPROVED", "DENIED"],
+ APPROVED: [
+ "SENT_TO_COLLECTON_CENTRE",
+ "RECEIVED_AND_FORWARED",
+ "RECEIVED_AT_LAB",
+ "COMPLETED",
+ ],
+ DENIED: ["REQUEST_SUBMITTED"],
+ SENT_TO_COLLECTON_CENTRE: [
+ "RECEIVED_AND_FORWARED",
+ "RECEIVED_AT_LAB",
+ "COMPLETED",
+ ],
+ RECEIVED_AND_FORWARED: ["RECEIVED_AT_LAB", "COMPLETED"],
+ RECEIVED_AT_LAB: ["COMPLETED"],
+};
+
+export const TEST_TYPE = [
+ "UNK",
+ "ANTIGEN",
+ "RTPCR",
+ "CBNAAT",
+ "TRUENAT",
+ "RTLAMP",
+ "POCPCR",
+];
+
+export const VACCINES = [
+ "CoviShield",
+ "Covaxin",
+ "Sputnik",
+ "Moderna",
+ "Pfizer",
+ "Janssen",
+ "Sinovac",
+];
+
+export const BLOOD_GROUPS = [
+ "UNK",
+ "A+",
+ "A-",
+ "B+",
+ "B-",
+ "AB+",
+ "AB-",
+ "O+",
+ "O-",
+];
+
+export const SAMPLE_TYPE_CHOICES = [
+ { id: "0", text: "UNKNOWN" },
+ { id: "1", text: "BA/ETA" },
+ { id: "2", text: "TS/NPS/NS" },
+ { id: "3", text: "Blood in EDTA" },
+ { id: "4", text: "Acute Sera" },
+ { id: "5", text: "Covalescent sera" },
+ { id: "6", text: "Biopsy" },
+ { id: "7", text: "AMR" },
+ { id: "8", text: "Communicable Diseases" },
+ { id: "9", text: "OTHER TYPE" },
+];
+
+export const ICMR_CATEGORY = [
+ "Cat 0",
+ "Cat 1",
+ "Cat 2",
+ "Cat 3",
+ "Cat 4",
+ "Cat 5a",
+ "Cat 5b",
+];
+
+export const TELEMEDICINE_ACTIONS = [
+ { id: 10, text: "NO_ACTION", desc: "No Action" },
+ { id: 20, text: "PENDING", desc: "Pending" },
+ { id: 30, text: "SPECIALIST_REQUIRED", desc: "Specialist Required" },
+ { id: 40, text: "PLAN_FOR_HOME_CARE", desc: "Plan for Home Care" },
+ { id: 50, text: "FOLLOW_UP_NOT_REQUIRED", desc: "Follow Up Not Required" },
+ { id: 60, text: "COMPLETE", desc: "Complete" },
+ { id: 70, text: "REVIEW", desc: "Review" },
+ { id: 80, text: "NOT_REACHABLE", desc: "Not Reachable" },
+ { id: 90, text: "DISCHARGE_RECOMMENDED", desc: "Discharge Recommended" },
+];
+
+export const FRONTLINE_WORKER = [
+ "NOT APPLICABLE",
+ "HEALTHCARE WORKER",
+ "ELECTED REPRESENTATIVE",
+ "POLICE OFFICER",
+ "REVENUE OFFICIAL",
+ "TEACHER",
+ "FIRE FORCE",
+ "ANGNAWADI WORKER",
+ "KUDUMBASREE",
+ "VOLUNTEER",
+ "SUPERVISOR",
+];
+
+export const DESIGNATION_HEALTH_CARE_WORKER = [
+ "AMBULANCE DRIVER",
+ "ASHA",
+ "ATTENDER",
+ "CLEANING STAFF",
+ "CSSD STAFF",
+ "ANEASTHESIA TECHNICHIAN",
+ "DIALYSIS TECHNICIAN",
+ "DIETICIAN",
+ "DOCTOR",
+ "FIELD STAFF",
+ "LAB ASSISTANT",
+ "LAB TECHNICIAN",
+ "NURSING ASSISTANT",
+ "OFFICE STAFF",
+ "PALLIATIVE NURSE",
+ "PHARMACIST",
+ "PHYSICIAN ASSISTANT",
+ "PHYSIOTHERAPIST",
+ "PSYCHOLOGIST",
+ "RADIOLOGY TECHNICIAN",
+ "SECURITY STAFF",
+ "SONOLOGIST",
+ "STAFF NURSE",
+ "OTHERS",
+];
+
+type NotificationEvent = {
+ id: string;
+ text: string;
+ icon: IconName;
+};
+
+export const NOTIFICATION_EVENTS: NotificationEvent[] = [
+ { id: "MESSAGE", text: "Notice", icon: "l-comment-alt-message" },
+ {
+ id: "PATIENT_CREATED",
+ text: "Patient Created",
+ icon: "l-user-plus",
+ },
+ {
+ id: "PATIENT_UPDATED",
+ text: "Patient Updated",
+ icon: "l-edit",
+ },
+ {
+ id: "PATIENT_CONSULTATION_CREATED",
+ text: "Patient Consultation Created",
+ icon: "l-heart",
+ },
+ {
+ id: "PATIENT_CONSULTATION_UPDATED",
+ text: "Patient Consultation Updated",
+ icon: "l-heart-medical",
+ },
+ {
+ id: "INVESTIGATION_SESSION_CREATED",
+ text: "Investigation Session Created",
+ icon: "l-search",
+ },
+ {
+ id: "INVESTIGATION_UPDATED",
+ text: "Investigation Updated",
+ icon: "l-search-plus",
+ },
+ {
+ id: "PATIENT_FILE_UPLOAD_CREATED",
+ text: "Patient File Upload Created",
+ icon: "l-file-medical",
+ },
+ {
+ id: "CONSULTATION_FILE_UPLOAD_CREATED",
+ text: "Consultation File Upload Created",
+ icon: "l-file-upload",
+ },
+ {
+ id: "PATIENT_CONSULTATION_UPDATE_CREATED",
+ text: "Patient Log Update Created",
+ icon: "l-heart",
+ },
+ {
+ id: "PATIENT_CONSULTATION_UPDATE_UPDATED",
+ text: "Patient Log Update Updated",
+ icon: "l-heart-medical",
+ },
+ {
+ id: "SHIFTING_UPDATED",
+ text: "Shifting Updated",
+ icon: "l-ambulance",
+ },
+ {
+ id: "PATIENT_NOTE_ADDED",
+ text: "Patient Note Added",
+ icon: "l-notes",
+ },
+];
+
+export const BREATHLESSNESS_LEVEL = [
+ "NOT BREATHLESS",
+ "MILD",
+ "MODERATE",
+ "SEVERE",
+];
+
+export const RESOURCE_CATEGORY_CHOICES = ["OXYGEN"];
+
+export const RESOURCE_CHOICES: Array = [
+ { id: 10, text: "PENDING" },
+ { id: 15, text: "ON HOLD" },
+ { id: 20, text: "APPROVED" },
+ { id: 30, text: "REJECTED" },
+ { id: 55, text: "TRANSPORTATION TO BE ARRANGED" },
+ { id: 70, text: "TRANSFER IN PROGRESS" },
+ { id: 80, text: "COMPLETED" },
+];
+export const RESOURCE_SUBCATEGORIES: Array = [
+ { id: 110, text: "LMO in KL" },
+ { id: 120, text: "B TYPE OXYGEN CYLINDER" },
+ { id: 130, text: "C TYPE OXYGEN CYLINDER" },
+ { id: 140, text: "JUMBO D TYPE OXYGEN CYLINDER" },
+ { id: 1000, text: "UNSPECIFIED" },
+];
+
+export const RESOURCE_FILTER_ORDER: Array = [
+ { id: 1, text: "created_date", desc: "ASC Created Date" },
+ { id: 2, text: "-created_date", desc: "DESC Created Date" },
+ { id: 3, text: "modified_date", desc: "ASC Modified Date" },
+ { id: 4, text: "-modified_date", desc: "DESC Modified Date" },
+];
+
+export const HEARTBEAT_RHYTHM_CHOICES = [
+ "REGULAR",
+ "IRREGULAR",
+ "UNKNOWN",
+] as const;
+
+export const NURSING_CARE_PROCEDURES = [
+ "oral_care",
+ "hair_care",
+ "bed_bath",
+ "eye_care",
+ "perineal_care",
+ "skin_care",
+ "pre_enema",
+ "wound_dressing",
+ "lymphedema_care",
+ "ascitic_tapping",
+ "colostomy_care",
+ "colostomy_change",
+ "personal_hygiene",
+ "positioning",
+ "suctioning",
+ "ryles_tube_care",
+ "ryles_tube_change",
+ "iv_sitecare",
+ "nubulisation",
+ "dressing",
+ "dvt_pump_stocking",
+ "restrain",
+ "chest_tube_care",
+ "tracheostomy_care",
+ "tracheostomy_tube_change",
+ "stoma_care",
+ "catheter_care",
+ "catheter_change",
+] as const;
+
+export const EYE_OPEN_SCALE = [
+ { value: 1, text: "No Response" },
+ { value: 2, text: "To Pain" },
+ { value: 3, text: "To Speech" },
+ { value: 4, text: "Spontaneous" },
+];
+
+export const VERBAL_RESPONSE_SCALE = [
+ { value: 1, text: "No Response" },
+ { value: 2, text: "Incomprehensible words/Moans to pain" },
+ { value: 3, text: "Inappropriate words/Cry to Pain" },
+ { value: 4, text: "Confused/Irritable" },
+ { value: 5, text: "Oriented to Time, Place and Person" },
+];
+
+export const MOTOR_RESPONSE_SCALE = [
+ { value: 1, text: "No Response" },
+ { value: 2, text: "Abnormal Extension(decerebrate)" },
+ { value: 3, text: "Abnormal Flexion(decorticate)" },
+ { value: 4, text: "Flexion/Withdrawal from pain" },
+ { value: 5, text: "Moves to localized pain" },
+ { value: 6, text: "Obeying commands/Normal acrivity" },
+];
+
+export const RHYTHM_CHOICES = [
+ { id: 5, text: "REGULAR", desc: "Regular" },
+ { id: 10, text: "IRREGULAR", desc: "Irregular" },
+] as const;
+
+export const BOWEL_ISSUE_CHOICES = [
+ "NO_DIFFICULTY",
+ "CONSTIPATION",
+ "DIARRHOEA",
+] as const;
+
+export const BLADDER_DRAINAGE_CHOICES = [
+ "NORMAL",
+ "CONDOM_CATHETER",
+ "DIAPER",
+ "INTERMITTENT_CATHETER",
+ "CONTINUOUS_INDWELLING_CATHETER",
+ "CONTINUOUS_SUPRAPUBIC_CATHETER",
+ "UROSTOMY",
+] as const;
+
+export const BLADDER_ISSUE_CHOICES = [
+ "NO_ISSUES",
+ "INCONTINENCE",
+ "RETENTION",
+ "HESITANCY",
+] as const;
+
+export const URINATION_FREQUENCY_CHOICES = [
+ "NORMAL",
+ "DECREASED",
+ "INCREASED",
+] as const;
+
+export const SLEEP_CHOICES = [
+ "EXCESSIVE",
+ "SATISFACTORY",
+ "UNSATISFACTORY",
+ "NO_SLEEP",
+] as const;
+
+export const NUTRITION_ROUTE_CHOICES = [
+ "ORAL",
+ "RYLES_TUBE",
+ "GASTROSTOMY_OR_JEJUNOSTOMY",
+ "PEG",
+ "PARENTERAL_TUBING_FLUID",
+ "PARENTERAL_TUBING_TPN",
+] as const;
+
+export const ORAL_ISSUE_CHOICES = [
+ "NO_ISSUE",
+ "DYSPHAGIA",
+ "ODYNOPHAGIA",
+] as const;
+
+export const APPETITE_CHOICES = [
+ "INCREASED",
+ "SATISFACTORY",
+ "REDUCED",
+ "NO_TASTE_FOR_FOOD",
+ "CANNOT_BE_ASSESSED",
+] as const;
+
+export const LOCATION_BED_TYPES = [
+ { id: "ISOLATION", name: "Isolation" },
+ { id: "ICU", name: "ICU" },
+ { id: "BED_WITH_OXYGEN_SUPPORT", name: "Bed with oxygen support" },
+ { id: "REGULAR", name: "Regular" },
+] as const;
+
+export type CameraPTZ = {
+ icon?: IconName;
+ label: string;
+ action: string;
+ loadingLabel?: string;
+ shortcutKey: string[];
+ value?: number;
+};
+
+export const CAMERA_STATES = {
+ IDLE: "idle",
+ MOVING: {
+ GENERIC: "Moving",
+ UP: "Moving Up",
+ DOWN: "Moving Down",
+ LEFT: "Moving Left",
+ RIGHT: "Moving Right",
+ },
+ ZOOMING: {
+ IN: "Zooming In",
+ OUT: "Zooming Out",
+ },
+ PRECISION: "Setting Precision",
+ UPDATING_PRESET: "Updating Preset",
+};
+
+export const getCameraPTZ: (precision: number) => CameraPTZ[] = (precision) => [
+ {
+ icon: "l-angle-up",
+ label: "Move Up",
+ action: "up",
+ loadingLabel: CAMERA_STATES.MOVING.UP,
+ shortcutKey: ["Control", "Shift", "ArrowUp"],
+ },
+ {
+ icon: "l-angle-down",
+ label: "Move Down",
+ action: "down",
+ loadingLabel: CAMERA_STATES.MOVING.DOWN,
+ shortcutKey: ["Control", "Shift", "ArrowDown"],
+ },
+ {
+ icon: "l-angle-left",
+ label: "Move Left",
+ action: "left",
+ loadingLabel: CAMERA_STATES.MOVING.LEFT,
+ shortcutKey: ["Control", "Shift", "ArrowLeft"],
+ },
+ {
+ icon: "l-angle-right",
+ label: "Move Right",
+ action: "right",
+ loadingLabel: CAMERA_STATES.MOVING.RIGHT,
+ shortcutKey: ["Control", "Shift", "ArrowRight"],
+ },
+ {
+ value: precision,
+ label: "Precision",
+ action: "precision",
+ loadingLabel: CAMERA_STATES.PRECISION,
+ shortcutKey: ["Shift", "P"],
+ },
+ {
+ icon: "l-search-plus",
+ label: "Zoom In",
+ action: "zoomIn",
+ loadingLabel: CAMERA_STATES.ZOOMING.IN,
+ shortcutKey: ["Shift", "I"],
+ },
+ {
+ icon: "l-search-minus",
+ label: "Zoom Out",
+ action: "zoomOut",
+ loadingLabel: CAMERA_STATES.ZOOMING.OUT,
+ shortcutKey: ["Shift", "O"],
+ },
+ {
+ icon: "l-save",
+ label: "Update Preset",
+ action: "updatePreset",
+ loadingLabel: CAMERA_STATES.UPDATING_PRESET,
+ shortcutKey: ["Shift", "S"],
+ },
+ {
+ icon: "l-redo",
+ label: "Reset",
+ action: "reset",
+ shortcutKey: ["Shift", "R"],
+ },
+ {
+ icon: "l-expand-arrows-alt",
+ label: "Full Screen",
+ action: "fullScreen",
+ shortcutKey: ["F"],
+ },
+];
+
+// in future, if you find Unicon equivalents of all these icons, please replace them. Only use the same iconset throughout.
+export const FACILITY_FEATURE_TYPES: {
+ id: number;
+ name: string;
+ icon: IconName;
+}[] = [
+ {
+ id: 1,
+ name: "CT Scan",
+ icon: "l-compact-disc",
+ },
+ {
+ id: 2,
+ name: "Maternity Care",
+ icon: "l-baby-carriage",
+ },
+ {
+ id: 3,
+ name: "X-Ray",
+ icon: "l-clipboard-alt",
+ },
+ {
+ id: 4,
+ name: "Neonatal Care",
+ icon: "l-baby-carriage",
+ },
+ {
+ id: 5,
+ name: "Operation Theater",
+ icon: "l-syringe",
+ },
+ {
+ id: 6,
+ name: "Blood Bank",
+ icon: "l-medical-drip",
+ },
+];
+
+export const WAVEFORM_VIEWABLE_LENGTH = 400;
+
+//blacklisted paths will not scroll to top
+export const BLACKLISTED_PATHS: RegExp[] = [
+ /\/facility\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/patient\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/consultation\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/feed+/i,
+ /\/facility\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/patient\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/consultation\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/summary+/i,
+ /\/facility\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/patient\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/consultation\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/medicines+/i,
+ /\/facility\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/patient\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/consultation\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/files+/i,
+ /\/facility\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/patient\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/consultation\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/investigations+/i,
+ /\/facility\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/patient\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/consultation\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/abg+/i,
+ /\/facility\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/patient\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/consultation\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/nursing+/i,
+ /\/facility\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/patient\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/consultation\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/neurological_monitoring+/i,
+ /\/facility\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/patient\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/consultation\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/ventilator+/i,
+ /\/facility\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/patient\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/consultation\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/nutrition+/i,
+ /\/facility\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/patient\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/consultation\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/pressure_sore+/i,
+ /\/facility\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/patient\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/consultation\/([A-Za-z0-9]+(-[A-Za-z0-9]+)+)\/dialysis+/i,
+];
+
+export const AssetImportSchema: SchemaType = {
+ Name: { prop: "name", type: "string" },
+ Type: {
+ prop: "asset_type",
+ type: "string",
+ oneOf: ["INTERNAL", "EXTERNAL"],
+ required: true,
+ },
+ Class: {
+ prop: "asset_class",
+ type: "string",
+ oneOf: ["HL7MONITOR", "ONVIF", "VENTILATOR", ""],
+ },
+ Description: { prop: "description", type: "string" },
+ "Working Status": {
+ prop: "is_working",
+ type: "boolean",
+ parse: (status: string) => {
+ if (status === "WORKING") {
+ return true;
+ } else if (status === "NOT WORKING") {
+ return false;
+ } else {
+ throw new Error("Invalid Working Status: " + status);
+ }
+ },
+ required: true,
+ },
+ "Not Working Reason": { prop: "not_working_reason", type: "string" },
+ "Serial Number": { prop: "serial_number", type: "string" },
+ "QR Code ID": { prop: "qr_code_id", type: "string" },
+ Manufacturer: { prop: "manufacturer", type: "string" },
+ "Vendor Name": { prop: "vendor_name", type: "string" },
+ "Support Name": { prop: "support_name", type: "string" },
+ "Support Email": {
+ prop: "support_email",
+ type: "string",
+ parse: (email: string) => {
+ if (!email) return null;
+ const isValid = /^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/.test(email);
+
+ if (!isValid) {
+ throw new Error("Invalid Support Email: " + email);
+ }
+
+ return email;
+ },
+ },
+ "Support Phone Number": {
+ prop: "support_phone",
+ type: "string",
+ parse: (phone: number | string) => {
+ phone = String(phone);
+ if (phone.length === 10 && !phone.startsWith("1800")) {
+ phone = "+91" + phone;
+ }
+ if (phone.startsWith("91") && phone.length === 12) {
+ phone = "+" + phone;
+ }
+ if (phone.startsWith("+911800")) {
+ phone = "1800" + phone.slice(6);
+ }
+ if (
+ PhoneNumberValidator(["mobile", "landline", "support"])(phone) !==
+ undefined
+ ) {
+ throw new Error("Invalid Support Phone Number: " + phone);
+ }
+
+ return phone ? phone : undefined;
+ },
+ required: true,
+ },
+ "Warranty End Date": {
+ prop: "warranty_amc_end_of_validity",
+ type: "string",
+ parse: (date: string) => {
+ if (!date) return null;
+ //handles both "YYYY-MM-DD" and long date format eg : Wed Oct 14 2020 05:30:00 GMT+0530 (India Standard Time)
+ if (isNaN(Date.parse(date))) {
+ const parts = date.split("-");
+ if (parts.length !== 3) {
+ throw new Error("Invalid Date Format: " + date);
+ }
+ const reformattedDateStr = `${parts[2]}-${parts[1]}-${parts[0]}`;
+ const parsed = new Date(reformattedDateStr);
+ if (String(parsed) === "Invalid Date") {
+ throw new Error("Invalid Date: " + date);
+ }
+ return dateQueryString(parsed);
+ } else {
+ const parsed = new Date(date);
+ if (String(parsed) === "Invalid Date") {
+ throw new Error("Invalid Date: " + date);
+ }
+ return dateQueryString(parsed);
+ }
+ },
+ },
+ "Last Service Date": {
+ prop: "last_serviced_on",
+ type: "string",
+ parse: (date: string) => {
+ if (!date) return null;
+ if (isNaN(Date.parse(date))) {
+ const parts = date.split("-");
+ if (parts.length !== 3) {
+ throw new Error("Invalid Date Format: " + date);
+ }
+ const reformattedDateStr = `${parts[2]}-${parts[1]}-${parts[0]}`;
+ const parsed = new Date(reformattedDateStr);
+ if (String(parsed) === "Invalid Date") {
+ throw new Error("Invalid Date: " + date);
+ }
+ return dateQueryString(parsed);
+ } else {
+ const parsed = new Date(date);
+ if (String(parsed) === "Invalid Date") {
+ throw new Error("Invalid Date: " + date);
+ }
+ return dateQueryString(parsed);
+ }
+ },
+ },
+ Notes: { prop: "note", type: "string" },
+ "Config - IP Address": {
+ parent: "meta",
+ prop: "local_ip_address",
+ type: "string",
+ parse: (ip: string) => {
+ if (!ip) return null;
+ const isValid =
+ /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(
+ ip
+ );
+
+ if (!isValid) {
+ throw new Error("Invalid Config IP Address: " + ip);
+ }
+
+ return ip;
+ },
+ },
+ "Config: Camera Access Key": {
+ parent: "meta",
+ prop: "camera_access_key",
+ type: "string",
+ },
+};
+
+export const USER_TYPES_MAP = {
+ Pharmacist: "Pharmacist",
+ Volunteer: "Volunteer",
+ StaffReadOnly: "Staff",
+ Staff: "Staff",
+ Doctor: "Doctor",
+ Nurse: "Nurse",
+ NurseReadOnly: "Nurse",
+ WardAdmin: "Ward Admin",
+ LocalBodyAdmin: "Local Body Admin",
+ DistrictLabAdmin: "District Lab Admin",
+ DistrictReadOnlyAdmin: "District Admin",
+ DistrictAdmin: "District Admin",
+ StateLabAdmin: "State Lab Admin",
+ StateReadOnlyAdmin: "State Admin",
+ StateAdmin: "State Admin",
+ RemoteSpecialist: "Remote Specialist",
+} as const;
+
+export const AREACODES: Record = {
+ CA: [
+ "403",
+ "587",
+ "250",
+ "604",
+ "778",
+ "204",
+ "431",
+ "506",
+ "709",
+ "867",
+ "902",
+ "226",
+ "249",
+ "289",
+ "343",
+ "365",
+ "416",
+ "437",
+ "519",
+ "613",
+ "647",
+ "705",
+ "807",
+ "902",
+ "418",
+ "438",
+ "450",
+ "514",
+ "579",
+ "581",
+ "819",
+ "306",
+ "639",
+ "867",
+ ],
+ JM: ["658", "876"],
+ PR: ["787", "939"],
+ DO: ["809", "829"],
+ RE: ["262", "263", "692", "693"],
+ YT: ["269", "639"],
+ CC: ["89162"],
+ CX: ["89164"],
+ BQ: ["9"],
+ KZ: ["6", "7"],
+ SJ: ["79"],
+};
+
+export const IN_LANDLINE_AREA_CODES = [
+ "11",
+ "22",
+ "33",
+ "44",
+ "20",
+ "40",
+ "79",
+ "80",
+ "120",
+ "124",
+ "129",
+ "135",
+ "141",
+ "160",
+ "161",
+ "172",
+ "175",
+ "181",
+ "183",
+ "233",
+ "240",
+ "241",
+ "250",
+ "251",
+ "253",
+ "257",
+ "260",
+ "261",
+ "265",
+ "343",
+ "413",
+ "422",
+ "431",
+ "435",
+ "452",
+ "462",
+ "471",
+ "474",
+ "477",
+ "478",
+ "481",
+ "484",
+ "485",
+ "487",
+ "490",
+ "497",
+ "512",
+ "522",
+ "532",
+ "542",
+ "551",
+ "562",
+ "581",
+ "591",
+ "621",
+ "612",
+ "641",
+ "657",
+ "712",
+ "721",
+ "724",
+ "751",
+ "761",
+ "821",
+ "824",
+ "831",
+ "836",
+ "866",
+ "870",
+ "891",
+ "4822",
+];
+
+export const CONSENT_TYPE_CHOICES = [
+ { id: 1, text: "Consent for admission" },
+ { id: 2, text: "Patient Code Status" },
+ { id: 3, text: "Consent for procedure" },
+ { id: 4, text: "High risk consent" },
+ { id: 5, text: "Others" },
+];
+
+export const CONSENT_PATIENT_CODE_STATUS_CHOICES = [
+ { id: 1, text: "Do Not Hospitalise (DNH)" },
+ { id: 2, text: "Do Not Resuscitate (DNR)" },
+ { id: 3, text: "Comfort Care Only" },
+ { id: 4, text: "Active treatment" },
+];
+
+export const SOCIOECONOMIC_STATUS_CHOICES = [
+ "MIDDLE_CLASS",
+ "POOR",
+ "VERY_POOR",
+ "WELL_OFF",
+] as const;
+
+export const DOMESTIC_HEALTHCARE_SUPPORT_CHOICES = [
+ "FAMILY_MEMBER",
+ "PAID_CAREGIVER",
+ "NO_SUPPORT",
+] as const;
+
+export const OCCUPATION_TYPES = [
+ {
+ id: 27,
+ text: "Aircraft Pilot or Flight Engineer",
+ value: "PILOT_FLIGHT",
+ },
+ { id: 5, text: "Animal Handler", value: "ANIMAL_HANDLER" },
+ {
+ id: 9,
+ text: "Business or Finance related Occupations",
+ value: "BUSINESS_RELATED",
+ },
+ { id: 2, text: "Businessman", value: "BUSINESSMAN" },
+ { id: 14, text: "Chef or Head Cook", value: "CHEF" },
+ {
+ id: 24,
+ text: "Construction and Extraction Worker",
+ value: "CONSTRUCTION_EXTRACTION",
+ },
+ { id: 17, text: "Custodial Occupations", value: "CUSTODIAL" },
+ {
+ id: 18,
+ text: "Customer Service Occupations",
+ value: "CUSTOMER_SERVICE",
+ },
+ { id: 10, text: "Engineer", value: "ENGINEER" },
+ {
+ id: 25,
+ text: "Farming, Fishing and Forestry",
+ value: "AGRI_NATURAL",
+ },
+ {
+ id: 4,
+ text: "Healthcare Lab Worker",
+ value: "HEALTH_CARE_LAB_WORKER",
+ },
+ {
+ id: 7,
+ text: "Healthcare Practitioner",
+ value: "HEALTHCARE_PRACTITIONER",
+ },
+ { id: 3, text: "Healthcare Worker", value: "HEALTH_CARE_WORKER" },
+ { id: 30, text: "Homemaker", value: "HOMEMAKER" },
+ {
+ id: 16,
+ text: "Hospitality Service Occupations",
+ value: "HOSPITALITY",
+ },
+ {
+ id: 21,
+ text: "Insurance Sales Agent",
+ value: "INSURANCE_SALES_AGENT",
+ },
+ { id: 29, text: "Military", value: "MILITARY" },
+ {
+ id: 13,
+ text: "Office and Administrative Support Occupations",
+ value: "OFFICE_ADMINISTRATIVE",
+ },
+ {
+ id: 12,
+ text: "Other Professional Occupations",
+ value: "OTHER_PROFESSIONAL_OCCUPATIONS",
+ },
+ { id: 8, text: "Paramedics", value: "PARADEMICS" },
+ {
+ id: 26,
+ text: "Production Occupations",
+ value: "PRODUCTION_OCCUPATION",
+ },
+ {
+ id: 15,
+ text: "Protective Service Occupations",
+ value: "PROTECTIVE_SERVICE",
+ },
+ { id: 23, text: "Real Estate Sales Agent", value: "REAL_ESTATE" },
+ { id: 20, text: "Retail Sales Worker", value: "RETAIL_SALES_WORKER" },
+ {
+ id: 22,
+ text: "Sales Representative",
+ value: "SALES_REPRESENTATIVE",
+ },
+ { id: 19, text: "Sales Supervisor", value: "SALES_SUPERVISOR" },
+ { id: 1, text: "Student", value: "STUDENT" },
+ { id: 11, text: "Teacher", value: "TEACHER" },
+ { id: 28, text: "Vehicle Driver", value: "VEHICLE_DRIVER" },
+ { id: 6, text: "Others", value: "OTHERS" },
+ { id: 32, text: "Not Applicable", value: "NOT_APPLICABLE" },
+];
+
+export const PATIENT_NOTES_THREADS = {
+ Doctors: 10,
+ Nurses: 20,
+} as const;
+
+export const RATION_CARD_CATEGORY = ["BPL", "APL", "NO_CARD"] as const;
+
+export const DEFAULT_ALLOWED_EXTENSIONS = [
+ "image/*",
+ "video/*",
+ "audio/*",
+ "text/plain",
+ "text/csv",
+ "application/rtf",
+ "application/msword",
+ "application/vnd.oasis.opendocument.text",
+ "application/pdf",
+ "application/vnd.ms-excel",
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ "application/vnd.oasis.opendocument.spreadsheet,application/pdf",
+];
+
+export const SPOKE_RELATION_TYPES = [
+ {
+ text: "Regular",
+ value: SpokeRelationship.REGULAR,
+ },
+ {
+ text: "Tele ICU",
+ value: SpokeRelationship.TELE_ICU,
+ },
+];
+
+export const HumanBodyPaths = {
+ anterior: [
+ {
+ d: "M535.244,212.572c32.253.43,32.684-31.823,32.684-31.823,9.891-.215,14.191-19.783,13.331-23.653s-7.526-1.5-7.526-1.5c3.656-30.1-9.676-48.38-17.847-53.756S535.244,95.6,535.244,95.6h.43s-12.472.86-20.643,6.236-21.5,23.653-17.846,53.756c0,0-6.666-2.365-7.526,1.5s3.44,23.438,13.331,23.653c0,0,.43,32.253,32.684,31.823Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorHead",
+ },
+ {
+ d: "M512.129,213.97s31.608,4.954,47.574-1.394v14.456s-26.287,4.355-47.574,0Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorNeck",
+ },
+ {
+ d: "M505.355,231.279s-56.766,25.8-69.452,34.4c0,0,15.7,20.857,21.072,66.872C456.975,332.555,469.417,246.838,505.355,231.279Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorRightShoulder",
+ },
+ {
+ d: "M526.482,232.838l.806,137.346s-46.607-22.2-67.745,18.762C459.543,388.946,455.685,234.612,526.482,232.838Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorRightChest",
+ },
+ {
+ d: "M433.108,269.768s34.728,55.552,18.279,141.992c0,0-19.57-9.107-33.761-7.333,0,0-1.613-106.276,0-110.952S429.721,271.058,433.108,269.768Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorRightArm",
+ },
+ {
+ d: "M415.207,408.781s27.254-.968,35.963,11.45c0,0-7.58,59.024-13.547,77.57s-19.03,56.766-19.03,56.766l-22.254-2.742s1.451-34.672,1.29-45.477,5-49.993,9.514-62.249S415.207,408.781,415.207,408.781Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorRightForearm",
+ },
+ {
+ d: "M396.6,556.524l18.245,2.606a1.808,1.808,0,0,1,1.565,1.776c.049,6.373.053,30.692-2.6,41.987-2.568,10.951-16.244,28.022-26.205,35.726a4.126,4.126,0,0,1-6.575-2.7c-.192-1.322-.39-2.923-.584-4.855a1.828,1.828,0,0,0-2.054-1.637l-4.174.551a1.818,1.818,0,0,1-2.026-2.171c.631-3.043,1.887-8.187,3.72-11.529,2.591-4.724,5.9-18.948,5.442-26.76a1.79,1.79,0,0,0-1.514-1.635,7.118,7.118,0,0,0-5.448,1c-1.364,1.043-3.83,4.558-5.963,7.825-1.941,2.973-6.715.452-5.152-2.736.018-.037.037-.074.056-.111,1.936-3.71,13.063-18.708,16.288-24.513,2.9-5.221,13.627-8.747,15.171-11.984A1.706,1.706,0,0,1,396.6,556.524Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorRightHand",
+ },
+ {
+ d: "M674.037,556.2l-18.244,2.606a1.808,1.808,0,0,0-1.566,1.776c-.049,6.373-.052,30.692,2.6,41.988,2.569,10.951,16.244,28.021,26.205,35.726a4.126,4.126,0,0,0,6.576-2.7c.191-1.322.389-2.922.584-4.855a1.827,1.827,0,0,1,2.053-1.637l4.174.551a1.818,1.818,0,0,0,2.027-2.17c-.632-3.043-1.888-8.188-3.721-11.53-2.59-4.723-5.9-18.948-5.442-26.76a1.79,1.79,0,0,1,1.515-1.634,7.114,7.114,0,0,1,5.447,1c1.364,1.043,3.83,4.558,5.964,7.826,1.94,2.973,6.715.451,5.151-2.736-.018-.038-.037-.075-.056-.112-1.935-3.709-13.063-18.707-16.288-24.513-2.9-5.221-13.627-8.746-15.171-11.984A1.707,1.707,0,0,0,674.037,556.2Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorLeftHand",
+ },
+ {
+ d: "M544.705,232.838h19.137s18.062,15.643,20,19.513,29.888,42.79,26.878,128.154c0,0-16.557-16.556-31.178-15.051,0,0,2.365-33.114-34.834-34.619Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorLeftChest",
+ },
+ {
+ d: "M569.432,231.279s61.927,31.824,65.153,35.694c0,0-12.9,9.752-18.707,73.791C615.878,340.764,610.072,268.048,569.432,231.279Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorLeftShoulder",
+ },
+ {
+ d: "M638.455,271.058s14.407,18.923,14.837,23.223-1.291,105.362.86,108.8c0,0-26.233,1.29-34.834,9.891,0,0-4.3-51.176.86-78.484S633.079,279.659,638.455,271.058Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorLeftArm",
+ },
+ {
+ d: "M621.038,419s16.342-12.257,33.974-10.537c0,0,7.741,26.233,8.816,34.189s10.321,49.241,9.246,66.658.087,41.069.087,41.069-16.214,3.44-20.084,4.731c0,0-17.2-46.661-18.062-52.036S620.982,426.52,621.038,419Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorLeftForearm",
+ },
+ {
+ d: "M510.758,934.272s-20.723,1.451-24.973,1.5a56.32,56.32,0,0,0-1.556,10.672c0,4.355.484,25.481-.645,28.061s-21.771,27.254-23.383,30.641.645,8.386,1.935,9.192,2.1,4.757,4.193,5.644c1.807.765,3.064,3.709,5.644,4.032s10.482-.645,12.418.726c0,0,.887,3.144,2.58,3.306.864.082,5.644,1.774,10.644-5.967s13.04-35.019,13.439-37.791c.249-1.732-1.183-2.125-1.506-5.189a112.484,112.484,0,0,1,1.855-20.64C513.419,948.3,510.758,934.272,510.758,934.272Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorRightFoot",
+ },
+ {
+ d: "M563.251,934.191s20.756.564,25.006.616c0,0,.151,7.125.151,11.479s.162,24.351,1.29,26.932,22.531,27.576,24.144,30.963-.645,8.386-1.935,9.192-2.1,4.758-4.193,5.645c-1.807.764-3.064,3.709-5.645,4.031s-10.482-.645-12.417.726c0,0-.887,3.145-2.581,3.306-.864.082-5.644,1.774-10.643-5.967s-13.04-35.018-13.439-37.79c-.25-1.733,1.182-2.126,1.5-5.19a112.484,112.484,0,0,0-1.855-20.64C560.623,947.334,563.251,934.191,563.251,934.191Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorLeftFoot",
+ },
+ {
+ d: "M485.2,932.363l24.513-1.4s1.666-37.2,2.526-41.285,4.731-85.149,4.086-99.771c0,0-30,2.527-49.348-3.924,0,0-6.451,44.026-1.828,62.841C467.775,859.527,484.874,929.6,485.2,932.363Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorRightLeg",
+ },
+ {
+ d: "M469.231,420.715s-5.966-30.318-4.515-34.834a115.141,115.141,0,0,1,16.772-10.966c10.428-5.483,29.727-6.773,36.339-3.548,5.81,2.834,4.972,2.548,13.439,4.73l.054-142.13h9.192V334.92s32.415,1.291,31.931,33.06a72.9,72.9,0,0,0,8.869,2.419c5.322,1.129,23.062,9.031,25.642,19.675,0,0-4.945,22.2-3.655,32.684,0,0-39.4-29.835-47.306-31.609s-12.959,2.31-16.933,2.8c-4.483.547-11.71-.628-18.142-2.9C514.306,388.7,475.2,414.909,469.231,420.715Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorLowerChest",
+ },
+ {
+ d: "M461.813,481.665c2.43-11.313,8.042-43.207,7.1-55.467,0,0,48.3-30.56,50.88-30.4s12.122,5.564,23.841,2.338c0,0,6.719-3.225,13.331.162s34.874,24.149,46.324,28.987c0,0-.524,28.746,1.573,37.777s10.159,42.091,10.966,46.123,0,.806,0,.806-58.057,50.155-59.669,52.574c0,0-6.451-6.29-20.481-6.774s-20.643,6.774-20.643,6.774l-60.152-51.122S460.965,485.617,461.813,481.665Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorAbdomen",
+ },
+ {
+ d: "M554.381,790.77s30.748,3.226,51.39-4.945c0,0,3.441,40.424,0,63.432s-16.449,76.871-17.094,81.816c0,0-23.33.108-25.91-1.4,0,0-3.011-33.328-3.871-43S550.08,810.982,554.381,790.77Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorLeftLeg",
+ },
+ {
+ d: "M454.072,520.056s-4.515,29.35-6.128,48.7.323,59.346,6.128,81.278,21.288,89.343,14.514,131.272c0,0,20.464,8.064,47.808,4.516,0,0,7.2-74.822,6.7-87.73,0,0,3.333-50.745,3.333-58.7s1.72-27.738,1.72-27.738-20.642-10.106-14.837-44.08C513.311,567.576,462.351,524.571,454.072,520.056Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorRightThigh",
+ },
+ {
+ d: "M553.114,785.825s37.713,2.741,50.615-3.548c0,0-6.451-35.8-1.129-63.325s19.943-77.408,20.8-92.03,2.33-87.3-7.221-108.371l-56.426,49.455s3.441,37.629-18.922,44.725c0,0,7.741,68.807,7.741,78.913S554.857,777.654,553.114,785.825Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorLeftThigh",
+ },
+ {
+ d: "M535.624,610.466s16.722-10.1,18.818-27.355-3.386-17.578-5.805-18.545-13.063-1.291-13.063-1.291h.1s-10.644.323-13.063,1.291-7.9,1.29-5.806,18.545S535.624,610.466,535.624,610.466Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "AnteriorGroin",
+ },
+ ],
+
+ posterior: [
+ {
+ d: "M 506.9838 158.0121 C 509.6029 173.1336 512.1258 187.9477 521.5039 184.4407 C 517.7283 191.6346 525.6919 202.9266 528.0919 210.8841 C 544.9623 208.3461 562.3174 208.3461 579.1878 210.8841 C 581.5893 202.9236 589.5363 191.6662 585.7863 184.4511 C 595.6744 187.4586 596.8188 174.3021 600.3813 158.5926 C 600.1173 156.4611 595.9999 158.5806 594.7788 159.0816 C 597.7384 128.3122 591.2088 97.1811 553.7104 97.22 C 516.1444 97.1497 509.5249 128.2116 512.5008 159.0891 C 511.0564 158.4651 508.4914 157.0971 506.9838 158.0121 Z",
+ transform: "translate(-390.349 -94.472)",
+ region: "PosteriorHead",
+ },
+ {
+ d: "M 503.129 213.97 s 30.871 -1.97 46.871 0.03 v 12.456 s -26 -2.456 -47.574 0 Z",
+ transform: "translate(-362.967 -95.599)",
+ region: "PosteriorNeck",
+ },
+ {
+ d: "M545.584,228.037V361.6s-13.6,10.828-25.282,13.145c-10.077,2-36.162,3.374-36.766-.857S478.9,239.117,545.584,228.037Z",
+ transform: "translate(-390.349 -94.472)",
+ region: "PosteriorLeftChest",
+ },
+ {
+ d: "M563.865,228.037V361.6s13.6,10.828,25.282,13.145c10.076,2,36.161,3.374,36.766-.857S630.546,239.117,563.865,228.037Z",
+ transform: "translate(-390.349 -94.472)",
+ region: "PosteriorRightChest",
+ },
+ {
+ d: "M550.973,228.188h8.914l.151,136.435s20.7,17.828,59.681,16.317c0,0-4.684,38.528-1.057,56.508s9.216,41.248,9.216,41.248-77.812,30.218-145.954-.151c0,0,9.67-35.96,9.972-58.321a167.6,167.6,0,0,0-4.23-39.888s37.924,5.439,62.1-15.713C549.764,364.623,550.52,228.188,550.973,228.188Z",
+ transform: "translate(-390.349 -94.472)",
+ region: "PosteriorAbdomen",
+ },
+ {
+ d: "M523.223,230.857s-40.694,20.548-50.968,25.182-11.08,5.439-11.08,5.439,15.512,18.735,18.533,70.509C479.708,331.987,489.58,244.354,523.223,230.857Z",
+ transform: "translate(-390.349 -94.472)",
+ region: "PosteriorLeftShoulder",
+ },
+ {
+ d: "M587.084,230.857s40.693,20.548,50.968,25.182,11.08,5.439,11.08,5.439S633.62,280.213,630.6,331.987C630.6,331.987,620.726,244.354,587.084,230.857Z",
+ transform: "translate(-390.349 -94.472)",
+ region: "PosteriorRightShoulder",
+ },
+ {
+ d: "M457.951,265.306s-12.49,14.706-13.5,29.613,1.813,82.194.6,95.691c0,0,15.512-1.209,22.16,3.022s9.872,4.23,9.872,4.23,3.223-32.232,1.41-53.385S467.823,277.393,457.951,265.306Z",
+ transform: "translate(-390.349 -94.472)",
+ region: "PosteriorLeftArm",
+ },
+ {
+ d: "M444.655,394.639s3.627-1.209,8.864,1.612,21.153,4.835,21.153,4.835a241.987,241.987,0,0,1-6.245,50.968c-6.446,27.8-23.167,79.977-22.966,81.992,0,0-17.325-4.03-20.951-3.828,0,0,1.209-21.354,1.612-31.427s.2-42.91,6.648-63.659S444.454,396.049,444.655,394.639Z",
+ transform: "translate(-390.349 -94.472)",
+ region: "PosteriorLeftForearm",
+ },
+ {
+ d: "M423.5,533.844s-4.029,2.82-7.454,5.036-12.49,13.1-15.311,18.131-11.482,15.915-10.274,16.923,5.44.2,7.454-2.216,7.051-8.663,10.476-7.253c0,0,1.007,12.087-3.224,22.966s-4.633,13.7-4.633,13.7,2.591,2.22,7.063.809q.291-.091.592-.2s1.612,4.835.806,8.864,3.022,3.425,7.655,1.007,21.959-22.562,24.175-35.053,1.611-40.895,1.611-40.895S427.33,534.65,423.5,533.844Z",
+ transform: "translate(-390.349 -94.472)",
+ region: "PosteriorLeftHand",
+ },
+ {
+ d: "M650.678,265.306s12.49,14.706,13.5,29.613-1.813,82.194-.6,95.691c0,0-15.512-1.209-22.16,3.022s-9.871,4.23-9.871,4.23-3.224-32.232-1.41-53.385S640.807,277.393,650.678,265.306Z",
+ transform: "translate(-390.349 -94.472)",
+ region: "PosteriorRightArm",
+ },
+ {
+ d: "M663.974,394.639s-3.626-1.209-8.864,1.612-21.153,4.835-21.153,4.835a242.066,242.066,0,0,0,6.245,50.968c6.447,27.8,23.168,79.977,22.966,81.992,0,0,17.325-4.03,20.951-3.828,0,0-1.208-21.354-1.611-31.427s-.2-42.91-6.648-63.659S664.175,396.049,663.974,394.639Z",
+ transform: "translate(-390.349 -94.472)",
+ region: "PosteriorRightForearm",
+ },
+ {
+ d: "M685.127,533.844s4.029,2.82,7.453,5.036,12.491,13.1,15.311,18.131,11.483,15.915,10.274,16.923-5.439.2-7.454-2.216-7.051-8.663-10.475-7.253c0,0-1.008,12.087,3.223,22.966s4.633,13.7,4.633,13.7-2.59,2.22-7.062.809q-.291-.091-.593-.2s-1.612,4.835-.806,8.864-3.022,3.425-7.655,1.007-21.958-22.562-24.174-35.053-1.612-40.895-1.612-40.895S681.3,534.65,685.127,533.844Z",
+ transform: "translate(-390.349 -94.472)",
+ region: "PosteriorRightHand",
+ },
+ {
+ d: "M552.635,495.366s0,66.279-.6,69.9c-.051.277-.126.982-.2,2.065-5.691,6.673-27.473,28.254-58.673,9.04a10.164,10.164,0,0,1-1.738-1.309c-23.066-21.783-7.076-50.968-6.371-52.2l-2.216-1.234c-.176.327-17.652,32.107,6.849,55.249a14.16,14.16,0,0,0,2.166,1.662c9.519,5.842,18.232,8.033,25.988,8.033,16.116,0,27.977-9.519,33.642-15.235-1.661,20.07-6.144,82.369-6.5,86-.4,4.231-7.605,77.51-7.605,80.935,0,0-36.111-4.785-45.579-2.972,0,0,.2-37.672-2.821-59.63s-14.5-65.473-15.914-101.936-1.411-65.473,7.453-91.46C480.514,482.272,499.048,497.582,552.635,495.366Z",
+ transform: "translate(-390.349 -94.472)",
+ region: "PosteriorLeftThighAndButtock",
+ },
+ {
+ d: "M555.471,495.366s0,66.279.6,69.9c.051.277.126.982.2,2.065,5.691,6.673,27.473,28.254,58.673,9.04a10.164,10.164,0,0,0,1.738-1.309c23.066-21.783,7.076-50.968,6.371-52.2l2.216-1.234c.176.327,17.652,32.107-6.85,55.249a14.151,14.151,0,0,1-2.165,1.662c-9.519,5.842-18.232,8.033-25.988,8.033-16.116,0-27.977-9.519-33.643-15.235,1.662,20.07,6.145,82.369,6.5,86,.4,4.231,7.605,77.51,7.605,80.935,0,0,36.111-4.785,45.579-2.972,0,0-.2-37.672,2.82-59.63s14.5-65.473,15.915-101.936,1.41-65.473-7.453-91.46C627.592,482.272,609.058,497.582,555.471,495.366Z",
+ transform: "translate(-390.349 -94.472)",
+ region: "PosteriorRightThighAndButtock",
+ },
+ {
+ d: "M492.2,739.529s21.354-2.418,42.909,3.425c0,0,3.627,43.312,1.612,61.846s-7.655,75.445-6.849,80.078c0,0-19.944.907-25.988,2.518,0,0-2.619-29.009-9.267-49.154S486.961,754.839,492.2,739.529Z",
+ transform: "translate(-390.349 -94.472)",
+ region: "PosteriorLeftLeg",
+ },
+ {
+ d: "M617.088,739.529s-21.354-2.418-42.909,3.425c0,0-3.626,43.312-1.612,61.846s7.655,75.445,6.85,80.078c0,0,19.944.907,25.987,2.518,0,0,2.619-29.009,9.267-49.154S622.326,754.839,617.088,739.529Z",
+ transform: "translate(-390.349 -94.472)",
+ region: "PosteriorRightLeg",
+ },
+ {
+ d: "M504.387,891.023s17.728-.806,24.879-2.619c0,0,2.015,6.245,1.209,18.131s-1.007,21.555-.6,23.771,1.813,9.67-1.209,15.512S520,967.172,516.978,972.007s-10.275,5.439-11.886-1.611c0,0-1.813,3.424-7.857,1.41s-9.67-1.209-11.483-5.44-4.835-11.684-1.41-16.922,18.937-18.534,20.145-25.182S505.6,895.455,504.387,891.023Z",
+ transform: "translate(-390.349 -94.472)",
+ region: "PosteriorLeftFoot",
+ },
+ {
+ d: "M604.752,891.023s-17.728-.806-24.88-2.619c0,0-2.014,6.245-1.209,18.131s1.008,21.555.605,23.771-1.813,9.67,1.209,15.512,8.662,21.354,11.684,26.189,10.274,5.439,11.886-1.611c0,0,1.813,3.424,7.856,1.41s9.67-1.209,11.483-5.44,4.835-11.684,1.41-16.922-18.936-18.534-20.145-25.182S603.543,895.455,604.752,891.023Z",
+ transform: "translate(-390.349 -94.472)",
+ region: "PosteriorRightFoot",
+ },
+ ],
+} as const;
+
+export type HumanBodyRegion = (typeof HumanBodyPaths)[
+ | "anterior"
+ | "posterior"][number]["region"];
+
+export const PressureSoreExudateAmountOptions = [
+ "None",
+ "Light",
+ "Moderate",
+ "Heavy",
+] as const;
+
+export const PressureSoreTissueTypeOptions = [
+ "Closed",
+ "Epithelial",
+ "Granulation",
+ "Slough",
+ "Necrotic",
+] as const;
+
+export const FILE_EXTENSIONS = {
+ IMAGE: ["jpeg", "jpg", "png", "gif", "svg", "bmp", "webp", "jfif"],
+ AUDIO: ["mp3", "wav"],
+ VIDEO: [
+ "webm",
+ "mpg",
+ "mp2",
+ "mpeg",
+ "mpe",
+ "mpv",
+ "ogg",
+ "mp4",
+ "m4v",
+ "avi",
+ "wmv",
+ "mov",
+ "qt",
+ "flv",
+ "swf",
+ ],
+ PRESENTATION: ["pptx"],
+ DOCUMENT: ["pdf", "docx"],
+} as const;
+
+export const PREVIEWABLE_FILE_EXTENSIONS = [
+ "html",
+ "htm",
+ "pdf",
+ "mp4",
+ "webm",
+ "jpg",
+ "jpeg",
+ "png",
+ "gif",
+ "webp",
+] as const;
+
+export const HEADER_CONTENT_TYPES = {
+ pdf: "application/pdf",
+ txt: "text/plain",
+ jpeg: "image/jpeg",
+ jpg: "image/jpeg",
+ doc: "application/msword",
+ xls: "application/vnd.ms-excel",
+ docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+ epub: "application/epub+zip",
+ gif: "image/gif",
+ html: "text/html",
+ htm: "text/html",
+ mp4: "video/mp4",
+ png: "image/png",
+ ppt: "application/vnd.ms-powerpoint",
+ pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
+ svg: "image/svg+xml",
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+} as const;
diff --git a/src/components/CareLivekit.tsx b/src/components/CareLivekit.tsx
index 2a67e1b..71ce171 100644
--- a/src/components/CareLivekit.tsx
+++ b/src/components/CareLivekit.tsx
@@ -1,16 +1,9 @@
import React, { Suspense } from "react";
-const PageTitle = React.lazy(() => import("core/PageTitle"));
const CareLivekit: React.FC = () => {
return (
Loading...}>
-
- {PageTitle ? (
-
- ) : (
- "PageTitle not available"
- )}
-
+ "PageTitle not available"
);
};
diff --git a/src/components/DoctorConnectButtons.tsx b/src/components/DoctorConnectButtons.tsx
index 631e3dc..b3e9332 100644
--- a/src/components/DoctorConnectButtons.tsx
+++ b/src/components/DoctorConnectButtons.tsx
@@ -1,38 +1,45 @@
import React from "react";
import { navigate } from "raviger";
-import CareIcon from "@core/CAREUI/icons/CareIcon";
-import { triggerGoal } from "@core/Integrations/Plausible";
-import useAuthUser from "@core/common/hooks/useAuthUser";
-
-import { DoctorConnectButtonComponentType } from "@/pluginTypes";
-
-const DoctorConnectButtons: DoctorConnectButtonComponentType = ({ user }) => {
- const authUser = useAuthUser();
-
- const handleLivekitConnect = (e: React.MouseEvent) => {
- e.preventDefault();
- e.stopPropagation();
-
- triggerGoal("Doctor Connect Click", {
- medium: "Livekit Video Call",
- userId: authUser.id,
- targetUserType: user.user_type,
- });
-
- // Navigate to the Livekit video call page with the user's ID
- navigate(`/live_connect/${user.username}`);
+import { triggerGoal } from "core/Integrations/Plausible";
+
+// Create a type wrapper component for the lazy-loaded components
+const DoctorConnectButtons = ({ user }: { user: any }) => {
+ const AuthUserWrapper = () => {
+ const authUser = useAuthUser();
+ const handleLivekitConnect = async (
+ e: React.MouseEvent
+ ) => {
+ e.preventDefault();
+ e.stopPropagation();
+
+ await triggerGoal("Doctor Connect Click", {
+ medium: "Livekit Video Call",
+ userId: authUser.id,
+ targetUserType: user.user_type,
+ });
+
+ navigate(`/live_connect/${user.username}`);
+ };
+
+ const ConnectDoctorText = "Connect via Livekit Video Call";
+
+ return (
+
+
+ {ConnectDoctorText}
+ Loading...
}>
+
+
+
+
+ );
};
- const ConnectDoctorText = "Connect via Livekit Video Call";
-
return (
-
-
- {ConnectDoctorText}
-
-
-
+ Loading...}>
+
+
);
};
diff --git a/src/components/DoctorLiveConnect.tsx b/src/components/DoctorLiveConnect.tsx
index 3c8b270..90d8708 100644
--- a/src/components/DoctorLiveConnect.tsx
+++ b/src/components/DoctorLiveConnect.tsx
@@ -1,15 +1,33 @@
import React from "react";
-
import LiveKitComponent from "./LiveKitComponent";
-import { useAuthContext } from "@core/common/hooks/useAuthUser";
+// Convert core imports to lazy imports
+const useAuthContext = React.lazy(() =>
+ import("@core/common/hooks/useAuthUser").then(
+ (module) => module.useAuthContext
+ )
+);
const PageTitle = React.lazy(() => import("@core/components/Common/PageTitle"));
const DoctorLiveConnect = ({ username }: { username: string }) => {
- const { user: currentUser } = useAuthContext();
+ // Wrap the useAuthContext in a React.Suspense
+ const AuthContextWrapper = () => {
+ const auth = useAuthContext();
+ const currentUser = auth?.user;
+
+ return (
+
+ );
+ };
+
return (
}>
+
+
@@ -22,10 +40,9 @@ const DoctorLiveConnect = ({ username }: { username: string }) => {
-
+ Loading...
}>
+
+
diff --git a/src/models/models.ts b/src/models/models.ts
new file mode 100644
index 0000000..e69de29
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..f85d92a
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,26 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+ "baseUrl": ".",
+ "paths": {
+ "core/*": ["./core/src/*"],
+ "@/*": ["./src/*"]
+ }
+ },
+ "include": ["src", "core/src/**/*"],
+ "references": [{ "path": "./tsconfig.node.json" }]
+}
diff --git a/tsconfig.node.json b/tsconfig.node.json
new file mode 100644
index 0000000..42872c5
--- /dev/null
+++ b/tsconfig.node.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "skipLibCheck": true,
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/vite.config.ts b/vite.config.ts
index 9ee713e..827c160 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,6 +1,7 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import federation from "@originjs/vite-plugin-federation";
+import path from "path";
export default defineConfig({
plugins: [
@@ -11,14 +12,15 @@ export default defineConfig({
exposes: {
"./CareLivekit": "./src/components/CareLivekit.tsx",
},
- remotes: {
- core: {
- external:
- 'Promise.resolve(window.location.origin + "/bundle/sharedCore.js")',
- from: "vite",
- externalType: "promise",
- },
- },
+ // remotes: {
+ // core: {
+ // external:
+ // 'Promise.resolve(window.location.origin + "/bundle/sharedCore.js")',
+ // from: "vite",
+ // externalType: "promise",
+ // },
+ // },
+ shared: ["react", "react-dom"],
}),
],
build: {
@@ -36,4 +38,9 @@ export default defineConfig({
},
},
},
+ resolve: {
+ alias: {
+ "@": path.resolve(__dirname, "./src"),
+ },
+ },
});