- {kasp_enabled && (
+ {careConfig.kasp.enabled && (
- {kasp_string}
+
+ {careConfig.kasp.string}
+
- o ? `Show ${kasp_string}` : `Show Non ${kasp_string}`
+ o
+ ? `Show ${careConfig.kasp.string}`
+ : `Show Non ${careConfig.kasp.string}`
}
value={filterState.is_kasp}
onChange={(v) => setFilterState({ ...filterState, is_kasp: v })}
diff --git a/src/Components/Patient/PatientInfoCard.tsx b/src/Components/Patient/PatientInfoCard.tsx
index 005c93521d6..f301db6333e 100644
--- a/src/Components/Patient/PatientInfoCard.tsx
+++ b/src/Components/Patient/PatientInfoCard.tsx
@@ -12,7 +12,6 @@ import { Switch, MenuItem, Field, Label } from "@headlessui/react";
import { Link, navigate } from "raviger";
import { useState } from "react";
import CareIcon from "../../CAREUI/icons/CareIcon.js";
-import useConfig from "../../Common/hooks/useConfig.js";
import dayjs from "../../Utils/dayjs.js";
import {
classNames,
@@ -43,6 +42,7 @@ import useQuery from "../../Utils/request/useQuery.js";
import FetchRecordsModal from "../ABDM/FetchRecordsModal.js";
import { SkillModel } from "../Users/models.js";
import { AuthorizedForConsultationRelatedActions } from "../../CAREUI/misc/AuthorizedChild.js";
+import careConfig from "@careConfig";
const formatSkills = (arr: SkillModel[]) => {
const skills = arr.map((skill) => skill.skill_object.name);
@@ -73,8 +73,6 @@ export default function PatientInfoCard(props: {
const [openDischargeSummaryDialog, setOpenDischargeSummaryDialog] =
useState(false);
const [openDischargeDialog, setOpenDischargeDialog] = useState(false);
-
- const { enable_hcx, enable_abdm } = useConfig();
const [showLinkCareContext, setShowLinkCareContext] = useState(false);
const patient = props.patient;
@@ -665,7 +663,7 @@ export default function PatientInfoCard(props: {
],
]
.concat(
- enable_hcx
+ careConfig.hcx.enabled
? [
[
`/facility/${patient.facility}/patient/${patient.id}/consultation/${consultation?.id}/claims`,
@@ -735,7 +733,7 @@ export default function PatientInfoCard(props: {
- {enable_abdm &&
+ {careConfig.abdm.enabled &&
(patient.abha_number ? (
<>
diff --git a/src/Components/Patient/PatientRegister.tsx b/src/Components/Patient/PatientRegister.tsx
index 3b38c3d54af..c25a6365e70 100644
--- a/src/Components/Patient/PatientRegister.tsx
+++ b/src/Components/Patient/PatientRegister.tsx
@@ -61,7 +61,6 @@ import countryList from "../../Common/static/countries.json";
import { debounce } from "lodash-es";
import useAppHistory from "../../Common/hooks/useAppHistory";
-import useConfig from "../../Common/hooks/useConfig";
import { validatePincode } from "../../Common/validation";
import { FormContextValue } from "../Form/FormContext.js";
import useAuthUser from "../../Common/hooks/useAuthUser.js";
@@ -73,6 +72,7 @@ import SelectMenuV2 from "../Form/SelectMenuV2.js";
import _ from "lodash";
import { ILocalBodies } from "../ExternalResult/models.js";
import { useTranslation } from "react-i18next";
+import careConfig from "@careConfig";
const Loading = lazy(() => import("../Common/Loading"));
const PageTitle = lazy(() => import("../Common/PageTitle"));
@@ -181,7 +181,6 @@ export const PatientRegister = (props: PatientRegisterProps) => {
const authUser = useAuthUser();
const { t } = useTranslation();
const { goBack } = useAppHistory();
- const { gov_data_api_key, enable_hcx, enable_abdm } = useConfig();
const { facilityId, id } = props;
const [state, dispatch] = useReducer(patientFormReducer, initialState);
const [showAlertMessage, setAlertMessage] = useState({
@@ -504,7 +503,7 @@ export const PatientRegister = (props: PatientRegisterProps) => {
const errors: Partial> = {};
const insuranceDetailsError = insuranceDetails
- .map((policy) => HCXPolicyValidator(policy, enable_hcx))
+ .map((policy) => HCXPolicyValidator(policy, careConfig.hcx.enabled))
.find((error) => !!error);
setInsuranceDetailsError(insuranceDetailsError);
@@ -644,7 +643,10 @@ export const PatientRegister = (props: PatientRegisterProps) => {
const handlePincodeChange = async (e: any, setField: any) => {
if (!validatePincode(e.value)) return;
- const pincodeDetails = await getPincodeDetails(e.value, gov_data_api_key);
+ const pincodeDetails = await getPincodeDetails(
+ e.value,
+ careConfig.govDataApiKey,
+ );
if (!pincodeDetails) return;
const matchedState = stateData?.results?.find((state) => {
@@ -792,7 +794,7 @@ export const PatientRegister = (props: PatientRegisterProps) => {
body: policy,
});
- if (enable_hcx && policyData?.id) {
+ if (careConfig.hcx.enabled && policyData?.id) {
await request(routes.hcxCheckEligibility, {
body: { policy: policyData?.id },
onResponse: ({ res }) => {
@@ -1181,7 +1183,7 @@ export const PatientRegister = (props: PatientRegisterProps) => {
Import From External Results
- {enable_abdm && (
+ {careConfig.abdm.enabled && (
ABHA Details
diff --git a/src/Components/Patient/SampleDetails.tsx b/src/Components/Patient/SampleDetails.tsx
index 91fd2d4a122..deda220a891 100644
--- a/src/Components/Patient/SampleDetails.tsx
+++ b/src/Components/Patient/SampleDetails.tsx
@@ -4,7 +4,7 @@ import { lazy } from "react";
import ButtonV2 from "../Common/components/ButtonV2";
import Card from "../../CAREUI/display/Card";
-import { FileUpload } from "./FileUpload";
+import { FileUpload } from "../Files/FileUpload";
import Page from "../Common/components/Page";
import _ from "lodash-es";
import { formatDateTime, formatPatientAge } from "../../Utils/utils";
@@ -428,7 +428,7 @@ export const SampleDetails = ({ id }: DetailRoute) => {
{showPatientCard(sampleDetails?.patient_object)}
-
+
Sample Test History
{sampleDetails?.flow &&
sampleDetails.flow.map((flow: FlowModel) => renderFlow(flow))}
@@ -437,12 +437,9 @@ export const SampleDetails = ({ id }: DetailRoute) => {
);
diff --git a/src/Components/Patient/SamplePreview.tsx b/src/Components/Patient/SamplePreview.tsx
index 479b426c3f2..f56714f0c36 100644
--- a/src/Components/Patient/SamplePreview.tsx
+++ b/src/Components/Patient/SamplePreview.tsx
@@ -84,7 +84,7 @@ export default function SampleReport(props: ISamplePreviewProps) {
diff --git a/src/Components/Patient/ShiftCreate.tsx b/src/Components/Patient/ShiftCreate.tsx
index 7307727d372..c3b01ad189d 100644
--- a/src/Components/Patient/ShiftCreate.tsx
+++ b/src/Components/Patient/ShiftCreate.tsx
@@ -20,7 +20,6 @@ import { navigate } from "raviger";
import { parsePhoneNumber } from "../../Utils/utils.js";
import { phonePreg } from "../../Common/validation";
import useAppHistory from "../../Common/hooks/useAppHistory";
-import useConfig from "../../Common/hooks/useConfig";
import { useTranslation } from "react-i18next";
import Page from "../Common/components/Page.js";
import Card from "../../CAREUI/display/Card.js";
@@ -30,6 +29,7 @@ import { PhoneNumberValidator } from "../Form/FieldValidators.js";
import useQuery from "../../Utils/request/useQuery.js";
import routes from "../../Redux/api.js";
import request from "../../Utils/request/request.js";
+import careConfig from "@careConfig";
const Loading = lazy(() => import("../Common/Loading"));
@@ -44,7 +44,6 @@ export const ShiftCreate = (props: patientShiftProps) => {
const [isLoading, setIsLoading] = useState(false);
const [patientCategory, setPatientCategory] = useState
();
const { t } = useTranslation();
- const { wartime_shifting } = useConfig();
const initForm: any = {
shifting_approving_facility: null,
@@ -79,7 +78,7 @@ export const ShiftCreate = (props: patientShiftProps) => {
},
};
- if (wartime_shifting) {
+ if (careConfig.wartimeShifting) {
requiredFields = {
...requiredFields,
shifting_approving_facility: {
@@ -200,7 +199,7 @@ export const ShiftCreate = (props: patientShiftProps) => {
setIsLoading(true);
const data = {
- status: wartime_shifting ? "PENDING" : "APPROVED",
+ status: careConfig.wartimeShifting ? "PENDING" : "APPROVED",
origin_facility: props.facilityId,
shifting_approving_facility: state.form.shifting_approving_facility?.id,
assigned_facility: state.form?.assigned_facility?.id,
@@ -282,7 +281,7 @@ export const ShiftCreate = (props: patientShiftProps) => {
types={["mobile", "landline"]}
/>
- {wartime_shifting && (
+ {careConfig.wartimeShifting && (
Name of shifting approving facility
@@ -336,7 +335,7 @@ export const ShiftCreate = (props: patientShiftProps) => {
label="Patient Category"
/>
- {wartime_shifting && (
+ {careConfig.wartimeShifting && (
<>
{
setfile(e.target.files[0]);
const fileName = e.target.files[0].name;
const ext: string = fileName.split(".")[1];
- setcontentType(header_content_type[ext]);
+ setcontentType(
+ HEADER_CONTENT_TYPES[ext as keyof typeof HEADER_CONTENT_TYPES],
+ );
return e.target.files[0];
};
const handleUpload = async () => {
diff --git a/src/Components/Patient/Waveform.tsx b/src/Components/Patient/Waveform.tsx
deleted file mode 100644
index d567739a3d2..00000000000
--- a/src/Components/Patient/Waveform.tsx
+++ /dev/null
@@ -1,150 +0,0 @@
-import { useEffect, useRef, useState } from "react";
-import { LinePlot } from "../Facility/Consultations/components/LinePlot";
-
-export type WaveformType = {
- data: string;
- "data-baseline": number;
- "data-high-limit": number;
- "data-low-limit": number;
- "date-time": string;
- device_id: string;
- observation_id: "waveform";
- "patient-id": number;
- "patient-name": string;
- resolution: `${number}uV`;
- "sampling rate": `${number}/sec`;
- "wave-name": string;
-};
-
-export default function Waveform(props: {
- wave: WaveformType;
- color?: string;
- title: string;
- metrics?: boolean;
- classes?: string;
- defaultSpace?: boolean;
- wavetype?: "STREAM" | "REFRESH";
-}) {
- const wave = props.wave;
- const data = wave.data.split(" ").map(Number);
- const viewable = data.length;
- const [queueData, setQueueData] = useState(
- Array(viewable).fill(null),
- );
- const [refreshData, setRefreshData] = useState([]);
- const [lastData, setLastData] = useState([]);
- const [xData, setXData] = useState([]);
- const [lastStream, setLastStream] = useState(0);
- const [rPointer, setRPointer] = useState(0);
-
- const initialRender = useRef(true);
-
- useEffect(() => {
- if (props.wavetype === "STREAM") {
- setQueueData(queueData.concat(data));
- } else {
- if (lastData.length === 0) {
- setLastData(data);
- } else {
- setRefreshData(data);
- }
- setRPointer(0);
- }
- setXData(Array.from(Array(viewable).keys()));
-
- let seconds = 1;
- setLastStream(0);
- const timer = setInterval(() => {
- setLastStream(seconds);
- seconds++;
- }, 1000);
- return () => clearInterval(timer);
- }, [props.wave]);
-
- useEffect(() => {
- const timeout = setTimeout(() => {
- if (props.wavetype === "STREAM") {
- if (queueData.length > 30000) {
- setQueueData(queueData.slice(-viewable));
- } else {
- setQueueData(queueData.slice(2));
- }
- }
- }, 6);
- return () => clearTimeout(timeout);
- }, [queueData]);
-
- useEffect(() => {
- let timeout: NodeJS.Timeout;
- if (initialRender.current) {
- initialRender.current = false;
- } else {
- timeout = setTimeout(() => {
- setRefreshData([
- ...data.slice(0, rPointer - 25),
- ...Array(50).fill(null),
- ...lastData.slice(rPointer - 25),
- ]);
- setRPointer(rPointer + Math.round(viewable / 150));
- }, 2);
- }
- return () => clearTimeout(timeout);
- }, [refreshData]);
-
- useEffect(() => {
- if (refreshData.length === 0) {
- setRefreshData(data);
- }
- }, [lastData]);
-
- useEffect(() => {
- if (rPointer >= data.length) {
- setLastData(data);
- }
- }, [rPointer]);
-
- return (
-
-
- {props.title}
-
-
-
- {props.metrics && (
-
-
Lowest: {Math.min(...queueData.slice(0, viewable))}
-
Highest: {Math.max(...queueData.slice(0, viewable))}
-
Stream Length: {data.length}
-
Buffer Length: {queueData.length}
-
Sampling Rate: {wave["sampling rate"]}
-
Lag: {Math.round(queueData.length / viewable)} seconds
-
Last response: {lastStream} sec ago
- {queueData.length > viewable && (
-
setQueueData(queueData.slice(-1 * viewable))}
- >
- Clear Buffer
-
- )}
-
- )}
-
-
- );
-}
diff --git a/src/Components/Patient/models.tsx b/src/Components/Patient/models.tsx
index 5387e457e9e..7676d294b4c 100644
--- a/src/Components/Patient/models.tsx
+++ b/src/Components/Patient/models.tsx
@@ -2,6 +2,7 @@ import { ConsultationModel, PatientCategory } from "../Facility/models";
import { PerformedByModel } from "../HCX/misc";
import {
CONSCIOUSNESS_LEVEL,
+ HEARTBEAT_RHYTHM_CHOICES,
HumanBodyRegion,
INSULIN_INTAKE_FREQUENCY_OPTIONS,
LIMB_RESPONSE_OPTIONS,
@@ -12,7 +13,6 @@ import {
PressureSoreTissueTypeOptions,
RATION_CARD_CATEGORY,
RESPIRATORY_SUPPORT,
- RHYTHM_CHOICES,
VENTILATOR_MODE_OPTIONS,
} from "../../Common/constants";
@@ -311,7 +311,7 @@ export type IPressureSore = {
};
export interface DailyRoundsModel {
spo2?: number;
- rhythm?: (typeof RHYTHM_CHOICES)[number]["text"];
+ rhythm?: (typeof HEARTBEAT_RHYTHM_CHOICES)[number];
rhythm_detail?: string;
bp?: BloodPressure;
pulse?: number;
diff --git a/src/Components/Resource/ResourceBoardView.tsx b/src/Components/Resource/ResourceBoardView.tsx
index 421fab4ab06..bff0282f91a 100644
--- a/src/Components/Resource/ResourceBoardView.tsx
+++ b/src/Components/Resource/ResourceBoardView.tsx
@@ -9,12 +9,12 @@ import BadgesList from "./BadgesList";
import { formatFilter } from "./Commons";
import useFilters from "../../Common/hooks/useFilters";
import { ExportButton } from "../Common/Export";
-import SwitchTabs from "../Common/components/SwitchTabs";
import ButtonV2 from "../Common/components/ButtonV2";
import { useTranslation } from "react-i18next";
import { AdvancedFilterButton } from "../../CAREUI/interactive/FiltersSlideover";
import CareIcon from "../../CAREUI/icons/CareIcon";
import SearchInput from "../Form/SearchInput";
+import Tabs from "../Common/components/Tabs";
const Loading = lazy(() => import("../Common/Loading"));
const PageTitle = lazy(() => import("../Common/PageTitle"));
@@ -67,12 +67,13 @@ export default function BoardView() {
onChange={(e) => updateQuery({ [e.name]: e.value })}
placeholder={t("search_resource")}
/>
- setBoardFilter(ACTIVE)}
- onClickTab2={() => setBoardFilter(COMPLETED)}
- isTab2Active={boardFilter !== ACTIVE}
+ setBoardFilter(tab ? COMPLETED : ACTIVE)}
+ currentTab={boardFilter !== ACTIVE ? 1 : 0}
/>
diff --git a/src/Components/Scribe/Scribe.tsx b/src/Components/Scribe/Scribe.tsx
index c942d130a43..d952ff7b1b2 100644
--- a/src/Components/Scribe/Scribe.tsx
+++ b/src/Components/Scribe/Scribe.tsx
@@ -5,10 +5,10 @@ import CareIcon from "../../CAREUI/icons/CareIcon";
import routes from "../../Redux/api";
import * as Notify from "../../Utils/Notifications";
import request from "../../Utils/request/request";
-import axios from "axios";
import { UserModel } from "../Users/models";
-import useConfig from "../../Common/hooks/useConfig";
import useSegmentedRecording from "../../Utils/useSegmentedRecorder";
+import careConfig from "@careConfig";
+import uploadFile from "../../Utils/request/uploadFile";
interface FieldOption {
id: string | number;
@@ -63,7 +63,6 @@ const SCRIBE_FILE_TYPES = {
};
export const Scribe: React.FC = ({ form, onFormUpdate }) => {
- const { enable_scribe } = useConfig();
const [open, setOpen] = useState(false);
const [_progress, setProgress] = useState(0);
const [stage, setStage] = useState("start");
@@ -120,21 +119,20 @@ export const Scribe: React.FC = ({ form, onFormUpdate }) => {
return;
}
const newFile = new File([f], `${internal_name}`, { type: f.type });
- const config = {
- headers: {
- "Content-type": newFile?.type?.split(";")?.[0],
- "Content-disposition": "inline",
- },
+ const headers = {
+ "Content-type": newFile?.type?.split(";")?.[0],
+ "Content-disposition": "inline",
};
- axios
- .put(url, newFile, config)
- .then(() => {
- resolve();
- })
- .catch((error) => {
- reject(error);
- });
+ uploadFile(
+ url,
+ newFile,
+ "PUT",
+ headers,
+ (xhr: XMLHttpRequest) => (xhr.status === 200 ? resolve() : reject()),
+ null,
+ reject,
+ );
});
};
@@ -546,7 +544,7 @@ export const Scribe: React.FC = ({ form, onFormUpdate }) => {
}
}
- if (!enable_scribe) return null;
+ if (!careConfig.scribe.enabled) return null;
return (
diff --git a/src/Components/Scribe/formDetails.ts b/src/Components/Scribe/formDetails.ts
index d085a72d331..6300ac7e3c2 100644
--- a/src/Components/Scribe/formDetails.ts
+++ b/src/Components/Scribe/formDetails.ts
@@ -68,13 +68,15 @@ const DAILY_ROUND_FORM_SCRIBE_DATA: Field[] = [
friendlyName: "Patient Category",
id: "patient_category",
type: "string",
- example: "Comfort Care",
+ example: "Mild",
default: "",
description: "A string to categorize the patient.",
- options: PATIENT_CATEGORIES.map((category) => ({
- id: category.id,
- text: category.text,
- })),
+ options: PATIENT_CATEGORIES.filter((c) => c.id !== "Comfort").map(
+ (category) => ({
+ id: category.id,
+ text: category.text,
+ }),
+ ),
validator: (value) => {
return typeof value === "string";
},
@@ -268,7 +270,7 @@ const DAILY_ROUND_FORM_SCRIBE_DATA: Field[] = [
});
return true;
},
- },
+ } /*
{
friendlyName: "Prescriptions",
id: "prescriptions",
@@ -328,7 +330,7 @@ const DAILY_ROUND_FORM_SCRIBE_DATA: Field[] = [
return true;
},
},
- /*{
+ {
friendlyName: "Round Type",
id: "rounds_type",
type: "string",
@@ -353,7 +355,7 @@ const DAILY_ROUND_FORM_SCRIBE_DATA: Field[] = [
"A string to store the date and time at which the round was taken or measured. 'The round was taken yesterday/today' would amount to yesterday/today's date.",
validator: (value) => typeof value === "string",
},
-*/
+*/,
];
export const SCRIBE_FORMS: { [key: string]: ScribeForm } = {
diff --git a/src/Components/Shifting/BoardView.tsx b/src/Components/Shifting/BoardView.tsx
index 413774bceac..f4fb45093aa 100644
--- a/src/Components/Shifting/BoardView.tsx
+++ b/src/Components/Shifting/BoardView.tsx
@@ -12,15 +12,15 @@ import { downloadShiftRequests } from "../../Redux/actions";
import { formatFilter } from "./Commons";
import { navigate } from "raviger";
-import useConfig from "../../Common/hooks/useConfig";
import useFilters from "../../Common/hooks/useFilters";
import { lazy, useLayoutEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import withScrolling from "react-dnd-scrolling";
import ButtonV2 from "../Common/components/ButtonV2";
-import SwitchTabs from "../Common/components/SwitchTabs";
import { AdvancedFilterButton } from "../../CAREUI/interactive/FiltersSlideover";
import CareIcon from "../../CAREUI/icons/CareIcon";
+import Tabs from "../Common/components/Tabs";
+import careConfig from "@careConfig";
const Loading = lazy(() => import("../Common/Loading"));
const PageTitle = lazy(() => import("../Common/PageTitle"));
@@ -31,13 +31,12 @@ export default function BoardView() {
limit: -1,
cacheBlacklist: ["patient_name"],
});
- const { wartime_shifting } = useConfig();
- const shiftStatusOptions = wartime_shifting
+ const shiftStatusOptions = careConfig.wartimeShifting
? SHIFTING_CHOICES_WARTIME
: SHIFTING_CHOICES_PEACETIME;
- const COMPLETED = wartime_shifting
+ const COMPLETED = careConfig.wartimeShifting
? [
"COMPLETED",
"REJECTED",
@@ -153,12 +152,15 @@ export default function BoardView() {
placeholder={t("search_patient")}
/>
- setBoardFilter(activeBoards)}
- onClickTab2={() => setBoardFilter(completedBoards)}
- isTab2Active={boardFilter[0].text !== activeBoards[0].text}
+
+ setBoardFilter(tab ? completedBoards : activeBoards)
+ }
+ currentTab={boardFilter[0].text !== activeBoards[0].text ? 1 : 0}
/>
diff --git a/src/Components/Shifting/ListFilter.tsx b/src/Components/Shifting/ListFilter.tsx
index 12bb17db09c..17692ac8f35 100644
--- a/src/Components/Shifting/ListFilter.tsx
+++ b/src/Components/Shifting/ListFilter.tsx
@@ -17,7 +17,6 @@ import DateRangeFormField from "../Form/FormFields/DateRangeFormField";
import FiltersSlideover from "../../CAREUI/interactive/FiltersSlideover";
import { SelectFormField } from "../Form/FormFields/SelectFormField";
import PhoneNumberFormField from "../Form/FormFields/PhoneNumberFormField";
-import useConfig from "../../Common/hooks/useConfig";
import useMergeState from "../../Common/hooks/useMergeState";
import { useTranslation } from "react-i18next";
@@ -26,18 +25,20 @@ import { dateQueryString, parsePhoneNumber } from "../../Utils/utils";
import dayjs from "dayjs";
import useQuery from "../../Utils/request/useQuery";
import routes from "../../Redux/api";
+import careConfig from "@careConfig";
const getDate = (value: any) =>
value && dayjs(value).isValid() && dayjs(value).toDate();
export default function ListFilter(props: any) {
- const { kasp_enabled, kasp_string, wartime_shifting } = useConfig();
const { filter, onChange, closeFilter, removeFilters } = props;
const { t } = useTranslation();
const shiftStatusOptions = (
- wartime_shifting ? SHIFTING_CHOICES_WARTIME : SHIFTING_CHOICES_PEACETIME
+ careConfig.wartimeShifting
+ ? SHIFTING_CHOICES_WARTIME
+ : SHIFTING_CHOICES_PEACETIME
).map((option) => option.text);
const [filterState, setFilterState] = useMergeState({
@@ -227,7 +228,7 @@ export default function ListFilter(props: any) {
- {wartime_shifting && (
+ {careConfig.wartimeShifting && (
{t("shifting_approving_facility")}
@@ -308,12 +309,12 @@ export default function ListFilter(props: any) {
errorClassName="hidden"
/>
- {kasp_enabled && (
+ {careConfig.kasp.enabled && (
option}
diff --git a/src/Components/Shifting/ListView.tsx b/src/Components/Shifting/ListView.tsx
index cfffcef7377..b05795f934d 100644
--- a/src/Components/Shifting/ListView.tsx
+++ b/src/Components/Shifting/ListView.tsx
@@ -11,11 +11,7 @@ import SearchInput from "../Form/SearchInput";
import { formatDateTime, formatPatientAge } from "../../Utils/utils";
import { formatFilter } from "./Commons";
import { navigate } from "raviger";
-
-import useConfig from "../../Common/hooks/useConfig";
-
import useFilters from "../../Common/hooks/useFilters";
-
import { useTranslation } from "react-i18next";
import { AdvancedFilterButton } from "../../CAREUI/interactive/FiltersSlideover";
import CareIcon from "../../CAREUI/icons/CareIcon";
@@ -24,11 +20,11 @@ import useAuthUser from "../../Common/hooks/useAuthUser";
import request from "../../Utils/request/request";
import routes from "../../Redux/api";
import useQuery from "../../Utils/request/useQuery";
+import careConfig from "@careConfig";
const Loading = lazy(() => import("../Common/Loading"));
export default function ListView() {
- const { wartime_shifting } = useConfig();
const {
qParams,
updateQuery,
@@ -127,7 +123,7 @@ export default function ListView() {
- {wartime_shifting && (
+ {careConfig.wartimeShifting && (
import("../Common/Loading"));
export default function ShiftDetails(props: { id: string }) {
- const { header_logo, kasp_full_string, wartime_shifting, kasp_enabled } =
- useConfig();
-
const [isPrintMode, setIsPrintMode] = useState(false);
const [isCopied, setIsCopied] = useState(false);
const [openDeleteShiftDialog, setOpenDeleteShiftDialog] = useState(false);
const { t } = useTranslation();
- const shiftStatusOptions = wartime_shifting
+ const shiftStatusOptions = careConfig.wartimeShifting
? SHIFTING_CHOICES_WARTIME
: SHIFTING_CHOICES_PEACETIME;
@@ -113,7 +110,7 @@ export default function ShiftDetails(props: { id: string }) {
t("reason") +
":" +
data?.reason;
- if (wartime_shifting) {
+ if (careConfig.wartimeShifting) {
formattedText +=
t("facility_preference") + ": " + data?.assigned_facility_type + "\n";
}
@@ -304,7 +301,9 @@ export default function ShiftDetails(props: { id: string }) {
return (
-
{data.is_kasp &&
}
+
+ {data.is_kasp &&
}
+
@@ -571,7 +570,7 @@ export default function ShiftDetails(props: { id: string }) {
{data?.origin_facility_object?.name || "--"}
- {wartime_shifting && (
+ {careConfig.wartimeShifting && (
{t("shifting_approving_facility")}:{" "}
@@ -635,10 +634,10 @@ export default function ShiftDetails(props: { id: string }) {
data?.patient_object.last_consultation?.category}
- {kasp_enabled && (
+ {careConfig.kasp.enabled && (
- {kasp_full_string}:{" "}
+ {careConfig.kasp.fullString}:{" "}
{" "}
@@ -646,11 +645,11 @@ export default function ShiftDetails(props: { id: string }) {
)}
- {wartime_shifting && (
+ {careConfig.wartimeShifting && (
<>
- {kasp_full_string}:{" "}
+ {careConfig.kasp.fullString}:{" "}
{" "}
@@ -813,7 +812,7 @@ export default function ShiftDetails(props: { id: string }) {
{showFacilityCard(data?.assigned_facility_object)}
)}
- {wartime_shifting && (
+ {careConfig.wartimeShifting && (
{t("details_of_shifting_approving_facility")}
diff --git a/src/Components/Shifting/ShiftDetailsUpdate.tsx b/src/Components/Shifting/ShiftDetailsUpdate.tsx
index 37adecaedcd..8e6fb582906 100644
--- a/src/Components/Shifting/ShiftDetailsUpdate.tsx
+++ b/src/Components/Shifting/ShiftDetailsUpdate.tsx
@@ -11,7 +11,6 @@ import {
USER_TYPES,
} from "../../Common/constants";
import { Cancel, Submit } from "../Common/components/ButtonV2";
-
import { navigate, useQueryParams } from "raviger";
import { lazy, useReducer, useState } from "react";
import { ConsultationModel } from "../Facility/models.js";
@@ -26,8 +25,6 @@ import TextAreaFormField from "../Form/FormFields/TextAreaFormField";
import TextFormField from "../Form/FormFields/TextFormField";
import { parsePhoneNumber } from "../../Utils/utils.js";
import useAppHistory from "../../Common/hooks/useAppHistory";
-import useConfig from "../../Common/hooks/useConfig";
-
import { useTranslation } from "react-i18next";
import CircularProgress from "../Common/components/CircularProgress.js";
import Card from "../../CAREUI/display/Card";
@@ -41,6 +38,7 @@ import { IShift } from "./models.js";
import request from "../../Utils/request/request.js";
import { PatientModel } from "../Patient/models.js";
import useAuthUser from "../../Common/hooks/useAuthUser.js";
+import careConfig from "@careConfig";
const Loading = lazy(() => import("../Common/Loading"));
@@ -51,9 +49,6 @@ interface patientShiftProps {
export const ShiftDetailsUpdate = (props: patientShiftProps) => {
const { goBack } = useAppHistory();
const { user_type, home_facility } = useAuthUser();
-
- const { kasp_full_string, kasp_enabled, wartime_shifting } = useConfig();
-
const [qParams, _] = useQueryParams();
const [isLoading, setIsLoading] = useState(true);
@@ -137,7 +132,7 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => {
},
};
- if (wartime_shifting) {
+ if (careConfig.wartimeShifting) {
requiredFields = {
...requiredFields,
shifting_approving_facility_object: {
@@ -336,7 +331,7 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => {
label={t("status")}
required
options={
- wartime_shifting
+ careConfig.wartimeShifting
? SHIFTING_CHOICES_WARTIME
: SHIFTING_CHOICES_PEACETIME
}
@@ -355,7 +350,7 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => {
className="w-full bg-white md:col-span-1 md:leading-5"
/>
- {wartime_shifting &&
+ {careConfig.wartimeShifting &&
(assignedUserLoading ? (
) : (
@@ -369,7 +364,7 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => {
/>
))}
- {wartime_shifting && (
+ {careConfig.wartimeShifting && (
{t("name_of_shifting_approving_facility")}
@@ -429,11 +424,11 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => {
optionValue={(option) => option.value}
/>
- {kasp_enabled && (
+ {careConfig.kasp.enabled && (
{
error={state.errors.patient_category}
/>
- {wartime_shifting && (
+ {careConfig.wartimeShifting && (
<>
{
- const { wartime_shifting } = useConfig();
const [modalFor, setModalFor] = useState({
externalId: undefined,
loading: false,
@@ -110,7 +108,7 @@ const ShiftCard = ({ shift, filter }: any) => {
- {wartime_shifting && (
+ {careConfig.wartimeShifting && (
{
title={headerText}
options={
diff --git a/src/Components/Users/UserFilter.tsx b/src/Components/Users/UserFilter.tsx
index f79968cef4f..ff2a81723cd 100644
--- a/src/Components/Users/UserFilter.tsx
+++ b/src/Components/Users/UserFilter.tsx
@@ -43,7 +43,7 @@ export default function UserFilter(props: any) {
useQuery(routes.getAnyFacility, {
pathParams: { id: filter.home_facility },
- prefetch: !!filter.home_facility,
+ prefetch: !!filter.home_facility && filter.home_facility !== "NONE",
onResponse: ({ data }) => setFilterState({ home_facility_ref: data }),
});
@@ -134,6 +134,7 @@ export default function UserFilter(props: any) {
Home Facility
setFilterState({
@@ -142,7 +143,11 @@ export default function UserFilter(props: any) {
home_facility_ref: selected,
})
}
- selected={filterState.home_facility_ref}
+ selected={
+ filterState.home_facility === "NONE"
+ ? { name: t("no_home_facility"), id: "NONE" }
+ : filterState.home_facility_ref
+ }
errors=""
multiple={false}
/>
diff --git a/src/Integrations/Plausible.tsx b/src/Integrations/Plausible.tsx
index 3f04fc420b2..8001c8139d2 100644
--- a/src/Integrations/Plausible.tsx
+++ b/src/Integrations/Plausible.tsx
@@ -1,11 +1,9 @@
import { useLocationChange } from "raviger";
-import useConfig from "../Common/hooks/useConfig";
import Script from "../Components/Common/Script";
import { useEffect } from "react";
+import careConfig from "@careConfig";
export default function Plausible() {
- const { site_url, analytics_server_url } = useConfig();
-
useLocationChange(() => {
plausible("pageview");
});
@@ -17,11 +15,11 @@ export default function Plausible() {
return (
);
}
diff --git a/src/Integrations/Sentry.tsx b/src/Integrations/Sentry.tsx
index 466f93487c4..90a8e78f3a9 100644
--- a/src/Integrations/Sentry.tsx
+++ b/src/Integrations/Sentry.tsx
@@ -1,25 +1,20 @@
+import careConfig from "@careConfig";
import { useEffect } from "react";
-import useConfig from "../Common/hooks/useConfig";
interface Props {
disabled?: boolean;
}
export default function Sentry({ disabled }: Props) {
- const { sentry_dsn, sentry_environment } = useConfig();
-
useEffect(() => {
- if (disabled || !sentry_dsn) {
+ if (disabled || !careConfig.sentry.dsn) {
return;
}
import("@sentry/browser").then((Sentry) => {
- Sentry.init({
- environment: sentry_environment,
- dsn: sentry_dsn,
- });
+ Sentry.init(careConfig.sentry);
});
- }, [sentry_dsn, sentry_environment, disabled]);
+ }, [disabled]);
return null;
}
diff --git a/src/Locale/en/Asset.json b/src/Locale/en/Asset.json
index f24549ee0b6..182bb25a4fe 100644
--- a/src/Locale/en/Asset.json
+++ b/src/Locale/en/Asset.json
@@ -11,5 +11,10 @@
"update_asset_service_record": "Update Asset Service Record",
"eg_details_on_functionality_service_etc": "Eg. Details on functionality, service, etc.",
"updating": "Updating",
- "update": "Update"
-}
+ "update": "Update",
+ "are_you_still_watching": "Are you still watching?",
+ "stream_stop_due_to_inativity": "The live feed will stop streaming due to inactivity",
+ "stream_stopped_due_to_inativity": "The live feed has stopped streaming due to inactivity",
+ "continue_watching": "Continue watching",
+ "resume": "Resume"
+}
\ No newline at end of file
diff --git a/src/Locale/en/Common.json b/src/Locale/en/Common.json
index 6694bd53a06..24855e05d70 100644
--- a/src/Locale/en/Common.json
+++ b/src/Locale/en/Common.json
@@ -1,5 +1,4 @@
{
- "coronasafe_network": "CoronaSafe Network",
"goal": "Our goal is to continuously improve the quality and accessibility of public healthcare services using digital tools.",
"something_wrong": "Something went wrong! Try again later!",
"try_again_later": "Try again later!",
@@ -31,7 +30,7 @@
"care": "CARE",
"something_went_wrong": "Something went wrong..!",
"stop": "Stop",
- "record": "Record",
+ "record": "Record Audio",
"recording": "Recording",
"yes": "Yes",
"no": "No",
@@ -105,7 +104,7 @@
"filters": "Filters",
"unknown": "Unknown",
"active": "Active",
- "completed": "Archived",
+ "completed": "Completed",
"on": "On",
"open": "Open",
"features": "Features",
@@ -148,7 +147,8 @@
"add_as": "Add as",
"sort_by": "Sort By",
"none": "None",
- "choose_file": "Choose File",
+ "choose_file": "Upload From Device",
+ "open_camera": "Open Camera",
"file_preview": "File Preview",
"file_preview_not_supported": "Can't preview this file. Try downloading it.",
"view_faciliy": "View Facility",
@@ -176,11 +176,29 @@
"ration_card__NO_CARD": "Non-card holder",
"ration_card__BPL": "BPL",
"ration_card__APL": "APL",
+ "empty_date_time": "--:-- --; --/--/----",
"caution": "Caution",
"feed_optimal_experience_for_phones": "For optimal viewing experience, consider rotating your device.",
"feed_optimal_experience_for_apple_phones": "For optimal viewing experience, consider rotating your device. Ensure auto-rotate is enabled in your device settings.",
"action_irreversible": "This action is irreversible",
"GENDER__1": "Male",
"GENDER__2": "Female",
- "GENDER__3": "Non-binary"
+ "GENDER__3": "Non-binary",
+ "normal": "Normal",
+ "done": "Done",
+ "view": "View",
+ "rename": "Rename",
+ "more_info": "More Info",
+ "archive": "Archive",
+ "discard": "Discard",
+ "live": "Live",
+ "discharged": "Discharged",
+ "archived": "Archived",
+ "no_changes_made": "No changes made",
+ "user_deleted_successfuly": "User Deleted Successfuly",
+ "users": "Users",
+ "are_you_sure_want_to_delete": "Are you sure you want to delete {{name}}?",
+ "oxygen_information": "Oxygen Information",
+ "deleted_successfully": "{{name}} deleted successfully",
+ "delete_item": "Delete {{name}}"
}
diff --git a/src/Locale/en/Facility.json b/src/Locale/en/Facility.json
index e321fa02f43..d19c889a98f 100644
--- a/src/Locale/en/Facility.json
+++ b/src/Locale/en/Facility.json
@@ -55,8 +55,65 @@
"discharged_patients": "Discharged Patients",
"discharged_patients_empty": "No discharged patients present in this facility",
"update_facility_middleware_success": "Facility middleware updated successfully",
+ "treatment_summary__head_title": "Treatment Summary",
+ "treatment_summary__print": "Print Treatment Summary",
+ "treatment_summary__heading": "INTERIM TREATMENT SUMMARY",
+ "patient_registration__name": "Name",
+ "patient_registration__address": "Address",
+ "patient_registration__age": "Age",
+ "patient_consultation__op": "OP",
+ "patient_consultation__ip": "IP",
+ "patient_consultation__dc_admission": "Date of domiciliary care commenced",
+ "patient_consultation__admission": "Date of admission",
+ "patient_registration__gender": "Gender",
+ "patient_registration__contact": "Emergency Contact",
+ "patient_registration__comorbidities": "Comorbidities",
+ "patient_registration__comorbidities__disease": "Disease",
+ "patient_registration__comorbidities__details": "Details",
+ "patient_consultation__consultation_notes": "General Instructions",
+ "patient_consultation__special_instruction": "Special Instructions",
+ "suggested_investigations": "Suggested Investigations",
+ "investigations__date": "Date",
+ "investigations__name": "Name",
+ "investigations__result": "Result",
+ "investigations__ideal_value": "Ideal Value",
+ "investigations__range": "Value Range",
+ "investigations__unit": "Unit",
+ "patient_consultation__treatment__plan": "Plan",
+ "patient_consultation__treatment__summary": "Summary",
+ "patient_consultation__treatment__summary__date": "Date",
+ "patient_consultation__treatment__summary__spo2": "SpO2",
+ "patient_consultation__treatment__summary__temperature": "Temperature",
+ "diagnosis": "Diagnosis",
+ "diagnosis__principal": "Principal",
+ "diagnosis__confirmed": "Confirmed",
+ "diagnosis__provisional": "Provisional",
+ "diagnosis__unconfirmed": "Unconfirmed",
+ "diagnosis__differential": "Differential",
+ "active_prescriptions": "Active Prescriptions",
+ "prescriptions__medicine": "Medicine",
+ "prescriptions__route": "Route",
+ "prescriptions__dosage_frequency": "Dosage & Frequency",
+ "prescriptions__start_date": "Prescribed On",
+ "select_facility_for_discharged_patients_warning": "Facility needs to be selected to view discharged patients.",
"duplicate_patient_record_confirmation": "Admit the patient record to your facility by adding the year of birth",
"duplicate_patient_record_rejection": "I confirm that the suspect / patient I want to create is not on the list.",
"duplicate_patient_record_birth_unknown": "Please contact your district care coordinator, the shifting facility or the patient themselves if you are not sure about the patient's year of birth.",
- "patient_transfer_birth_match_note": "Note: Year of birth must match the patient to process the transfer request."
+ "patient_transfer_birth_match_note": "Note: Year of birth must match the patient to process the transfer request.",
+ "cover_image_updated_note": "It could take a while to see the updated cover image",
+ "available_features": "Available Features",
+ "update_facility": "Update Facility",
+ "configure_facility": "Configure Facility",
+ "inventory_management": "Inventory Management",
+ "location_management": "Location Management",
+ "resource_request": "Resource Request",
+ "view_asset": "View Assets",
+ "view_users": "View Users",
+ "view_abdm_records": "View ABDM Records",
+ "delete_facility": "Delete Facility",
+ "central_nursing_station": "Central Nursing Station",
+ "add_details_of_patient": "Add Details of Patient",
+ "choose_location": "Choose Location",
+ "live_monitoring": "Live Monitoring",
+ "open_live_monitoring": "Open Live Monitoring"
}
diff --git a/src/Locale/en/FileUpload.json b/src/Locale/en/FileUpload.json
new file mode 100644
index 00000000000..93b61943944
--- /dev/null
+++ b/src/Locale/en/FileUpload.json
@@ -0,0 +1,29 @@
+{
+ "audio__allow_permission": "Please allow microphone permission in site settings",
+ "audio__allow_permission_helper": "You might have denied microphone access in the past.",
+ "audio__allow_permission_button": "Click here to know how to allow",
+ "audio__record": "Record Audio",
+ "audio__record_helper": "Click the button to start recording",
+ "audio__recording": "Recording",
+ "audio__recording_helper": "Please speak into your microphone.",
+ "audio__recording_helper_2": "Click on the button to stop recording.",
+ "audio__recorded": "Audio Recorded",
+ "audio__start_again": "Start Again",
+ "enter_file_name": "Enter File Name",
+ "no_files_found": "No {{type}} files found",
+ "upload_headings__patient": "Upload New Patient File",
+ "upload_headings__consultation": "Upload New Consultation File",
+ "upload_headings__sample_report": "Upload Sample Report",
+ "upload_headings__supporting_info": "Upload Supporting Info",
+ "file_list_headings__patient": "Patient Files",
+ "file_list_headings__consultation": "Consultation Files",
+ "file_list_headings__sample_report": "Sample Report",
+ "file_list_headings__supporting_info": "Supporting Info",
+ "file_error__choose_file": "Please choose a file to upload",
+ "file_error__file_name": "Please enter file name",
+ "file_error__file_size": "Maximum size of files is 100 MB",
+ "file_error__file_type": "Invalid file type \".{{extension}}\" Allowed types: {{allowedExtensions}}",
+ "file_uploaded": "File Uploaded Successfully",
+ "file_error__dynamic": "Error Uploading File: {{statusText}}",
+ "file_error__network": "Error Uploading File: Network Error"
+}
diff --git a/src/Locale/en/LogUpdate.json b/src/Locale/en/LogUpdate.json
index 319a87bd8d8..080e2fc979a 100644
--- a/src/Locale/en/LogUpdate.json
+++ b/src/Locale/en/LogUpdate.json
@@ -52,5 +52,22 @@
"NURSING_CARE_PROCEDURE__chest_tube_care": "Chest Tube Care",
"NURSING_CARE_PROCEDURE__tracheostomy_care": "Tracheostomy Care",
"NURSING_CARE_PROCEDURE__stoma_care": "Stoma Care",
- "NURSING_CARE_PROCEDURE__catheter_care": "Catheter Care"
+ "NURSING_CARE_PROCEDURE__catheter_care": "Catheter Care",
+ "HEARTBEAT_RHYTHM__REGULAR": "Regular",
+ "HEARTBEAT_RHYTHM__IRREGULAR": "Irregular",
+ "HEARTBEAT_RHYTHM__UNKNOWN": "Unknown",
+ "heartbeat_rhythm": "Heartbeat Rhythm",
+ "heartbeat_description": "Heartbeat Description",
+ "blood_pressure": "Blood Pressure",
+ "map_acronym": "M.A.P.",
+ "systolic": "Systolic",
+ "diastolic": "Diastolic",
+ "temperature": "Temperature",
+ "resipiratory_rate": "Respiratory Rate",
+ "pain": "Pain",
+ "pain_chart_description": "Mark region and intensity of pain",
+ "pulse": "Pulse",
+ "bradycardia": "Bradycardia",
+ "tachycardia": "Tachycardia",
+ "spo2": "SpOโ"
}
\ No newline at end of file
diff --git a/src/Locale/en/Medicine.json b/src/Locale/en/Medicine.json
index 3e861f2e486..df0467de7b6 100644
--- a/src/Locale/en/Medicine.json
+++ b/src/Locale/en/Medicine.json
@@ -61,5 +61,8 @@
"PRESCRIPTION_FREQUENCY_QID": "6th hourly",
"PRESCRIPTION_FREQUENCY_Q4H": "4th hourly",
"PRESCRIPTION_FREQUENCY_QOD": "Alternate day",
- "PRESCRIPTION_FREQUENCY_QWK": "Once a week"
-}
+ "PRESCRIPTION_FREQUENCY_QWK": "Once a week",
+ "inconsistent_dosage_units_error": "Dosage units must be same",
+ "max_dosage_in_24hrs_gte_base_dosage_error": "Max. dosage in 24 hours must be greater than or equal to base dosage",
+ "administration_dosage_range_error": "Dosage should be between start and target dosage"
+}
\ No newline at end of file
diff --git a/src/Locale/en/Users.json b/src/Locale/en/Users.json
index 32c6ee209c3..035ed8933a5 100644
--- a/src/Locale/en/Users.json
+++ b/src/Locale/en/Users.json
@@ -4,10 +4,13 @@
"add_new_user": "Add New User",
"no_users_found": "No Users Found",
"home_facility": "Home Facility",
+ "no_home_facility": "No home facility assigned",
"clear_home_facility": "Clear Home Facility",
"linked_facilities": "Linked Facilities",
"no_linked_facilities": "No Linked Facilities",
"average_weekly_working_hours": "Average weekly working hours",
"set_average_weekly_working_hours_for": "Set Average weekly working hours for",
- "search_by_username": "Search by username"
+ "search_by_username": "Search by username",
+ "last_online": "Last Online",
+ "total_users": "Total Users"
}
diff --git a/src/Locale/en/index.js b/src/Locale/en/index.js
index ff1fa801301..e0fbc212ea4 100644
--- a/src/Locale/en/index.js
+++ b/src/Locale/en/index.js
@@ -17,6 +17,7 @@ import Resource from "./Resource.json";
import Shifting from "./Shifting.json";
import SortOptions from "./SortOptions.json";
import Users from "./Users.json";
+import FileUpload from "./FileUpload.json";
export default {
...Auth,
@@ -37,5 +38,6 @@ export default {
...Bed,
...Users,
...LogUpdate,
+ ...FileUpload,
SortOptions,
};
diff --git a/src/Locale/kn/Common.json b/src/Locale/kn/Common.json
index 7b82b52d9e1..3ba378654e2 100644
--- a/src/Locale/kn/Common.json
+++ b/src/Locale/kn/Common.json
@@ -1,5 +1,4 @@
{
- "coronasafe_network": "เฒเณเฒฐเณเฒจเฒพเฒธเณเฒซเณ เฒจเณเฒเณโเฒตเฒฐเณเฒเณ",
"goal": "เฒกเฒฟเฒเฒฟเฒเฒฒเณ เฒเฒชเฒเฒฐเฒฃเฒเฒณเฒจเณเฒจเณ เฒฌเฒณเฒธเฒฟเฒเณเฒเฒกเณ เฒธเฒพเฒฐเณเฒตเฒเฒจเฒฟเฒ เฒเฒฐเณเฒเณเฒฏ เฒธเณเฒตเณเฒเฒณ เฒเณเฒฃเฒฎเฒเณเฒ เฒฎเฒคเณเฒคเณ เฒชเณเฒฐเฒตเณเฒถเฒตเฒจเณเฒจเณ เฒจเฒฟเฒฐเฒเฒคเฒฐเฒตเฒพเฒเฒฟ เฒธเณเฒงเฒพเฒฐเฒฟเฒธเณเฒตเณเฒฆเณ เฒจเฒฎเณเฒฎ เฒเณเฒฐเฒฟเฒฏเฒพเฒเฒฟเฒฆเณ",
"something_wrong": "เฒเฒจเณเณเณ เฒคเฒชเณเฒชเฒพเฒเฒฟเฒฆเณ! เฒจเฒเฒคเฒฐ เฒฎเฒคเณเฒคเณ เฒชเณเฒฐเฒฏเฒคเณเฒจเฒฟเฒธเฒฟ!",
"contribute_github": "GitHub เฒจเฒฒเณเฒฒเฒฟ เฒเณเฒกเณเฒเณ เฒจเณเฒกเฒฟ",
@@ -15,4 +14,4 @@
"Notice Board": "เฒธเณเฒเฒจเฒพ เฒซเฒฒเฒ",
"Assets": "เฒธเณเฒตเฒคเณเฒคเณเฒเฒณเณ",
"Notifications": "เฒ
เฒงเฒฟเฒธเณเฒเฒจเณเฒเฒณเณ"
-}
+}
\ No newline at end of file
diff --git a/src/Locale/ml/Common.json b/src/Locale/ml/Common.json
index 430305a6a54..3ab266fdb63 100644
--- a/src/Locale/ml/Common.json
+++ b/src/Locale/ml/Common.json
@@ -1,5 +1,4 @@
{
- "coronasafe_network": "เดเตเดฑเตเดฃ เดธเตเดซเต เดจเตเดฑเตเดฑเตเดตเตผเดเตเดเต",
"goal": "เดกเดฟเดเดฟเดฑเตเดฑเตฝ เดเตเดณเตเดเตพ เดเดชเดฏเตเดเดฟเดเตเดเต เดชเตเดคเตเดเดจเดพเดฐเตเดเตเดฏ เดธเตเดตเดจเดเตเดเดณเตเดเต เดเตเดฃเดจเดฟเดฒเดตเดพเดฐเดตเตเด เดชเตเดฐเดตเตเดถเดจเดเตเดทเดฎเดคเดฏเตเด เดคเตเดเตผเดเตเดเดฏเดพเดฏเดฟ เดฎเตเดเตเดเดชเตเดชเตเดเตเดคเตเดคเตเดเดฏเดพเดฃเต เดเดเตเดเดณเตเดเต เดฒเดเตเดทเตเดฏเด.",
"something_wrong": "เดเดจเตเดคเต เดเตเดดเดชเตเดชเด เดธเดเดญเดตเดฟเดเตเดเต! เดเตเดฑเดเตเดเต เดเดดเดฟเดเตเดเต เดตเตเดฃเตเดเตเด เดถเตเดฐเดฎเดฟเดเตเดเตเด!",
"contribute_github": "GitHubเตฝ เดธเดเดญเดพเดตเดจ เดเตเดฏเตเดฏเตเด",
@@ -15,4 +14,4 @@
"Notice Board": "เดจเตเดเตเดเตเดธเต เดฌเตเตผเดกเต",
"Assets": "เดเดธเตเดคเดฟเดเตพ",
"Notifications": "เด
เดฑเดฟเดฏเดฟเดชเตเดชเตเดเตพ"
-}
+}
\ No newline at end of file
diff --git a/src/Locale/mr/Common.json b/src/Locale/mr/Common.json
index d164745bcf3..8e0fd7ae47e 100644
--- a/src/Locale/mr/Common.json
+++ b/src/Locale/mr/Common.json
@@ -1,5 +1,4 @@
{
- "coronasafe_network": "เคเฅเคฐเฅเคจเคพเคธเฅเคซ เคจเฅเคเคตเคฐเฅเค",
"goal": "เคกเคฟเคเคฟเคเคฒ เคธเคพเคงเคจเคพเคเคเคพ เคตเคพเคชเคฐ เคเคฐเฅเคจ เคธเคพเคฐเฅเคตเคเคจเคฟเค เคเคฐเฅเคเฅเคฏ เคธเฅเคตเคพเคเคเฅ เคเฅเคฃเคตเคคเฅเคคเคพ เคเคฃเคฟ เคธเฅเคฒเคญเคคเคพ เคธเคคเคค เคธเฅเคงเคพเคฐเคฃเฅ เคนเฅ เคเคฎเคเฅ เคงเฅเคฏเฅเคฏ เคเคนเฅ.",
"something_wrong": "เคเคพเคนเฅเคคเคฐเฅ เคเฅเค เคเคพเคฒเฅ! เคชเฅเคจเฅเคนเคพ เคชเฅเคฐเคฏเคคเฅเคจ เคเคฐเคพ",
"contribute_github": "Github เคตเคฐ เคฏเฅเคเคฆเคพเคจ เคฆเฅเคฏเคพ",
@@ -15,4 +14,4 @@
"Notice Board": "เคธเฅเคเคจเคพ เคซเคฒเค",
"Assets": "เคฎเคพเคฒเคฎเคคเฅเคคเคพ",
"Notifications": "เค
เคงเคฟเคธเฅเคเคจเคพ"
-}
+}
\ No newline at end of file
diff --git a/src/Locale/ta/Common.json b/src/Locale/ta/Common.json
index 4b08291783e..2ee39016c2e 100644
--- a/src/Locale/ta/Common.json
+++ b/src/Locale/ta/Common.json
@@ -1,5 +1,4 @@
{
- "coronasafe_network": "เฎเฏเฎฐเฏเฎฉเฎพ เฎเฏเฎเฎชเฏ เฎจเฏเฎเฏเฎตเฏเฎฐเฏเฎเฏ",
"goal": "เฎเฎฟเฎเฎฟเฎเฏเฎเฎฒเฏ เฎเฎฐเฏเฎตเฎฟเฎเฎณเฏเฎชเฏ เฎชเฎฏเฎฉเฏเฎชเฎเฏเฎคเฏเฎคเฎฟ เฎชเฏเฎคเฏ เฎเฏเฎเฎพเฎคเฎพเฎฐ เฎเฏเฎตเฏเฎเฎณเฎฟเฎฉเฏ เฎคเฎฐเฎฎเฏ เฎฎเฎฑเฏเฎฑเฏเฎฎเฏ เฎ
เฎฃเฏเฎเฎฒเฏเฎคเฎฉเฏเฎฎเฏเฎฏเฏ เฎคเฏเฎเฎฐเฏเฎจเฏเฎคเฏ เฎฎเฏเฎฎเฏเฎชเฎเฏเฎคเฏเฎคเฏเฎตเฎคเฏ เฎเฎเฏเฎเฎณเฏ เฎเฏเฎฑเฎฟเฎเฏเฎเฏเฎณเฏ.",
"something_wrong": "เฎเฎคเฏเฎพ เฎคเฎตเฎฑเฏ เฎจเฎเฎจเฏเฎคเฏเฎตเฎฟเฎเฏเฎเฎคเฏ! เฎชเฎฟเฎฉเฏเฎฉเฎฐเฏ เฎฎเฏเฎฃเฏเฎเฏเฎฎเฏ เฎฎเฏเฎฏเฎฑเฏเฎเฎฟเฎเฏเฎเฎตเฏเฎฎเฏ!",
"contribute_github": "Github-เฎฒเฏ เฎชเฎเฏเฎเฎณเฎฟเฎชเฏเฎชเฏ เฎเฏเฎฏเฏเฎฏเฏเฎเฏเฎเฎณเฏ",
@@ -15,4 +14,4 @@
"Notice Board": "เฎ
เฎฑเฎฟเฎตเฎฟเฎชเฏเฎชเฏ เฎชเฎฒเฎเฏ",
"Assets": "เฎเฏเฎคเฏเฎคเฏเฎเฏเฎเฎณเฏ",
"Notifications": "เฎ
เฎฑเฎฟเฎตเฎฟเฎชเฏเฎชเฏเฎเฎณเฏ"
-}
+}
\ No newline at end of file
diff --git a/src/Providers/AppConfigProvider.tsx b/src/Providers/AppConfigProvider.tsx
deleted file mode 100644
index 7492a83c126..00000000000
--- a/src/Providers/AppConfigProvider.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { AppConfigContext } from "../Common/hooks/useConfig";
-import Loading from "../Components/Common/Loading";
-import routes from "../Redux/api";
-import useQuery from "../Utils/request/useQuery";
-
-interface Props {
- children: React.ReactNode;
-}
-
-export default function AppConfigProvider({ children }: Props) {
- const { data, loading } = useQuery(routes.config, {
- refetchOnWindowFocus: false,
- prefetch: true,
- });
-
- if (loading || data === undefined) {
- return ;
- }
-
- return (
-
- {children}
-
- );
-}
diff --git a/src/Providers/AuthUserProvider.tsx b/src/Providers/AuthUserProvider.tsx
index c3e15b670cc..df2997abe2e 100644
--- a/src/Providers/AuthUserProvider.tsx
+++ b/src/Providers/AuthUserProvider.tsx
@@ -5,8 +5,8 @@ import routes from "../Redux/api";
import useQuery from "../Utils/request/useQuery";
import { LocalStorageKeys } from "../Common/constants";
import request from "../Utils/request/request";
-import useConfig from "../Common/hooks/useConfig";
import { navigate } from "raviger";
+import careConfig from "@careConfig";
interface Props {
children: React.ReactNode;
@@ -14,9 +14,6 @@ interface Props {
}
export default function AuthUserProvider({ children, unauthorized }: Props) {
- const { jwt_token_refresh_interval } = useConfig();
- const tokenRefreshInterval = jwt_token_refresh_interval ?? 5 * 60 * 1000;
-
const {
res,
data: user,
@@ -30,8 +27,11 @@ export default function AuthUserProvider({ children, unauthorized }: Props) {
}
updateRefreshToken(true);
- setInterval(() => updateRefreshToken(), tokenRefreshInterval);
- }, [user, tokenRefreshInterval]);
+ setInterval(
+ () => updateRefreshToken(),
+ careConfig.auth.tokenRefreshInterval,
+ );
+ }, [user]);
const signIn = useCallback(
async (creds: { username: string; password: string }) => {
diff --git a/src/Providers/index.tsx b/src/Providers/index.tsx
deleted file mode 100644
index 728ee9e1f91..00000000000
--- a/src/Providers/index.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import AppConfigProvider from "./AppConfigProvider";
-import AuthUserProvider from "./AuthUserProvider";
-import HistoryAPIProvider from "./HistoryAPIProvider";
-
-export { AppConfigProvider, AuthUserProvider, HistoryAPIProvider };
diff --git a/src/Redux/Reducer.tsx b/src/Redux/Reducer.tsx
index 2c5335e6d7c..c7d4698b694 100644
--- a/src/Redux/Reducer.tsx
+++ b/src/Redux/Reducer.tsx
@@ -1,26 +1,6 @@
-import { IConfig } from "../Common/hooks/useConfig";
import { actions } from "./fireRequest";
-export const getCachedConfig = () => {
- const localConfig = localStorage.getItem("config");
- if (localConfig) {
- try {
- const config = JSON.parse(localConfig) as IConfig;
- return config;
- } catch (_) {
- return undefined;
- }
- }
-};
-
-const cachedConfig = getCachedConfig();
-
-const reducer = (
- state = {
- config: cachedConfig,
- },
- changeAction: any,
-) => {
+const reducer = (state = {}, changeAction: any) => {
switch (changeAction.type) {
case actions.FETCH_REQUEST: {
const obj: any = Object.assign({}, state);
diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx
index b03faf07e5a..e72f7766bbe 100644
--- a/src/Redux/api.tsx
+++ b/src/Redux/api.tsx
@@ -1,4 +1,3 @@
-import { IConfig } from "../Common/hooks/useConfig";
import {
ConsentRequestModel,
CreateConsentTBody,
@@ -132,13 +131,6 @@ export interface LoginCredentials {
}
const routes = {
- config: {
- path: import.meta.env.REACT_APP_CONFIG ?? "/config.json",
- method: "GET",
- noAuth: true,
- TRes: Type(),
- },
-
createScribe: {
path: "/api/care_scribe/scribe/",
method: "POST",
diff --git a/src/Redux/fireRequest.tsx b/src/Redux/fireRequest.tsx
index 99cd2fe7ca4..fe72b2af0d2 100644
--- a/src/Redux/fireRequest.tsx
+++ b/src/Redux/fireRequest.tsx
@@ -1,10 +1,9 @@
import * as Notification from "../Utils/Notifications.js";
-import { isEmpty, omitBy } from "lodash-es";
-
import { LocalStorageKeys } from "../Common/constants";
import api from "./api";
import axios from "axios";
+import careConfig from "@careConfig";
const requestMap: any = api;
export const actions = {
@@ -92,6 +91,7 @@ export const fireRequest = (
// set authorization header in the request header
const config: any = {
headers: {},
+ baseURL: careConfig.apiUrl,
};
if (!request.noAuth) {
const access_token = localStorage.getItem(LocalStorageKeys.accessToken);
@@ -173,104 +173,3 @@ export const fireRequest = (
});
};
};
-
-export const fireRequestV2 = (
- key: string,
- path: any = [],
- params: any = {},
- successCallback: any = () => undefined,
- errorCallback: any = () => undefined,
- pathParam?: any,
- altKey?: string,
-) => {
- // cancel previous api call
- if (isRunning[altKey ? altKey : key]) {
- isRunning[altKey ? altKey : key].cancel();
- }
- isRunning[altKey ? altKey : key] = axios.CancelToken.source();
- // get api url / method
- const request = Object.assign({}, requestMap[key]);
- if (path.length > 0) {
- request.path += "/" + path.join("/");
- }
- if (request.method === undefined || request.method === "GET") {
- request.method = "GET";
- const qs = new URLSearchParams(omitBy(params, isEmpty)).toString();
- if (qs !== "") {
- request.path += `?${qs}`;
- }
- }
- // set dynamic params in the URL
- if (pathParam) {
- Object.keys(pathParam).forEach((param: any) => {
- request.path = request.path.replace(`{${param}}`, pathParam[param]);
- });
- }
-
- // set authorization header in the request header
- const config: any = {
- headers: {},
- };
- if (!request.noAuth && localStorage.getItem(LocalStorageKeys.accessToken)) {
- config.headers["Authorization"] =
- "Bearer " + localStorage.getItem(LocalStorageKeys.accessToken);
- }
- const axiosApiCall: any = axios.create(config);
-
- fetchDataRequest(key);
- return axiosApiCall[request.method.toLowerCase()](request.path, {
- ...params,
- cancelToken: isRunning[altKey ? altKey : key].token,
- })
- .then((response: any) => {
- successCallback(response.data);
- })
- .catch((error: any) => {
- errorCallback(error);
- if (error.response) {
- // temporarily don't show invalid phone number error on duplicate patient check
- if (error.response.status === 400 && key === "searchPatient") {
- return;
- }
-
- // deleteUser: 404 is for permission denied
- if (error.response.status === 404 && key === "deleteUser") {
- Notification.Error({
- msg: "Permission denied!",
- });
- }
-
- // currentUser is ignored because on the first page load
- // 403 error is displayed for invalid credential.
- if (error.response.status === 403 && key === "currentUser") {
- if (localStorage.getItem(LocalStorageKeys.accessToken)) {
- localStorage.removeItem(LocalStorageKeys.accessToken);
- }
- }
-
- // 400 Bad Request Error
- if (error.response.status === 400 || error.response.status === 406) {
- Notification.BadRequest({
- errs: error.response.data,
- });
- }
-
- // 4xx Errors
- if (error.response.status > 400 && error.response.status < 600) {
- if (error.response.data && error.response.data.detail) {
- Notification.Error({
- msg: error.response.data.detail,
- });
- } else {
- Notification.Error({
- msg: "Something went wrong...!",
- });
- }
- if (error.response.status === 429) {
- return error.response;
- }
- return;
- }
- }
- });
-};
diff --git a/src/Routers/AppRouter.tsx b/src/Routers/AppRouter.tsx
index bba3bd04899..60e0f9411d5 100644
--- a/src/Routers/AppRouter.tsx
+++ b/src/Routers/AppRouter.tsx
@@ -11,7 +11,6 @@ import {
SidebarShrinkContext,
} from "../Components/Common/Sidebar/Sidebar";
import { BLACKLISTED_PATHS } from "../Common/constants";
-import useConfig from "../Common/hooks/useConfig";
import SessionExpired from "../Components/ErrorPages/SessionExpired";
import HealthInformation from "../Components/ABDM/HealthInformation";
import ABDMFacilityRecords from "../Components/ABDM/ABDMFacilityRecords";
@@ -28,6 +27,7 @@ import ResourceRoutes from "./routes/ResourceRoutes";
import ExternalResultRoutes from "./routes/ExternalResultRoutes";
import { DetailRoute } from "./types";
import useAuthUser from "../Common/hooks/useAuthUser";
+import careConfig from "@careConfig";
const Routes = {
"/": () => ,
@@ -59,11 +59,10 @@ const Routes = {
export default function AppRouter() {
const authUser = useAuthUser();
- const { main_logo, enable_hcx } = useConfig();
let routes = Routes;
- if (enable_hcx) {
+ if (careConfig.hcx.enabled) {
routes = { ...routes, ...HCXRoutes };
}
@@ -144,7 +143,7 @@ export default function AppRouter() {
>
diff --git a/src/Routers/routes/ConsultationRoutes.tsx b/src/Routers/routes/ConsultationRoutes.tsx
index 65baf77ddc2..598fd06adc3 100644
--- a/src/Routers/routes/ConsultationRoutes.tsx
+++ b/src/Routers/routes/ConsultationRoutes.tsx
@@ -4,14 +4,16 @@ import ShowInvestigation from "../../Components/Facility/Investigations/ShowInve
import ManagePrescriptions from "../../Components/Medicine/ManagePrescriptions";
import { DailyRoundListDetails } from "../../Components/Patient/DailyRoundListDetails";
import { DailyRounds } from "../../Components/Patient/DailyRounds";
-import { FileUpload } from "../../Components/Patient/FileUpload";
import { ConsultationDetails } from "../../Components/Facility/ConsultationDetails";
-import TreatmentSummary from "../../Components/Facility/TreatmentSummary";
+import TreatmentSummary, {
+ ITreatmentSummaryProps,
+} 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";
export default {
"/facility/:facilityId/patient/:patientId/consultation": ({
@@ -38,14 +40,11 @@ export default {
patientId,
id,
}: any) => (
-
),
"/facility/:facilityId/patient/:patientId/consultation/:consultationId/prescriptions":
@@ -132,12 +131,11 @@ export default {
),
"/facility/:facilityId/patient/:patientId/consultation/:consultationId/treatment-summary":
- ({ facilityId, patientId, consultationId }: any) => (
+ ({ facilityId, patientId, consultationId }: ITreatmentSummaryProps) => (
),
"/facility/:facilityId/patient/:patientId/consultation/:consultationId/notes":
diff --git a/src/Routers/routes/PatientRoutes.tsx b/src/Routers/routes/PatientRoutes.tsx
index ce2798c4492..fcfc9b04e37 100644
--- a/src/Routers/routes/PatientRoutes.tsx
+++ b/src/Routers/routes/PatientRoutes.tsx
@@ -1,5 +1,4 @@
import InvestigationReports from "../../Components/Facility/Investigations/Reports";
-import { FileUpload } from "../../Components/Patient/FileUpload";
import { PatientManager } from "../../Components/Patient/ManagePatients";
import { PatientHome } from "../../Components/Patient/PatientHome";
import PatientNotes from "../../Components/Patient/PatientNotes";
@@ -7,6 +6,7 @@ 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";
export default {
"/patients": () => ,
@@ -36,14 +36,10 @@ export default {
facilityId,
patientId,
}: any) => (
-
),
"/death_report/:id": ({ id }: any) => ,
diff --git a/src/Utils/VoiceRecorder.tsx b/src/Utils/VoiceRecorder.tsx
deleted file mode 100644
index 6336df5cb01..00000000000
--- a/src/Utils/VoiceRecorder.tsx
+++ /dev/null
@@ -1,102 +0,0 @@
-import useRecorder from "./useRecorder";
-import { useEffect, useState } from "react";
-import ButtonV2 from "../Components/Common/components/ButtonV2";
-import CareIcon from "../CAREUI/icons/CareIcon";
-import { NonReadOnlyUsers } from "./AuthorizeFor";
-import { useTranslation } from "react-i18next";
-
-export const VoiceRecorder = (props: any) => {
- const { t } = useTranslation();
- const {
- isDisabled,
- createAudioBlob,
- confirmAudioBlobExists,
- reset,
- setResetRecording,
- handleSetMicPermission,
- } = props;
- const [
- audioURL,
- isRecording,
- startRecording,
- stopRecording,
- newBlob,
- resetRecording,
- ] = useRecorder(handleSetMicPermission);
- const [time, setTime] = useState(0);
- createAudioBlob(newBlob);
- useEffect(() => {
- let interval: any;
- if (isRecording) {
- interval = setInterval(() => {
- setTime((prevTime) => prevTime + 10);
- }, 10);
- } else {
- clearInterval(interval);
- setTime(0);
- }
- if (reset) {
- resetRecording();
- setResetRecording(false);
- }
- return () => clearInterval(interval);
- }, [isRecording, reset, setResetRecording, resetRecording]);
-
- return (
-
-
- {isRecording ? (
- <>
-
-
-
- {t("recording") + "..."}
-
-
{
- stopRecording();
- confirmAudioBlobExists();
- }}
- >
-
- {t("stop")}
-
-
-
- {("0" + Math.floor((time / 60000) % 60)).slice(-2)}:
- {("0" + Math.floor((time / 1000) % 60)).slice(-2)}
-
- >
- ) : (
-
- {!audioURL && (
-
-
- {t("record")}
-
- )}
-
- )}
-
- {audioURL && (
-
- )}
-
- );
-};
diff --git a/src/Utils/request/handleResponse.ts b/src/Utils/request/handleResponse.ts
index 9f85b50a68d..905417ad0e2 100644
--- a/src/Utils/request/handleResponse.ts
+++ b/src/Utils/request/handleResponse.ts
@@ -20,14 +20,15 @@ export default function handleResponse(
// Other Errors between 400-599 (inclusive)
if (res.status >= 400 && res.status < 600) {
- // Invalid token
- if (!silent && error?.code === "token_not_valid") {
- navigate(`/session-expired?redirect=${window.location.href}`);
- }
-
- // Handle session expiry
- if (error?.detail === "Authentication credentials were not provided.") {
- notify?.Error({ msg: "Session expired. Please Login again." });
+ // Handle invalid token / session expiry
+ if (
+ !silent &&
+ (error?.code === "token_not_valid" ||
+ error?.detail === "Authentication credentials were not provided.")
+ ) {
+ if (!location.pathname.startsWith("/session-expired")) {
+ navigate(`/session-expired?redirect=${window.location.href}`);
+ }
return;
}
diff --git a/src/Utils/request/request.ts b/src/Utils/request/request.ts
index 9dd803148bb..151cc30c460 100644
--- a/src/Utils/request/request.ts
+++ b/src/Utils/request/request.ts
@@ -1,3 +1,4 @@
+import careConfig from "@careConfig";
import handleResponse from "./handleResponse";
import { RequestOptions, RequestResult, Route } from "./types";
import { makeHeaders, makeUrl } from "./utils";
@@ -34,7 +35,7 @@ export default async function request(
}
const signal = controller?.signal ?? controllerRef?.current?.signal;
- const url = makeUrl(path, query, pathParams);
+ const url = `${careConfig.apiUrl}${makeUrl(path, query, pathParams)}`;
const options: RequestInit = { method, signal };
diff --git a/src/Utils/useFileManager.tsx b/src/Utils/useFileManager.tsx
index 84079c2ba72..93ddd3ad479 100644
--- a/src/Utils/useFileManager.tsx
+++ b/src/Utils/useFileManager.tsx
@@ -1,7 +1,7 @@
import { useState } from "react";
import FilePreviewDialog from "../Components/Common/FilePreviewDialog";
import { FileUploadModel } from "../Components/Patient/models";
-import { ExtImage, StateInterface } from "../Components/Patient/FileUpload";
+import { StateInterface } from "../Components/Files/FileUpload";
import request from "./request/request";
import routes from "../Redux/api";
import DialogModal from "../Components/Common/Dialog";
@@ -11,13 +11,16 @@ import { Cancel, Submit } from "../Components/Common/components/ButtonV2";
import { formatDateTime } from "./utils";
import * as Notification from "./Notifications.js";
import TextFormField from "../Components/Form/FormFields/TextFormField";
+import {
+ FILE_EXTENSIONS,
+ PREVIEWABLE_FILE_EXTENSIONS,
+} from "../Common/constants";
export interface FileManagerOptions {
type: string;
onArchive?: () => void;
onEdit?: () => void;
}
-
export interface FileManagerResult {
viewFile: (file: FileUploadModel, associating_id: string) => void;
archiveFile: (
@@ -25,8 +28,17 @@ export interface FileManagerResult {
associating_id: string,
skipPrompt?: { reason: string },
) => void;
- editFile: (file: FileUploadModel) => void;
+ editFile: (file: FileUploadModel, associating_id: string) => void;
Dialogues: React.ReactNode;
+ isPreviewable: (file: FileUploadModel) => boolean;
+ getFileType: (
+ file: FileUploadModel,
+ ) => keyof typeof FILE_EXTENSIONS | "UNKNOWN";
+ downloadFile: (
+ file: FileUploadModel,
+ associating_id: string,
+ ) => Promise;
+ type: string;
}
export default function useFileManager(
@@ -92,7 +104,9 @@ export default function useFileManager(
open: true,
name: data.name as string,
extension,
- isImage: ExtImage.includes(extension),
+ isImage: FILE_EXTENSIONS.IMAGE.includes(
+ extension as (typeof FILE_EXTENSIONS.IMAGE)[number],
+ ),
});
downloadFileUrl(signedUrl);
setFileUrl(signedUrl);
@@ -195,8 +209,8 @@ export default function useFileManager(
setEditing(false);
};
- const editFile = (file: FileUploadModel) => {
- setEditDialogueOpen(file);
+ const editFile = (file: FileUploadModel, associating_id: string) => {
+ setEditDialogueOpen({ ...file, associating_id });
};
const Dialogues = (
@@ -245,6 +259,7 @@ export default function useFileManager(
State the reason for archiving{" "}
@@ -327,7 +342,12 @@ export default function useFileManager(
{item.label}
- {item.content}
+
+ {item.content}
+
))}
@@ -364,6 +384,7 @@ export default function useFileManager(
{
@@ -388,10 +409,63 @@ export default function useFileManager(
>
);
+ const isPreviewable = (file: FileUploadModel) =>
+ !!file.extension &&
+ PREVIEWABLE_FILE_EXTENSIONS.includes(
+ file.extension.slice(1) as (typeof PREVIEWABLE_FILE_EXTENSIONS)[number],
+ );
+
+ const getFileType: (
+ f: FileUploadModel,
+ ) => keyof typeof FILE_EXTENSIONS | "UNKNOWN" = (file: FileUploadModel) => {
+ if (!file.extension) return "UNKNOWN";
+ const ftype = (
+ Object.keys(FILE_EXTENSIONS) as (keyof typeof FILE_EXTENSIONS)[]
+ ).find((type) =>
+ FILE_EXTENSIONS[type].includes((file.extension?.slice(1) || "") as never),
+ );
+ return ftype || "UNKNOWN";
+ };
+
+ const downloadFile = async (
+ file: FileUploadModel,
+ associating_id: string,
+ ) => {
+ try {
+ if (!file.id) return;
+ Notification.Success({ msg: "Downloading file..." });
+ const { data: fileData } = await request(routes.retrieveUpload, {
+ query: { file_type: fileType, associating_id },
+ pathParams: { id: file.id },
+ });
+ const response = await fetch(fileData?.read_signed_url || "");
+ if (!response.ok) throw new Error("Network response was not ok.");
+
+ const data = await response.blob();
+ const blobUrl = window.URL.createObjectURL(data);
+
+ const a = document.createElement("a");
+ a.href = blobUrl;
+ a.download = file.name || "file";
+ document.body.appendChild(a);
+ a.click();
+
+ // Clean up
+ window.URL.revokeObjectURL(blobUrl);
+ document.body.removeChild(a);
+ } catch (err) {
+ Notification.Error({ msg: "Failed to download file" });
+ }
+ };
+
return {
viewFile,
archiveFile,
editFile,
Dialogues,
+ isPreviewable,
+ getFileType,
+ downloadFile,
+ type: fileType,
};
}
diff --git a/src/Utils/useFileUpload.tsx b/src/Utils/useFileUpload.tsx
index 863834dc424..fdd69c45765 100644
--- a/src/Utils/useFileUpload.tsx
+++ b/src/Utils/useFileUpload.tsx
@@ -1,22 +1,23 @@
-import { ChangeEvent, useCallback, useRef, useState } from "react";
+import {
+ ChangeEvent,
+ DetailedHTMLProps,
+ InputHTMLAttributes,
+ useState,
+} from "react";
import {
CreateFileResponse,
FileCategory,
FileUploadModel,
} from "../Components/Patient/models";
-import DialogModal from "../Components/Common/Dialog";
-import CareIcon, { IconName } from "../CAREUI/icons/CareIcon";
-import Webcam from "react-webcam";
-import ButtonV2, { Submit } from "../Components/Common/components/ButtonV2";
-import { t } from "i18next";
-import useWindowDimensions from "../Common/hooks/useWindowDimensions";
-import { classNames } from "./utils";
import request from "./request/request";
import routes from "../Redux/api";
import uploadFile from "./request/uploadFile";
import * as Notification from "./Notifications.js";
import imageCompression from "browser-image-compression";
import { DEFAULT_ALLOWED_EXTENSIONS } from "../Common/constants";
+import CameraCaptureDialog from "../Components/Files/CameraCaptureDialog";
+import AudioCaptureDialog from "../Components/Files/AudioCaptureDialog";
+import { t } from "i18next";
export type FileUploadOptions = {
type: string;
@@ -31,11 +32,11 @@ export type FileUploadOptions = {
}
);
-export type FileUploadButtonProps = {
- icon?: IconName;
- content?: string;
- className?: string;
-};
+export interface FileInputProps
+ extends Omit<
+ DetailedHTMLProps, HTMLInputElement>,
+ "id" | "title" | "type" | "accept" | "onChange"
+ > {}
export type FileUploadReturn = {
progress: null | number;
@@ -44,19 +45,13 @@ export type FileUploadReturn = {
handleAudioCapture: () => void;
handleFileUpload: (associating_id: string) => Promise;
Dialogues: JSX.Element;
- UploadButton: (_: FileUploadButtonProps) => JSX.Element;
+ Input: (_: FileInputProps) => JSX.Element;
fileName: string;
file: File | null;
setFileName: (name: string) => void;
clearFile: () => void;
};
-const videoConstraints = {
- width: { ideal: 4096 },
- height: { ideal: 2160 },
- facingMode: "user",
-};
-
// Array of image extensions
const ExtImage: string[] = [
"jpeg",
@@ -78,31 +73,9 @@ export default function useFileUpload(
const [error, setError] = useState(null);
const [progress, setProgress] = useState(null);
const [cameraModalOpen, setCameraModalOpen] = useState(false);
- const [cameraFacingFront, setCameraFacingFront] = useState(true);
- const webRef = useRef(null);
- const [previewImage, setPreviewImage] = useState(null);
- const [file, setFile] = useState(null);
-
- const handleSwitchCamera = useCallback(() => {
- setCameraFacingFront((prevState) => !prevState);
- }, []);
-
- const { width } = useWindowDimensions();
- const LaptopScreenBreakpoint = 640;
- const isLaptopScreen = width >= LaptopScreenBreakpoint ? true : false;
+ const [audioModalOpen, setAudioModalOpen] = useState(false);
- const captureImage = () => {
- setPreviewImage(webRef.current.getScreenshot());
- const canvas = webRef.current.getCanvas();
- canvas?.toBlob((blob: Blob) => {
- const extension = blob.type.split("/").pop();
- const myFile = new File([blob], `capture.${extension}`, {
- type: blob.type,
- });
- setUploadFileName(uploadFileName || "");
- setFile(myFile);
- });
- };
+ const [file, setFile] = useState(null);
const onFileChange = (e: ChangeEvent): any => {
if (!e.target.files?.length) {
@@ -111,11 +84,13 @@ export default function useFileUpload(
const f = e.target.files[0];
const fileName = f.name;
setFile(e.target.files[0]);
- setUploadFileName(
- uploadFileName ||
- fileName.substring(0, fileName.lastIndexOf(".")) ||
- fileName,
- );
+
+ // This is commented out to prompt users to input valid file names. See https://github.com/ohcnetwork/care_fe/issues/7942#issuecomment-2324391329
+ //setUploadFileName(
+ // uploadFileName ||
+ // fileName.substring(0, fileName.lastIndexOf(".")) ||
+ // fileName,
+ //);
const ext: string = fileName.split(".")[1];
@@ -136,15 +111,15 @@ export default function useFileUpload(
const filenameLength = uploadFileName.trim().length;
const f = file;
if (f === undefined || f === null) {
- setError("Please choose a file to upload");
+ setError(t("file_error__choose_file"));
return false;
}
if (filenameLength === 0) {
- setError("Please give a name !!");
+ setError(t("file_error__file_name"));
return false;
}
if (f.size > 10e7) {
- setError("Maximum size of files is 100 MB");
+ setError(t("file_error__file_size"));
return false;
}
const extension = f.name.split(".").pop();
@@ -153,7 +128,10 @@ export default function useFileUpload(
!options.allowedExtensions?.includes(extension || "")
) {
setError(
- `Invalid file type ".${extension}" Allowed types: ${options.allowedExtensions?.join(", ")}`,
+ t("file_error__file_type", {
+ extension,
+ allowedExtensions: options.allowedExtensions?.join(", "),
+ }),
);
return false;
}
@@ -179,7 +157,6 @@ export default function useFileUpload(
const f = file;
if (!f) return;
const newFile = new File([f], `${internal_name}`);
- console.log("filetype: ", newFile.type);
return new Promise((resolve, reject) => {
uploadFile(
url,
@@ -192,14 +169,14 @@ export default function useFileUpload(
setFile(null);
setUploadFileName("");
Notification.Success({
- msg: "File Uploaded Successfully",
+ msg: t("file_uploaded"),
});
setError(null);
onUpload && onUpload(data);
resolve();
} else {
Notification.Error({
- msg: "Error Uploading File: " + xhr.statusText,
+ msg: t("file_error__dynamic", { statusText: xhr.statusText }),
});
setProgress(null);
reject();
@@ -208,7 +185,7 @@ export default function useFileUpload(
setProgress as any,
() => {
Notification.Error({
- msg: "Error Uploading File: Network Error",
+ msg: t("file_error__network"),
});
setProgress(null);
reject();
@@ -242,217 +219,60 @@ export default function useFileUpload(
}
};
- const cameraFacingMode = cameraFacingFront
- ? "user"
- : { exact: "environment" };
-
const Dialogues = (
-
-
-
-
-
-
Camera
-
-
- }
- className="max-w-2xl"
- onClose={() => setCameraModalOpen(false)}
- >
-
- {!previewImage ? (
-
-
-
- ) : (
-
-
-
- )}
-
-
- {/* buttons for mobile screens */}
-
-
- {!previewImage ? (
-
- {t("switch")}
-
- ) : (
- <>>
- )}
-
-
- {!previewImage ? (
- <>
-
- {
- captureImage();
- }}
- className="m-2"
- >
- {t("capture")}
-
-
- >
- ) : (
- <>
-
- {
- setPreviewImage(null);
- }}
- className="m-2"
- >
- {t("retake")}
-
- {
- setPreviewImage(null);
- setCameraModalOpen(false);
- }}
- className="m-2"
- >
- {t("submit")}
-
-
- >
- )}
-
-
- {
- setPreviewImage(null);
- setCameraModalOpen(false);
- }}
- className="m-2"
- >
- {t("close")}
-
-
-
- {/* buttons for laptop screens */}
-
-
-
-
- {`${t("switch")} ${t("camera")}`}
-
-
-
-
-
- {!previewImage ? (
- <>
-
- {
- captureImage();
- }}
- >
-
- {t("capture")}
-
-
- >
- ) : (
- <>
-
- {
- setPreviewImage(null);
- }}
- >
- {t("retake")}
-
- {
- setCameraModalOpen(false);
- setPreviewImage(null);
- }}
- >
- {t("submit")}
-
-
- >
- )}
-
-
-
{
- setPreviewImage(null);
- setCameraModalOpen(false);
- }}
- >
- {`${t("close")} ${t("camera")}`}
-
-
-
-
+ <>
+ setCameraModalOpen(false)}
+ onCapture={(f) => {
+ setFile(f);
+ setUploadFileName(uploadFileName || "");
+ }}
+ />
+ setAudioModalOpen(false)}
+ onCapture={(f) => {
+ setFile(f);
+ setUploadFileName(uploadFileName || "");
+ }}
+ autoRecord
+ />
+ >
);
- const UploadButton = (props: FileUploadButtonProps) => (
-
-
- {props.content || t("choose_file")}
-
-
+ const Input = (props: FileInputProps) => (
+ "." + e).join(",")
+ : "allowAllExtensions" in options
+ ? "*"
+ : DEFAULT_ALLOWED_EXTENSIONS.join(",")
+ }
+ hidden={props.hidden || true}
+ />
);
return {
progress,
error,
- handleCameraCapture: () => {
- setCameraModalOpen(true);
- },
- handleAudioCapture: () => {
- console.log("Audio capture not implemented");
- },
+ handleCameraCapture: () => setCameraModalOpen(true),
+ handleAudioCapture: () => setAudioModalOpen(true),
handleFileUpload: handleUpload,
Dialogues,
- UploadButton,
+ Input,
fileName: uploadFileName,
file: file,
setFileName: setUploadFileName,
clearFile: () => {
setFile(null);
+ setError(null);
setUploadFileName("");
},
};
diff --git a/src/Utils/useRecorder.js b/src/Utils/useRecorder.js
index 585e557d787..446f824259f 100644
--- a/src/Utils/useRecorder.js
+++ b/src/Utils/useRecorder.js
@@ -1,3 +1,5 @@
+// why is this file in js? can we convert to ts?
+
import { useEffect, useState } from "react";
import { Error } from "./Notifications";
diff --git a/src/Utils/useTimer.tsx b/src/Utils/useTimer.tsx
new file mode 100644
index 00000000000..6a8d8320c5e
--- /dev/null
+++ b/src/Utils/useTimer.tsx
@@ -0,0 +1,53 @@
+import { useEffect, useState } from "react";
+
+/**
+ * Custom hook to manage a timer in MM:SS format. This can be useful for tracking time during recording sessions, user actions, or any other timed event.
+ *
+ * @returns {Object} A set of properties and methods to control and display the timer:
+ *
+ * @property {number} seconds - The total elapsed time in seconds.
+ * @property {JSX.Element} time - A JSX element displaying the current time in MM:SS format.
+ * @property {function} start - Function to start the timer.
+ * @property {function} stop - Function to stop the timer.
+ *
+ * @example
+ * const { time, start, stop } = useTimer();
+ *
+ * // To start the timer:
+ * start();
+ *
+ * // To stop the timer:
+ * stop();
+ *
+ * // To display the timer in your component:
+ * {time}
+ */
+export const useTimer = (autoStart = false) => {
+ const [running, setRunning] = useState(autoStart);
+ const [time, setTime] = useState(0);
+
+ useEffect(() => {
+ let interval: number;
+ if (running) {
+ interval = setInterval(() => {
+ setTime((prevTime) => prevTime + 1);
+ }, 10);
+ } else {
+ setTime(0);
+ }
+ return () => clearInterval(interval);
+ }, [running]);
+
+ return {
+ seconds: time / 100,
+ time: (
+
+ {("0" + Math.floor((time / 6000) % 60)).slice(-2)}:
+ {("0" + Math.floor((time / 100) % 60)).slice(-2)}
+
+ ),
+ start: () => setRunning(true),
+ stop: () => setRunning(false),
+ reset: () => setTime(0),
+ };
+};
diff --git a/src/stories/Care UI/ButtonV2.stories.tsx b/src/stories/Care UI/ButtonV2.stories.tsx
deleted file mode 100644
index 512bedf9e2a..00000000000
--- a/src/stories/Care UI/ButtonV2.stories.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import type { Meta, StoryObj } from "@storybook/react";
-import ButtonV2 from "../../Components/Common/components/ButtonV2";
-
-const meta: Meta = {
- component: ButtonV2,
-};
-
-export default meta;
-type Story = StoryObj;
-
-export const Default: Story = {
- render: (args) => Click Me ,
-};
diff --git a/src/stories/Care UI/Form Fields/DateFormField.stories.tsx b/src/stories/Care UI/Form Fields/DateFormField.stories.tsx
deleted file mode 100644
index c9555c9c04d..00000000000
--- a/src/stories/Care UI/Form Fields/DateFormField.stories.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import type { Meta, StoryObj } from "@storybook/react";
-import { useState } from "react";
-import DateFormField from "../../../Components/Form/FormFields/DateFormField";
-
-const meta: Meta = {
- component: DateFormField,
-};
-
-export default meta;
-type Story = StoryObj;
-
-const WithState = (args: any) => {
- const [value, setValue] = useState();
-
- return (
- setValue(value)}
- />
- );
-};
-
-export const Default: Story = {
- args: {
- name: "date",
- label: "Select a date",
- },
- render: (args) => (
-
-
-
- ),
-};
diff --git a/src/stories/Care UI/Form Fields/DateRangeFormField.stories.tsx b/src/stories/Care UI/Form Fields/DateRangeFormField.stories.tsx
deleted file mode 100644
index 6e4e1a9d29d..00000000000
--- a/src/stories/Care UI/Form Fields/DateRangeFormField.stories.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import type { Meta, StoryObj } from "@storybook/react";
-import { useState } from "react";
-import { DateRange } from "../../../Components/Common/DateRangeInputV2";
-import DateRangeFormField from "../../../Components/Form/FormFields/DateRangeFormField";
-
-const meta: Meta = {
- component: DateRangeFormField,
-};
-
-export default meta;
-type Story = StoryObj;
-
-const WithState = (args: any) => {
- const [value, setValue] = useState();
-
- return (
- setValue(value)}
- />
- );
-};
-
-export const Default: Story = {
- args: {
- name: "date-range",
- label: "Select a date range",
- },
- render: (args) => (
-
-
-
- ),
-};
diff --git a/src/stories/Care UI/Form Fields/MultiSelectFormField.stories.tsx b/src/stories/Care UI/Form Fields/MultiSelectFormField.stories.tsx
deleted file mode 100644
index 43b10627ff4..00000000000
--- a/src/stories/Care UI/Form Fields/MultiSelectFormField.stories.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import type { Meta, StoryObj } from "@storybook/react";
-import { useState } from "react";
-import { MultiSelectFormField } from "../../../Components/Form/FormFields/SelectFormField";
-
-const meta: Meta = {
- component: MultiSelectFormField,
-};
-
-export default meta;
-type Story = StoryObj;
-
-const WithState = (args: any) => {
- const [value, setValue] = useState();
-
- return (
- setValue(value)}
- />
- );
-};
-
-export const Default: Story = {
- args: {
- name: "select",
- label: "Pick items",
- placeholder: "Select multiple options",
- options: [
- { label: "Item 1", value: "item1" },
- { label: "Item 2", value: "item2" },
- { label: "Item 3", value: "item3" },
- { label: "Item 4", value: "item4" },
- ],
- optionLabel: (option: any) => option.label,
- optionValue: (option: any) => option.value,
- },
- render: (args) => (
-
-
-
- ),
-};
diff --git a/src/stories/Care UI/Form Fields/SelectFormField.stories.tsx b/src/stories/Care UI/Form Fields/SelectFormField.stories.tsx
deleted file mode 100644
index 73fe54ff034..00000000000
--- a/src/stories/Care UI/Form Fields/SelectFormField.stories.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import type { Meta, StoryObj } from "@storybook/react";
-import { useState } from "react";
-import { SelectFormField } from "../../../Components/Form/FormFields/SelectFormField";
-
-const meta: Meta = {
- component: SelectFormField,
-};
-
-export default meta;
-type Story = StoryObj;
-
-const WithState = (args: any) => {
- const [value, setValue] = useState();
-
- return (
- setValue(value)}
- />
- );
-};
-
-export const Default: Story = {
- args: {
- name: "select",
- label: "Pick an item",
- placeholder: "Select an option",
- options: [
- { label: "Item 1", value: "item1" },
- { label: "Item 2", value: "item2" },
- { label: "Item 3", value: "item3" },
- { label: "Item 4", value: "item4" },
- ],
- optionLabel: (option: any) => option.label,
- optionValue: (option: any) => option.value,
- },
- render: (args) => (
-
-
-
- ),
-};
diff --git a/src/stories/Care UI/Slideover.stories.tsx b/src/stories/Care UI/Slideover.stories.tsx
deleted file mode 100644
index 0c13d3e6111..00000000000
--- a/src/stories/Care UI/Slideover.stories.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import type { Meta, StoryObj } from "@storybook/react";
-import { useState } from "react";
-import SlideOver from "../../CAREUI/interactive/SlideOver";
-import ButtonV2 from "../../Components/Common/components/ButtonV2";
-
-const meta: Meta = {
- component: SlideOver,
-};
-
-export default meta;
-type Story = StoryObj;
-
-const WithState = (args: any) => {
- const [open, setOpen] = useState(false);
-
- return (
-
- setOpen(true)}>Open SlideOver
-
- Content
-
-
- );
-};
-
-export const Default: Story = {
- args: {
- slideFrom: "right",
- title: "Title",
- dialogClass: "md:w-[400px]",
- },
- render: (args) => ,
-};
diff --git a/src/stories/Introduction.mdx b/src/stories/Introduction.mdx
deleted file mode 100644
index e128c8c6cec..00000000000
--- a/src/stories/Introduction.mdx
+++ /dev/null
@@ -1,224 +0,0 @@
-import { Meta } from "@storybook/blocks";
-import Code from "./assets/code-brackets.svg";
-import Colors from "./assets/colors.svg";
-import Comments from "./assets/comments.svg";
-import Direction from "./assets/direction.svg";
-import Flow from "./assets/flow.svg";
-import Plugin from "./assets/plugin.svg";
-import Repo from "./assets/repo.svg";
-import StackAlt from "./assets/stackalt.svg";
-
-
-
-
-
-# Welcome to Storybook
-
-Storybook helps you build UI components in isolation from your app's business logic, data, and context.
-That makes it easy to develop hard-to-reach states. Save these UI states as **stories** to revisit during development, testing, or QA.
-
-Browse example stories now by navigating to them in the sidebar.
-View their code in the `stories` directory to learn how they work.
-We recommend building UIs with a [**component-driven**](https://componentdriven.org) process starting with atomic components and ending with pages.
-
-Configure
-
-
-
-Learn
-
-
-
-
- Tip Edit the Markdown in
- stories/Introduction.stories.mdx
-
diff --git a/src/stories/assets/code-brackets.svg b/src/stories/assets/code-brackets.svg
deleted file mode 100644
index 73de9477600..00000000000
--- a/src/stories/assets/code-brackets.svg
+++ /dev/null
@@ -1 +0,0 @@
-illustration/code-brackets
\ No newline at end of file
diff --git a/src/stories/assets/colors.svg b/src/stories/assets/colors.svg
deleted file mode 100644
index 17d58d516e1..00000000000
--- a/src/stories/assets/colors.svg
+++ /dev/null
@@ -1 +0,0 @@
-illustration/colors
\ No newline at end of file
diff --git a/src/stories/assets/comments.svg b/src/stories/assets/comments.svg
deleted file mode 100644
index 6493a139f52..00000000000
--- a/src/stories/assets/comments.svg
+++ /dev/null
@@ -1 +0,0 @@
-illustration/comments
\ No newline at end of file
diff --git a/src/stories/assets/direction.svg b/src/stories/assets/direction.svg
deleted file mode 100644
index 65676ac2722..00000000000
--- a/src/stories/assets/direction.svg
+++ /dev/null
@@ -1 +0,0 @@
-illustration/direction
\ No newline at end of file
diff --git a/src/stories/assets/flow.svg b/src/stories/assets/flow.svg
deleted file mode 100644
index 8ac27db403c..00000000000
--- a/src/stories/assets/flow.svg
+++ /dev/null
@@ -1 +0,0 @@
-illustration/flow
\ No newline at end of file
diff --git a/src/stories/assets/plugin.svg b/src/stories/assets/plugin.svg
deleted file mode 100644
index 29e5c690c0a..00000000000
--- a/src/stories/assets/plugin.svg
+++ /dev/null
@@ -1 +0,0 @@
-illustration/plugin
\ No newline at end of file
diff --git a/src/stories/assets/repo.svg b/src/stories/assets/repo.svg
deleted file mode 100644
index f386ee902c1..00000000000
--- a/src/stories/assets/repo.svg
+++ /dev/null
@@ -1 +0,0 @@
-illustration/repo
\ No newline at end of file
diff --git a/src/stories/assets/stackalt.svg b/src/stories/assets/stackalt.svg
deleted file mode 100644
index 9b7ad274350..00000000000
--- a/src/stories/assets/stackalt.svg
+++ /dev/null
@@ -1 +0,0 @@
-illustration/stackalt
\ No newline at end of file
diff --git a/src/style/index.css b/src/style/index.css
index f26d9bcfbc1..327cc03d047 100644
--- a/src/style/index.css
+++ b/src/style/index.css
@@ -712,6 +712,10 @@ button:disabled,
@apply bg-patient-unknown text-patient-unknown-fore
}
+.patient-activelydying {
+ @apply bg-patient-activelydying text-patient-activelydying-fore
+}
+
.patient-comfort-ring {
@apply ring-patient-comfort
}
@@ -727,6 +731,9 @@ button:disabled,
.patient-unknown-ring {
@apply ring-patient-unknown
}
+.patient-activelydying-ring {
+ @apply ring-patient-activelydying
+}
.patient-comfort-profile {
@apply border-2 border-patient-comfort rounded-t
@@ -743,6 +750,9 @@ button:disabled,
.patient-unknown-profile {
@apply border border-patient-unknown rounded
}
+.patient-activelydying-profile {
+ @apply border-2 border-patient-activelydying rounded-t
+}
/* for gmaps search dropdown */
.pac-container {
diff --git a/src/types/react-virtualized/index.d.ts b/src/types/react-virtualized/index.d.ts
deleted file mode 100755
index 40a4c38a475..00000000000
--- a/src/types/react-virtualized/index.d.ts
+++ /dev/null
@@ -1,182 +0,0 @@
-// Type definitions for react-virtualized 9.21
-// Project: https://github.com/bvaughn/react-virtualized
-// Definitions by: Kalle Ott
-// John Gunther
-// Konstantin Nesterov
-// Steve Zhang
-// Brandon Hall
-// Sebastian Busch
-// Adam Zmenak
-// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
-// TypeScript Version: 2.8
-declare module "react-virtualized" {
- export {
- ArrowKeyStepper,
- ArrowKeyStepperProps,
- ChildProps as ArrowKeyStepperChildProps,
- ScrollIndices,
- } from "./dist/es/ArrowKeyStepper";
- export {
- AutoSizer,
- AutoSizerProps,
- Dimensions,
- Size,
- } from "./dist/es/AutoSizer";
- export {
- CellMeasurer,
- CellMeasurerCache,
- CellMeasurerCacheParams,
- CellMeasurerProps,
- KeyMapper,
- } from "./dist/es/CellMeasurer";
- export {
- Collection,
- CollectionCellGroupRenderer,
- CollectionCellGroupRendererParams,
- CollectionCellRenderer,
- CollectionCellRendererParams,
- CollectionCellSizeAndPosition,
- CollectionCellSizeAndPositionGetter,
- CollectionProps,
- } from "./dist/es/Collection";
- export {
- ColumnSizer,
- ColumnSizerProps,
- SizedColumnProps,
- } from "./dist/es/ColumnSizer";
- export {
- accessibilityOverscanIndicesGetter,
- defaultOverscanIndicesGetter,
- defaultCellRangeRenderer,
- Grid,
- CellSizeAndPositionManager,
- ConfigureParams,
- ContainerSizeAndOffset,
- GetVisibleCellRangeParams,
- GridCellProps,
- GridCellRangeProps,
- GridCellRangeRenderer,
- GridCellRenderer,
- GridProps,
- GridState,
- OverscanIndices,
- OverscanIndicesGetterParams,
- ScrollDirection,
- ScrollParams,
- SectionRenderedParams,
- SizeAndPositionData,
- VisibleCellRange,
- ScrollbarPresenceParams,
- } from "./dist/es/Grid";
- export {
- InfiniteLoader,
- InfiniteLoaderChildProps,
- InfiniteLoaderProps,
- } from "./dist/es/InfiniteLoader";
- export {
- List,
- ListProps,
- ListRowProps,
- ListRowRenderer,
- } from "./dist/es/List";
- export {
- createCellPositioner as createMasonryCellPositioner,
- Masonry,
- CellRenderer,
- MasonryCellProps,
- MasonryProps,
- MasonryState,
- OnCellsRenderedCallback,
- OnScrollCallback,
- Position,
- Positioner,
- } from "./dist/es/Masonry";
- export {
- MultiGrid,
- MultiGridProps,
- MultiGridState,
- } from "./dist/es/MultiGrid";
- export {
- ScrollSync,
- OnScrollParams,
- ScrollSyncChildProps,
- ScrollSyncProps,
- ScrollSyncState,
- } from "./dist/es/ScrollSync";
- export {
- createMultiSort as createTableMultiSort,
- defaultCellDataGetter as defaultTableCellDataGetter,
- defaultCellRenderer as defaultTableCellRenderer,
- defaultHeaderRenderer as defaultTableHeaderRenderer,
- defaultHeaderRowRenderer as defaultTableHeaderRowRenderer,
- defaultRowRenderer as defaultTableRowRenderer,
- Table,
- Column,
- SortDirection,
- SortIndicator,
- ColumnProps,
- HeaderMouseEventHandlerParams,
- RowMouseEventHandlerParams,
- SortDirectionType,
- TableCellDataGetter,
- TableCellDataGetterParams,
- TableCellProps,
- TableCellRenderer,
- TableHeaderProps,
- TableHeaderRenderer,
- TableHeaderRowProps,
- TableHeaderRowRenderer,
- TableProps,
- TableRowProps,
- TableRowRenderer,
- SortParams,
- } from "./dist/es/Table";
- export {
- WindowScroller,
- WindowScrollerChildProps,
- WindowScrollerProps,
- WindowScrollerState,
- IS_SCROLLING_TIMEOUT,
- } from "./dist/es/WindowScroller";
-
- export type Index = {
- index: number;
- };
-
- export type PositionInfo = {
- x: number;
- y: number;
- };
-
- export type ScrollPosition = {
- scrollLeft: number;
- scrollTop: number;
- };
-
- export type SizeInfo = {
- height: number;
- width: number;
- };
-
- export type SizeAndPositionInfo = SizeInfo & PositionInfo;
-
- export type Map = { [key: string]: T };
-
- export type Alignment = "auto" | "end" | "start" | "center";
-
- export type IndexRange = {
- startIndex: number;
- stopIndex: number;
- };
-
- export type OverscanIndexRange = {
- overscanStartIndex: number;
- overscanStopIndex: number;
- };
-
- export type ScrollEventData = {
- clientHeight: number;
- scrollHeight: number;
- scrollTop: number;
- };
-}
diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts
index c899d453626..7a50ebe49db 100644
--- a/src/vite-env.d.ts
+++ b/src/vite-env.d.ts
@@ -1,14 +1,45 @@
///
///
interface ImportMetaEnv {
+ readonly CARE_CDN_URL?: string;
+
readonly REACT_APP_TITLE: string;
readonly REACT_APP_META_DESCRIPTION: string;
readonly REACT_APP_COVER_IMAGE: string;
readonly REACT_APP_COVER_IMAGE_ALT: string;
- readonly REACT_APP_CONFIG: string | undefined;
readonly REACT_PUBLIC_URL: string;
- readonly REACT_APP_SITE_URL: string;
- readonly REACT_APP_ANALYTICS_SERVER_URL: string;
+ readonly REACT_CARE_API_URL: string;
+ readonly REACT_DASHBOARD_URL?: string;
+ readonly REACT_GITHUB_URL?: string;
+ readonly REACT_OHCN_URL?: string;
+ readonly REACT_HEADER_LOGO?: string;
+ readonly REACT_MAIN_LOGO?: string;
+ readonly REACT_STATE_LOGO?: string;
+ readonly REACT_CUSTOM_LOGO?: string;
+ readonly REACT_CUSTOM_LOGO_ALT?: string;
+ readonly REACT_CUSTOM_DESCRIPTION?: string;
+ readonly REACT_GMAPS_API_KEY?: string;
+ readonly REACT_GOV_DATA_API_KEY?: string;
+ readonly REACT_RECAPTCHA_SITE_KEY?: string;
+ readonly REACT_KASP_ENABLED?: string;
+ readonly REACT_KASP_STRING?: string;
+ readonly REACT_KASP_FULL_STRING?: string;
+ readonly REACT_SAMPLE_FORMAT_ASSET_IMPORT?: string;
+ readonly REACT_SAMPLE_FORMAT_EXTERNAL_RESULT_IMPORT?: string;
+ readonly REACT_WARTIME_SHIFTING?: string;
+ readonly REACT_STILL_WATCHING_IDLE_TIMEOUT?: string;
+ readonly REACT_STILL_WATCHING_PROMPT_DURATION?: string;
+ readonly REACT_JWT_TOKEN_REFRESH_INTERVAL?: string;
+ readonly REACT_MIN_ENCOUNTER_DATE?: string;
+
+ // Plugins related envs...
+ readonly REACT_PLAUSIBLE_SERVER_URL?: string;
+ readonly REACT_PLAUSIBLE_SITE_DOMAIN?: string;
+ readonly REACT_SENTRY_DSN?: string;
+ readonly REACT_SENTRY_ENVIRONMENT?: string;
+ readonly REACT_ENABLE_HCX?: string;
+ readonly REACT_ENABLE_ABDM?: string;
+ readonly REACT_ENABLE_SCRIBE?: string;
}
interface ImportMeta {
diff --git a/tailwind.config.js b/tailwind.config.js
index a40c805621f..31aa43878dc 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -70,6 +70,10 @@ module.exports = {
DEFAULT: gray[400],
fore: gray[800],
},
+ activelydying: {
+ DEFAULT: colors.red[800],
+ fore: colors.red[100],
+ },
},
},
padding: {
diff --git a/tsconfig.json b/tsconfig.json
index 23f7ab14d4a..61e8476b152 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -15,10 +15,11 @@
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
- "types": ["vite/client", "vite-plugin-pwa/client"]
+ "types": ["vite/client", "vite-plugin-pwa/client"],
+ "paths": {
+ "@careConfig": ["./care.config.ts"]
+ }
},
- "include": ["src"],
- "exclude": [
- "src/**/*.gen.tsx"
- ]
+ "include": ["src", "care.config.ts"],
+ "exclude": ["src/**/*.gen.tsx"]
}
diff --git a/vite.config.mts b/vite.config.mts
index 5a8dcbae044..39ff4b4e99e 100644
--- a/vite.config.mts
+++ b/vite.config.mts
@@ -1,8 +1,19 @@
+import path from "node: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";
+const pdfWorkerPath = path.join(
+ path.dirname(
+ createRequire(import.meta.url).resolve("pdfjs-dist/package.json"),
+ ),
+ "build",
+ "pdf.worker.min.mjs",
+);
+
const cdnUrls =
process.env.CARE_CDN_URL ??
[
@@ -15,6 +26,14 @@ const cdnUrls =
export default {
envPrefix: "REACT_",
plugins: [
+ viteStaticCopy({
+ targets: [
+ {
+ src: pdfWorkerPath,
+ dest: "",
+ },
+ ],
+ }),
react(),
checker({ typescript: true }),
treeShakeCareIcons({
@@ -65,6 +84,11 @@ export default {
},
}),
],
+ resolve: {
+ alias: {
+ "@careConfig": path.resolve(__dirname, "./care.config.ts"),
+ },
+ },
build: {
outDir: "build",
assetsDir: "bundle",
@@ -81,12 +105,6 @@ export default {
},
server: {
port: 4000,
- proxy: {
- "/api": {
- target: process.env.CARE_API ?? "https://careapi.ohc.network",
- changeOrigin: true,
- },
- },
},
preview: {
headers: {
@@ -94,15 +112,9 @@ export default {
script-src 'self' blob: 'nonce-f51b9742' https://plausible.10bedicu.in;\
style-src 'self' 'unsafe-inline';\
connect-src 'self' https://plausible.10bedicu.in;\
- img-src 'self' https://cdn.coronasafe.network ${cdnUrls};\
+ img-src 'self' https://cdn.ohc.network ${cdnUrls};\
object-src 'self' ${cdnUrls};`,
},
port: 4000,
- proxy: {
- "/api": {
- target: process.env.CARE_API ?? "https://careapi.ohc.network",
- changeOrigin: true,
- },
- },
},
};