From 356f18a0975dae029d2fa815f819eddf8ff3f6a7 Mon Sep 17 00:00:00 2001 From: Rishith25 Date: Fri, 10 Jan 2025 17:19:49 +0530 Subject: [PATCH 01/11] noUncheckedIndexedAccess in tsconfig --- src/CAREUI/interactive/HumanChart.tsx | 2 +- src/Providers/PatientUserProvider.tsx | 4 +- src/Routers/AppRouter.tsx | 3 +- src/Routers/routes/ConsultationRoutes.tsx | 46 +++++++++++-------- src/Routers/routes/FacilityRoutes.tsx | 12 ++--- src/Routers/routes/OrganizationRoutes.tsx | 33 +++++++++---- src/Routers/routes/PatientRoutes.tsx | 20 ++++---- src/Routers/routes/ResourceRoutes.tsx | 4 +- src/Routers/routes/UserRoutes.tsx | 8 ++-- src/Routers/routes/questionnaireRoutes.tsx | 4 +- src/Utils/AutoSave.tsx | 10 ++-- src/Utils/utils.ts | 14 ++++-- src/common/schemaParser.ts | 17 ++++--- src/common/utils.tsx | 2 +- src/components/Common/AudioPlayer.tsx | 8 +++- src/components/Common/Avatar.tsx | 2 +- .../Common/Charts/ObservationChart.tsx | 4 +- src/components/Common/DateTextInput.tsx | 2 +- .../Common/ExcelFIleDragAndDrop.tsx | 17 +++++-- src/components/Common/Export.tsx | 6 +-- src/components/Common/GLocationPicker.tsx | 8 ++-- .../Common/SearchByMultipleFields.tsx | 30 ++++++------ .../Facility/DuplicatePatientDialog.tsx | 2 +- .../Form/FormFields/PhoneNumberFormField.tsx | 10 +++- .../Patient/PatientRegistration.tsx | 2 +- .../QuestionTypes/DateTimeQuestion.tsx | 7 ++- .../FollowUpAppointmentQuestion.tsx | 6 ++- .../Questionnaire/QuestionnaireEditor.tsx | 8 +++- .../Questionnaire/QuestionnaireForm.tsx | 6 ++- .../Questionnaire/structured/handlers.ts | 2 +- src/components/Schedule/Appointments/utils.ts | 5 +- .../Schedule/ScheduleTemplatesList.tsx | 4 +- src/components/Schedule/routes.tsx | 11 +++-- src/components/Users/UserAvailabilityTab.tsx | 8 ++-- src/components/ui/chart.tsx | 2 +- src/components/ui/input-otp.tsx | 3 +- src/hooks/useAppHistory.ts | 8 +++- src/hooks/useFileManager.tsx | 5 +- src/hooks/useFileUpload.tsx | 2 +- src/hooks/useFilters.tsx | 6 ++- src/pages/Encounters/EncounterShow.tsx | 3 +- src/pages/Encounters/PrintPrescription.tsx | 4 +- .../Encounters/tabs/EncounterNotesTab.tsx | 2 +- .../Encounters/tabs/EncounterPlotsTab.tsx | 2 +- .../FacilityOrganizationSelector.tsx | 8 +++- src/service-worker.ts | 2 +- tsconfig.json | 3 +- 47 files changed, 235 insertions(+), 142 deletions(-) diff --git a/src/CAREUI/interactive/HumanChart.tsx b/src/CAREUI/interactive/HumanChart.tsx index 1f6d87f31b3..119fe4e0a78 100644 --- a/src/CAREUI/interactive/HumanChart.tsx +++ b/src/CAREUI/interactive/HumanChart.tsx @@ -36,7 +36,7 @@ export default function HumanBodyChart({ > {getTitle( `${path.region}`.replace( - new RegExp(Object.keys(HumanBodyPaths)[i], "i"), + new RegExp(Object.keys(HumanBodyPaths)[i] || "", "i"), "", ), )} diff --git a/src/Providers/PatientUserProvider.tsx b/src/Providers/PatientUserProvider.tsx index 1ae9a9af8f1..2f85b8dfeab 100644 --- a/src/Providers/PatientUserProvider.tsx +++ b/src/Providers/PatientUserProvider.tsx @@ -50,7 +50,9 @@ export default function PatientUserProvider({ children }: Props) { const selectedPatient = userData.results.find((patient) => patient.id === localPatient?.id) || userData.results[0]; - setSelectedPatient(selectedPatient); + if (selectedPatient) { + setSelectedPatient(selectedPatient); + } localStorage.setItem("selectedPatient", JSON.stringify(selectedPatient)); } }, [userData]); diff --git a/src/Routers/AppRouter.tsx b/src/Routers/AppRouter.tsx index a49ca7767f9..d43e54af806 100644 --- a/src/Routers/AppRouter.tsx +++ b/src/Routers/AppRouter.tsx @@ -65,7 +65,8 @@ const Routes: AppRoutes = { ...(import.meta.env.PROD ? { "/icons": () => } : {}), "/apps": () => , - "/apps/plug-configs/:slug": ({ slug }) => , + "/apps/plug-configs/:slug": ({ slug }) => + slug ? : , "/login": () => , }; diff --git a/src/Routers/routes/ConsultationRoutes.tsx b/src/Routers/routes/ConsultationRoutes.tsx index 96812b5ea40..313e357af0e 100644 --- a/src/Routers/routes/ConsultationRoutes.tsx +++ b/src/Routers/routes/ConsultationRoutes.tsx @@ -11,15 +11,20 @@ const consultationRoutes: AppRoutes = { "/facility/:facilityId/encounter/:encounterId/prescriptions/print": ({ facilityId, encounterId, - }) => , + }) => ( + + ), "/facility/:facilityId/encounter/:encounterId/:tab": ({ facilityId, encounterId, tab, }) => ( ), @@ -28,18 +33,18 @@ const consultationRoutes: AppRoutes = { patientId, }) => ( ), "/facility/:facilityId/patient/:patientId/encounter/:encounterId/edit_encounter": ({ facilityId, encounterId, patientId }) => ( ), "/facility/:facilityId/patient/:patientId/questionnaire": ({ @@ -47,38 +52,41 @@ const consultationRoutes: AppRoutes = { patientId, }) => ( ), "/facility/:facilityId/patient/:patientId/encounter/:encounterId/questionnaire": ({ facilityId, encounterId, patientId }) => ( ), "/facility/:facilityId/patient/:patientId/encounter/:encounterId/questionnaire/:slug": ({ facilityId, encounterId, slug, patientId }) => ( ), "/facility/:facilityId/patient/:patientId/encounter/:encounterId/questionnaire_response/:id": ({ patientId, id }) => ( - + ), "/facility/:facilityId/patient/:patientId/consultation/:id/consent-records": ({ facilityId, patientId, id }) => ( ), "/facility/:facilityId/patient/:patientId/encounterId/:id/files/": ({ @@ -87,8 +95,8 @@ const consultationRoutes: AppRoutes = { id, }) => ( diff --git a/src/Routers/routes/FacilityRoutes.tsx b/src/Routers/routes/FacilityRoutes.tsx index 44637fdbcf8..02b0e0aa78c 100644 --- a/src/Routers/routes/FacilityRoutes.tsx +++ b/src/Routers/routes/FacilityRoutes.tsx @@ -17,22 +17,22 @@ const FacilityRoutes: AppRoutes = { ), "/facility/:facilityId": ({ facilityId }) => ( - + ), "/facility/:facilityId/users": ({ facilityId }) => ( - + ), "/facility/:facilityId/resource/new": ({ facilityId }) => ( - + ), "/facility/:facilityId/organization": ({ facilityId }) => ( - + ), "/facility/:facilityId/organization/:id": ({ facilityId, id }) => ( - + ), "/facility/:facilityId/organization/:id/users": ({ facilityId, id }) => ( - + ), }; diff --git a/src/Routers/routes/OrganizationRoutes.tsx b/src/Routers/routes/OrganizationRoutes.tsx index d6e83cb4f0f..d560ddd196f 100644 --- a/src/Routers/routes/OrganizationRoutes.tsx +++ b/src/Routers/routes/OrganizationRoutes.tsx @@ -7,29 +7,46 @@ import OrganizationView from "@/pages/Organization/OrganizationView"; const OrganizationRoutes: AppRoutes = { "/organization": () => , - "/organization/:id": ({ id }) => , - "/organization/:id/users": ({ id }) => , - "/organization/:id/patients": ({ id }) => , - "/organization/:id/facilities": ({ id }) => ( + "/organization/:id": ({ id = "" }) => , + "/organization/:id/users": ({ id = "" }) => , + "/organization/:id/patients": ({ id = "" }) => ( + + ), + "/organization/:id/facilities": ({ id = "" }) => ( ), "/organization/:navOrganizationId/children/:id": ({ navOrganizationId, id, - }) => , + }) => ( + + ), "/organization/:navOrganizationId/children/:id/users": ({ navOrganizationId, id, - }) => , + }) => ( + + ), "/organization/:navOrganizationId/children/:id/patients": ({ navOrganizationId, id, - }) => , + }) => ( + + ), "/organization/:navOrganizationId/children/:id/facilities": ({ navOrganizationId, id, }) => ( - + ), }; diff --git a/src/Routers/routes/PatientRoutes.tsx b/src/Routers/routes/PatientRoutes.tsx index 77ede2c44a9..e140dd9f7e0 100644 --- a/src/Routers/routes/PatientRoutes.tsx +++ b/src/Routers/routes/PatientRoutes.tsx @@ -10,38 +10,40 @@ import VerifyPatient from "@/pages/Patients/VerifyPatient"; const PatientRoutes: AppRoutes = { "/facility/:facilityId/patients": ({ facilityId }) => ( - + ), "/facility/:facilityId/encounters": ({ facilityId }) => ( ), "/facility/:facilityId/patients/verify": ({ facilityId }) => ( - + ), - "/patient/:id": ({ id }) => , + "/patient/:id": ({ id }) => , "/facility/:facilityId/patient/create": ({ facilityId }) => ( - + ), "/facility/:facilityId/patient/:id": ({ facilityId, id }) => ( - + ), ...patientTabs.reduce((acc: AppRoutes, tab) => { acc["/facility/:facilityId/patient/:id/" + tab.route] = ({ facilityId, id, - }) => ; + }) => ( + + ); return acc; }, {}), "/facility/:facilityId/patient/:id/update": ({ facilityId, id }) => ( - + ), "/facility/:facilityId/patient/:patientId/files": ({ facilityId, patientId, }) => ( ), diff --git a/src/Routers/routes/ResourceRoutes.tsx b/src/Routers/routes/ResourceRoutes.tsx index 547aeb53610..7f730c6a45b 100644 --- a/src/Routers/routes/ResourceRoutes.tsx +++ b/src/Routers/routes/ResourceRoutes.tsx @@ -14,8 +14,8 @@ const ResourceRoutes: AppRoutes = { "/resource": () => , "/resource/board": () => , "/resource/list": () => , - "/resource/:id": ({ id }) => , - "/resource/:id/update": ({ id }) => , + "/resource/:id": ({ id }) => , + "/resource/:id/update": ({ id }) => , }; export default ResourceRoutes; diff --git a/src/Routers/routes/UserRoutes.tsx b/src/Routers/routes/UserRoutes.tsx index 393b5fb9b2a..abf35f3c1ea 100644 --- a/src/Routers/routes/UserRoutes.tsx +++ b/src/Routers/routes/UserRoutes.tsx @@ -10,14 +10,16 @@ const UserRoutes: AppRoutes = { facilityId, username, tab, - }) => , + }) => ( + + ), "/users/:username": ({ username }) => ( ), "/users/:username/:tab": ({ username, tab }) => ( - + ), - "/user/:tab": ({ tab }) => , + "/user/:tab": ({ tab }) => , }; export default UserRoutes; diff --git a/src/Routers/routes/questionnaireRoutes.tsx b/src/Routers/routes/questionnaireRoutes.tsx index 044f9fcc1d4..b9f2d4e610c 100644 --- a/src/Routers/routes/questionnaireRoutes.tsx +++ b/src/Routers/routes/questionnaireRoutes.tsx @@ -6,8 +6,8 @@ import { AppRoutes } from "../AppRouter"; const QuestionnaireRoutes: AppRoutes = { "/questionnaire": () => , - "/questionnaire/:id": ({ id }) => , - "/questionnaire/:id/edit": ({ id }) => , + "/questionnaire/:id": ({ id }) => , + "/questionnaire/:id/edit": ({ id }) => , }; export default QuestionnaireRoutes; diff --git a/src/Utils/AutoSave.tsx b/src/Utils/AutoSave.tsx index f621a58802d..32525c6d7f3 100644 --- a/src/Utils/AutoSave.tsx +++ b/src/Utils/AutoSave.tsx @@ -113,7 +113,7 @@ export function DraftSection(props: { const saveKey = useRef(`form_draft_${window.location.pathname}`); const draftStarted = drafts.length > 0 - ? drafts[drafts.length - 1].draft == props.formData + ? (drafts[drafts.length - 1]?.draft ?? {}) == props.formData : false; useEffect(() => { @@ -181,7 +181,9 @@ export const RestoreDraftButton = () => { className="flex items-center space-x-2" onClick={() => handleDraftSelect( - (draftStarted ? drafts[0] : drafts[drafts.length - 1]).draft, + (draftStarted + ? drafts[0]?.draft + : drafts[drafts.length - 1]?.draft) || {}, ) } > @@ -191,8 +193,8 @@ export const RestoreDraftButton = () => { ( {relativeTime( draftStarted - ? drafts[0].timestamp - : drafts[drafts.length - 1].timestamp, + ? drafts[0]?.timestamp + : drafts[drafts.length - 1]?.timestamp, )} ) diff --git a/src/Utils/utils.ts b/src/Utils/utils.ts index 0d918a4398e..3e11055a908 100644 --- a/src/Utils/utils.ts +++ b/src/Utils/utils.ts @@ -287,9 +287,9 @@ export const formatPhoneNumber = (phoneNumber: string) => { const phoneCodes: Record = phoneCodesJson; return ( "+" + - phoneCodes[countryCode].code + + (phoneCodes[countryCode]?.code ?? "") + " " + - phoneNumber.slice(phoneCodes[countryCode].code.length + 1) + phoneNumber.slice((phoneCodes[countryCode]?.code.length ?? 0) + 1) ); } return phoneNumber; @@ -304,12 +304,16 @@ export const getCountryCode = (phoneNumber: string) => { for (let i = 0; i < phoneCodesArr.length; i++) { if ( phoneNumber.startsWith( - phoneCodes[phoneCodesArr[i]].code.replaceAll("-", ""), + phoneCodesArr[i] && phoneCodes[phoneCodesArr[i] as string]?.code + ? phoneCodes[phoneCodesArr[i] as string]!.code.replaceAll("-", "") + : "", ) ) { allMatchedCountries.push({ - name: phoneCodesArr[i], - code: phoneCodes[phoneCodesArr[i]].code.replaceAll("-", ""), + name: phoneCodesArr[i] ?? "", + code: + phoneCodes[phoneCodesArr[i] as string]?.code.replaceAll("-", "") ?? + "", }); } } diff --git a/src/common/schemaParser.ts b/src/common/schemaParser.ts index d4c2d89e1ee..42818582a89 100644 --- a/src/common/schemaParser.ts +++ b/src/common/schemaParser.ts @@ -91,16 +91,16 @@ const parseDataWithSchema = ( const parsedData: ParsedData[] = []; const dataWithErrors: DataWithError[] = data.map((item, index) => { return Object.keys(schema).reduce((acc, key) => { - const { - [key]: { value, error }, - } = validateAndParse(key, item[key], schema[key]); - const parsedRow = { [schema[key].prop]: value }; + const { value, error } = + validateAndParse(key, item[key], schema[key] as SingleKeySchema)[key] || + {}; + const parsedRow = { [schema[key]?.prop || key]: value }; if (error) { errors.push({ index, key, error }); } - const prop = schema[key].prop || key; + const prop = schema[key]?.prop || key; - if (schema[key].parent) { + if (schema[key]?.parent) { const indexKey = schema[key].parent || key; acc[indexKey] = acc[indexKey] || {}; acc[indexKey][prop] = { value, error }; @@ -183,7 +183,10 @@ const schemaParser = ( ); const ParsedDataWithOutErrors = parsedData.filter((item, index) => { - return !Object.values(dataWithErrors[index]).some((item) => item.error); + return ( + dataWithErrors[index] && + !Object.values(dataWithErrors[index])?.some((item) => item.error) + ); }); return { diff --git a/src/common/utils.tsx b/src/common/utils.tsx index 7089851a018..de7f626b5e6 100644 --- a/src/common/utils.tsx +++ b/src/common/utils.tsx @@ -36,7 +36,7 @@ export const useAbortableEffect = ( export const parseOptionId: ( options: readonly OptionsType[], id: string | string[], -) => string = (options, id) => { +) => string | undefined = (options, id) => { return humanizeStrings( options .filter((option) => { diff --git a/src/components/Common/AudioPlayer.tsx b/src/components/Common/AudioPlayer.tsx index 9f4545d69ab..87749a6aa5e 100644 --- a/src/components/Common/AudioPlayer.tsx +++ b/src/components/Common/AudioPlayer.tsx @@ -91,8 +91,12 @@ function AudioPlayer({ src, className }: AudioPlayerProps) { const handleSliderChange = useCallback((value: number[]) => { if (audioRef.current) { - audioRef.current.currentTime = value[0]; - setCurrentTime(value[0]); + if (value[0] !== undefined) { + audioRef.current.currentTime = value[0]; + } + if (value[0] !== undefined) { + setCurrentTime(value[0]); + } } }, []); diff --git a/src/components/Common/Avatar.tsx b/src/components/Common/Avatar.tsx index 0ef1ce7ad56..057404b8e4c 100644 --- a/src/components/Common/Avatar.tsx +++ b/src/components/Common/Avatar.tsx @@ -30,7 +30,7 @@ const stringToInt = (name: string): number => { const toColor = (name: string): [string, string] => { const index = stringToInt(name) % colors.length; - const backgroundColor = colors[index]; + const backgroundColor = colors[index] || "#FFFFFF"; // Default to white if undefined return [backgroundColor, "#333333"]; // Using dark gray for text }; diff --git a/src/components/Common/Charts/ObservationChart.tsx b/src/components/Common/Charts/ObservationChart.tsx index f79d529abb4..ec3d1bf78f5 100644 --- a/src/components/Common/Charts/ObservationChart.tsx +++ b/src/components/Common/Charts/ObservationChart.tsx @@ -351,10 +351,10 @@ export const ObservationVisualizer = ({
- {observations[0].details.enteredBy} + {observations[0]?.details.enteredBy}
diff --git a/src/components/Common/DateTextInput.tsx b/src/components/Common/DateTextInput.tsx index f2cd4844a1c..12661f66a12 100644 --- a/src/components/Common/DateTextInput.tsx +++ b/src/components/Common/DateTextInput.tsx @@ -62,7 +62,7 @@ export default function DateTextInput(props: { const getBlurredValue = (rawValue: string, key: string) => { const maxMap = [31, 12, 2999, 23, 59]; const index = Object.keys(editingText).findIndex((et) => et === key); - const value = Math.min(maxMap[index], parseInt(rawValue)); + const value = Math.min(maxMap[index] ?? 0, parseInt(rawValue)); const finalValue = rawValue.trim() !== "" ? ("000" + value).slice(key === "year" ? -4 : -2) diff --git a/src/components/Common/ExcelFIleDragAndDrop.tsx b/src/components/Common/ExcelFIleDragAndDrop.tsx index 06e99e9df5f..07cbb677d76 100644 --- a/src/components/Common/ExcelFIleDragAndDrop.tsx +++ b/src/components/Common/ExcelFIleDragAndDrop.tsx @@ -63,7 +63,12 @@ export default function ExcelFileDragAndDrop({ cellDates: true, }); const worksheetName = workbook.SheetNames[0]; - const worksheet = workbook.Sheets[worksheetName]; + const worksheet = worksheetName + ? workbook.Sheets[worksheetName] + : undefined; + if (!worksheet) { + throw new Error("Worksheet not found"); + } const data = XLSX.utils.sheet_to_json(worksheet, { defval: "" }); //converts the date to string data.forEach((row: any) => { @@ -119,12 +124,14 @@ export default function ExcelFileDragAndDrop({ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ]; - if (!fileTypes.includes(droppedFile?.type)) { + if (!fileTypes.includes(droppedFile?.type || "")) { dragProps.setFileDropError("Please drop a Excel / CSV file to upload!"); setSelectedFile(null); return; } - onSelectFile(droppedFile); + if (droppedFile) { + onSelectFile(droppedFile); + } }; return ( @@ -179,7 +186,9 @@ export default function ExcelFileDragAndDrop({ onChange={(e) => { const files = e.target.files; if (files && files.length > 0) { - onSelectFile(files[0]); + if (files[0]) { + onSelectFile(files[0]); + } } }} className="hidden" diff --git a/src/components/Common/Export.tsx b/src/components/Common/Export.tsx index 85a6a257da8..c48a2542b2e 100644 --- a/src/components/Common/Export.tsx +++ b/src/components/Common/Export.tsx @@ -62,15 +62,15 @@ export const ExportMenu = ({ className="gap-2" disabled={isExporting || disabled} onClick={() => { - let action = item.action; - if (item.route) { + let action = item?.action; + if (item?.route) { action = async () => { const { data } = await request(item.route!); return data ?? null; }; } if (action) { - exportFile(action, item.filePrefix, item.type, item.parse); + exportFile(action, item?.filePrefix, item?.type, item?.parse); } }} > diff --git a/src/components/Common/GLocationPicker.tsx b/src/components/Common/GLocationPicker.tsx index cee05ce4245..fd84dc55ed0 100644 --- a/src/components/Common/GLocationPicker.tsx +++ b/src/components/Common/GLocationPicker.tsx @@ -137,7 +137,7 @@ const Map: React.FC = ({ React.useEffect(() => { if (searchRef.current && map && !searchBox) { - map.controls[google.maps.ControlPosition.TOP_CENTER].push( + map?.controls[google.maps.ControlPosition.TOP_CENTER]?.push( searchRef.current, ); @@ -156,7 +156,7 @@ const Map: React.FC = ({ handleOnChange && places && places.length > 0 && - places[0].geometry?.location + places[0]?.geometry?.location ) { const selectedLocation = places[0].geometry.location; handleOnChange(selectedLocation); @@ -168,7 +168,7 @@ const Map: React.FC = ({ React.useEffect(() => { if (mapCloseRef.current && map) { - map.controls[google.maps.ControlPosition.TOP_RIGHT].push( + map?.controls[google.maps.ControlPosition.TOP_RIGHT]?.push( mapCloseRef.current, ); } @@ -176,7 +176,7 @@ const Map: React.FC = ({ React.useEffect(() => { if (currentLocationSelectRef.current && map) { - map.controls[google.maps.ControlPosition.TOP_LEFT].push( + map?.controls[google.maps.ControlPosition.TOP_LEFT]?.push( currentLocationSelectRef.current, ); } diff --git a/src/components/Common/SearchByMultipleFields.tsx b/src/components/Common/SearchByMultipleFields.tsx index ffc3822fea7..3355e93b554 100644 --- a/src/components/Common/SearchByMultipleFields.tsx +++ b/src/components/Common/SearchByMultipleFields.tsx @@ -69,15 +69,15 @@ const SearchByMultipleFields: React.FC = ({ initialOptionIndex || 0, ); const selectedOption = options[selectedOptionIndex]; - const [searchValue, setSearchValue] = useState(selectedOption.value || ""); + const [searchValue, setSearchValue] = useState(selectedOption?.value || ""); const [open, setOpen] = useState(false); const inputRef = useRef(null); const [focusedIndex, setFocusedIndex] = useState(0); const [error, setError] = useState(); useEffect(() => { - if (!(selectedOption.type === "phone" && searchValue.length < 13)) { - setSearchValue(options[selectedOptionIndex].value); + if (!(selectedOption?.type === "phone" && searchValue.length < 13)) { + setSearchValue(options[selectedOptionIndex]?.value || ""); } }, [options]); @@ -95,13 +95,15 @@ const SearchByMultipleFields: React.FC = ({ (index: number) => { setSelectedOptionIndex(index); const option = options[index]; - setSearchValue(option.value || ""); - setFocusedIndex(options.findIndex((op) => op.key === option.key)); + setSearchValue(option?.value || ""); + setFocusedIndex(options.findIndex((op) => op.key === option?.key)); setOpen(false); inputRef.current?.focus(); setError(false); - onSearch(option.key, option.value); - onFieldChange?.(options[index]); + onSearch(option?.key || "", option?.value || ""); + if (option) { + onFieldChange?.(option); + } }, [onSearch], ); @@ -157,10 +159,10 @@ const SearchByMultipleFields: React.FC = ({ }, [selectedOptionIndex]); useEffect(() => { - if (selectedOption.value !== searchValue) { - onSearch(selectedOption.key, searchValue); + if (selectedOption?.value !== searchValue) { + onSearch(selectedOption?.key || "", searchValue); } - }, [searchValue, selectedOption.key, selectedOption.value, onSearch]); + }, [searchValue, selectedOption?.key, selectedOption?.value, onSearch]); const handleSearchChange = useCallback((event: EventType) => { const value = "target" in event ? event.target.value : event.value; @@ -178,12 +180,12 @@ const SearchByMultipleFields: React.FC = ({ ), } as const; - switch (selectedOption.type) { + switch (selectedOption?.type) { case "phone": return ( = ({ ); @@ -271,7 +273,7 @@ const SearchByMultipleFields: React.FC = ({ size="xs" data-test-id={id + "__" + option.key} className={cn( - selectedOption.key === option.key + selectedOption?.key === option.key ? "bg-primary-100 text-primary-700 hover:bg-primary-200 border-primary-400" : "bg-gray-100 text-gray-700 hover:bg-gray-200", buttonClassName, diff --git a/src/components/Facility/DuplicatePatientDialog.tsx b/src/components/Facility/DuplicatePatientDialog.tsx index ea12f1d06c4..03bc3538815 100644 --- a/src/components/Facility/DuplicatePatientDialog.tsx +++ b/src/components/Facility/DuplicatePatientDialog.tsx @@ -39,7 +39,7 @@ const DuplicatePatientDialog = (props: Props) => {

{t("patient_records_found_description")}( - {patientList[0].phone_number}) + {patientList[0]?.phone_number})

diff --git a/src/components/Form/FormFields/PhoneNumberFormField.tsx b/src/components/Form/FormFields/PhoneNumberFormField.tsx index 72a3e0c3076..284b9353cb6 100644 --- a/src/components/Form/FormFields/PhoneNumberFormField.tsx +++ b/src/components/Form/FormFields/PhoneNumberFormField.tsx @@ -104,7 +104,13 @@ const PhoneNumberFormField = React.forwardRef( setCountry({ flag: "🌍", name: "Other", code: "+" }); return; } - setCountry(phoneCodes[getCountryCode(field.value)!]); + const countryCode = getCountryCode(field.value); + if (countryCode) { + const countryData = phoneCodes[countryCode]; + if (countryData) { + setCountry(countryData); + } + } } }, [field.value]); @@ -186,7 +192,7 @@ const PhoneNumberTypesHelp = (props: { types: PhoneNumberType[] }) => { ); }; const conditionPhoneCode = (code: string) => { - code = code.split(" ")[0]; + code = (code || "").split(" ")[0] || ""; return code.startsWith("+") ? code : "+" + code; }; diff --git a/src/components/Patient/PatientRegistration.tsx b/src/components/Patient/PatientRegistration.tsx index 36ac706c23b..4e137328ea2 100644 --- a/src/components/Patient/PatientRegistration.tsx +++ b/src/components/Patient/PatientRegistration.tsx @@ -471,7 +471,7 @@ export default function PatientRegistration( ["dob", t("date_of_birth")], ["age", t("age")], ].map(([key, label]) => ( - {label} + {label} ))} diff --git a/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx b/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx index b20629e171c..ddb13b16e6f 100644 --- a/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx @@ -55,8 +55,11 @@ export function DateTimeQuestion({ }; const handleTimeChange = (event: React.ChangeEvent) => { - const [hours, minutes] = event.target.value.split(":").map(Number); - if (isNaN(hours) || isNaN(minutes)) return; + const [hours, minutes] = event.target.value.split(":").map((value) => { + const number = Number(value); + return isNaN(number) ? undefined : number; + }); + if (hours === undefined || minutes === undefined) return; const date = currentValue || new Date(); date.setHours(hours); diff --git a/src/components/Questionnaire/QuestionTypes/FollowUpAppointmentQuestion.tsx b/src/components/Questionnaire/QuestionTypes/FollowUpAppointmentQuestion.tsx index f0f1cd3d79f..aa88c9a083f 100644 --- a/src/components/Questionnaire/QuestionTypes/FollowUpAppointmentQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/FollowUpAppointmentQuestion.tsx @@ -50,8 +50,10 @@ export function FollowUpAppointmentQuestion({ (questionnaireResponse.values?.[0] ?.value as unknown as FollowUpAppointmentRequest[]) || []; - const value = values[0] ?? {}; - + const value: FollowUpAppointmentRequest = values[0] ?? { + reason_for_visit: "", + slot_id: "", + }; const handleUpdate = (updates: Partial) => { const followUpAppointment = { ...value, ...updates }; updateQuestionnaireResponseCB({ diff --git a/src/components/Questionnaire/QuestionnaireEditor.tsx b/src/components/Questionnaire/QuestionnaireEditor.tsx index 8c7f0fa0854..10874c9d52b 100644 --- a/src/components/Questionnaire/QuestionnaireEditor.tsx +++ b/src/components/Questionnaire/QuestionnaireEditor.tsx @@ -131,7 +131,9 @@ export default function QuestionnaireEditor({ id }: QuestionnaireEditorProps) { const items = Array.from(questionnaire.questions); const [reorderedItem] = items.splice(result.source.index, 1); - items.splice(result.destination.index, 0, reorderedItem); + if (reorderedItem) { + items.splice(result.destination.index, 0, reorderedItem); + } updateQuestionnaireField("questions", items); }; @@ -1149,7 +1151,9 @@ function QuestionEditor({ const items = Array.from(questions || []); const [reorderedItem] = items.splice(result.source.index, 1); - items.splice(result.destination.index, 0, reorderedItem); + if (reorderedItem) { + items.splice(result.destination.index, 0, reorderedItem); + } updateField("questions", items); }} diff --git a/src/components/Questionnaire/QuestionnaireForm.tsx b/src/components/Questionnaire/QuestionnaireForm.tsx index 62953de8681..0f3abfc0a68 100644 --- a/src/components/Questionnaire/QuestionnaireForm.tsx +++ b/src/components/Questionnaire/QuestionnaireForm.tsx @@ -147,11 +147,13 @@ export function QuestionnaireForm({ (error: QuestionValidationError | DetailedValidationError) => { // Handle question-specific errors if ("question_id" in error) { - form.errors.push({ + form?.errors.push({ question_id: error.question_id, error: error.error ?? error.msg, } as QuestionValidationError); - updatedForms[index] = form; + if (form) { + updatedForms[index] = form; + } } // Handle form-level errors diff --git a/src/components/Questionnaire/structured/handlers.ts b/src/components/Questionnaire/structured/handlers.ts index 5d11c1b7359..a7536997a70 100644 --- a/src/components/Questionnaire/structured/handlers.ts +++ b/src/components/Questionnaire/structured/handlers.ts @@ -149,7 +149,7 @@ const handlers: { }, follow_up_appointment: { getRequests: (followUpAppointment, { facilityId, patientId }) => { - const { reason_for_visit, slot_id } = followUpAppointment[0]; + const { reason_for_visit = "", slot_id } = followUpAppointment[0] || {}; return [ { url: `/api/v1/facility/${facilityId}/slots/${slot_id}/create_appointment/`, diff --git a/src/components/Schedule/Appointments/utils.ts b/src/components/Schedule/Appointments/utils.ts index 6460b568391..dd3fae16026 100644 --- a/src/components/Schedule/Appointments/utils.ts +++ b/src/components/Schedule/Appointments/utils.ts @@ -52,7 +52,10 @@ export const groupSlotsByAvailability = (slots: SlotAvailability[]) => { // sort availability by first slot start time result.sort((a, b) => - compareAsc(a.slots[0].start_datetime, b.slots[0].start_datetime), + compareAsc( + a.slots[0]?.start_datetime ?? "00:00", + b.slots[0]?.start_datetime ?? "00:00", + ), ); return result; diff --git a/src/components/Schedule/ScheduleTemplatesList.tsx b/src/components/Schedule/ScheduleTemplatesList.tsx index c6464d2c211..db1cc5456b1 100644 --- a/src/components/Schedule/ScheduleTemplatesList.tsx +++ b/src/components/Schedule/ScheduleTemplatesList.tsx @@ -107,8 +107,8 @@ const ScheduleTemplateItem = (props: ScheduleTemplate) => { {Math.floor( getSlotsPerSession( - slot.availability[0].start_time, - slot.availability[0].end_time, + slot.availability[0]?.start_time ?? "00:00", + slot.availability[0]?.end_time ?? "23:59", slot.slot_size_in_minutes, ) ?? 0, )}{" "} diff --git a/src/components/Schedule/routes.tsx b/src/components/Schedule/routes.tsx index c784bc03c05..bbe4ca8c0f9 100644 --- a/src/components/Schedule/routes.tsx +++ b/src/components/Schedule/routes.tsx @@ -25,15 +25,20 @@ const ScheduleRoutes: AppRoutes = { "/facility/:facilityId/patient/:patientId/book-appointment": ({ facilityId, patientId, - }) => , + }) => ( + + ), "/facility/:facilityId/patient/:patientId/appointments/:appointmentId": ({ facilityId, appointmentId, }) => ( ), }; diff --git a/src/components/Users/UserAvailabilityTab.tsx b/src/components/Users/UserAvailabilityTab.tsx index e949cceb2bf..b28066533e1 100644 --- a/src/components/Users/UserAvailabilityTab.tsx +++ b/src/components/Users/UserAvailabilityTab.tsx @@ -200,8 +200,8 @@ export default function UserAvailabilityTab({ userData: user }: Props) {

{Math.floor( getSlotsPerSession( - availability[0].start_time, - availability[0].end_time, + availability[0]?.start_time || "00:00", + availability[0]?.end_time || "23:59", slot_size_in_minutes, ) ?? 0, )}{" "} @@ -299,7 +299,7 @@ const diagonalStripes = { export const formatAvailabilityTime = ( availability: ScheduleAvailability["availability"], ) => { - const startTime = availability[0].start_time; - const endTime = availability[0].end_time; + const startTime = availability[0]?.start_time || "00:00"; + const endTime = availability[0]?.end_time || "23:59"; return `${formatTimeShort(startTime)} - ${formatTimeShort(endTime)}`; }; diff --git a/src/components/ui/chart.tsx b/src/components/ui/chart.tsx index 5887b4d3acb..07289a66ab4 100644 --- a/src/components/ui/chart.tsx +++ b/src/components/ui/chart.tsx @@ -137,7 +137,7 @@ const ChartTooltipContent = React.forwardRef< } const [item] = payload; - const key = `${labelKey || item.dataKey || item.name || "value"}`; + const key = `${labelKey || item?.dataKey || item?.name || "value"}`; const itemConfig = getPayloadConfigFromPayload(config, item, key); const value = !labelKey && typeof label === "string" diff --git a/src/components/ui/input-otp.tsx b/src/components/ui/input-otp.tsx index ea07b294c56..62ebf77d903 100644 --- a/src/components/ui/input-otp.tsx +++ b/src/components/ui/input-otp.tsx @@ -33,7 +33,8 @@ const InputOTPSlot = React.forwardRef< React.ComponentPropsWithoutRef<"div"> & { index: number } >(({ index, className, ...props }, ref) => { const inputOTPContext = React.useContext(OTPInputContext); - const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index]; + const slot = inputOTPContext.slots[index]; + const { char, hasFakeCaret, isActive } = slot || {}; return (

{ - if (history.length > 1) + if (history.length > 1) { // Otherwise, navigate to history present in the app navigation history stack. - return navigate(history[1]); + const target = history[1]; + if (target) { + return history[1]; + } + } if (fallbackUrl) // use provided fallback url if provided. diff --git a/src/hooks/useFileManager.tsx b/src/hooks/useFileManager.tsx index e6c92ff5166..82fafce3b88 100644 --- a/src/hooks/useFileManager.tsx +++ b/src/hooks/useFileManager.tsx @@ -81,8 +81,9 @@ export default function useFileManager( const queryClient = useQueryClient(); const getExtension = (url: string) => { - const div1 = url.split("?")[0].split("."); - const ext: string = div1[div1.length - 1].toLowerCase(); + const div1 = url.split("?")[0]?.split(".") || []; + const ext: string = + div1.length > 0 ? (div1[div1.length - 1]?.toLowerCase() ?? "") : ""; return ext; }; diff --git a/src/hooks/useFileUpload.tsx b/src/hooks/useFileUpload.tsx index d5884dddd02..90db763a10a 100644 --- a/src/hooks/useFileUpload.tsx +++ b/src/hooks/useFileUpload.tsx @@ -105,7 +105,7 @@ export default function useFileUpload( setFiles((prev) => [...prev, ...selectedFiles]); selectedFiles.forEach((file) => { - const ext: string = file.name.split(".")[1]; + const ext: string = file.name.split(".")[1] || ""; if (ExtImage.includes(ext)) { const options = { initialQuality: 0.6, diff --git a/src/hooks/useFilters.tsx b/src/hooks/useFilters.tsx index c5984a70c9c..bcdc4daa5ab 100644 --- a/src/hooks/useFilters.tsx +++ b/src/hooks/useFilters.tsx @@ -94,7 +94,9 @@ export default function useFilters({ name={name} value={ value === undefined - ? humanizeStrings(paramKey.map((k) => qParams[k]).filter(Boolean)) + ? humanizeStrings( + paramKey.map((k) => qParams[k]).filter(Boolean), + ) || "" : value } onRemove={() => removeFilters(paramKey)} @@ -128,7 +130,7 @@ export default function useFilters({ }, range(name: string, paramKey: string, minKey = "min", maxKey = "max") { const paramKeys = [paramKey + "_" + minKey, paramKey + "_" + maxKey]; - const values = [qParams[paramKeys[0]], qParams[paramKeys[1]]]; + const values = [qParams[paramKeys[0] || ""], qParams[paramKeys[1] || ""]]; if (values[0] === values[1]) return [{ name, value: values[0], paramKey: paramKeys }]; return [name + " " + minKey, name + " " + maxKey].map((name, i) => { diff --git a/src/pages/Encounters/EncounterShow.tsx b/src/pages/Encounters/EncounterShow.tsx index 0440aa49aae..b68383ed927 100644 --- a/src/pages/Encounters/EncounterShow.tsx +++ b/src/pages/Encounters/EncounterShow.tsx @@ -166,8 +166,7 @@ export const EncounterShow = (props: Props) => { if (!encounterData) { return ; } - - const SelectedTab = tabs[props.tab]; + const SelectedTab = tabs[props.tab] || EncounterUpdatesTab; const tabButtonClasses = (selected: boolean) => `capitalize min-w-max-content cursor-pointer font-bold whitespace-nowrap ${ diff --git a/src/pages/Encounters/PrintPrescription.tsx b/src/pages/Encounters/PrintPrescription.tsx index b5f8f8ec4e6..3e7225a6dfb 100644 --- a/src/pages/Encounters/PrintPrescription.tsx +++ b/src/pages/Encounters/PrintPrescription.tsx @@ -194,10 +194,10 @@ export const PrintPrescription = (props: { {Array.from(usedFrequencies).map((key) => (
- {FREQUENCY_DISPLAY[key].code} + {FREQUENCY_DISPLAY[key]?.code} - = {FREQUENCY_DISPLAY[key].meaning} + = {FREQUENCY_DISPLAY[key]?.meaning}
))} diff --git a/src/pages/Encounters/tabs/EncounterNotesTab.tsx b/src/pages/Encounters/tabs/EncounterNotesTab.tsx index d8a93b592c5..88cf7db9bac 100644 --- a/src/pages/Encounters/tabs/EncounterNotesTab.tsx +++ b/src/pages/Encounters/tabs/EncounterNotesTab.tsx @@ -331,7 +331,7 @@ export const EncounterNotesTab = ({ encounter }: EncounterTabProps) => { // Auto-select first thread useEffect(() => { if (threadsData?.results.length && !selectedThread) { - setSelectedThread(threadsData.results[0].id); + setSelectedThread(threadsData?.results[0]?.id ?? null); } }, [threadsData, selectedThread]); diff --git a/src/pages/Encounters/tabs/EncounterPlotsTab.tsx b/src/pages/Encounters/tabs/EncounterPlotsTab.tsx index cc9c6d57689..b039dfc342c 100644 --- a/src/pages/Encounters/tabs/EncounterPlotsTab.tsx +++ b/src/pages/Encounters/tabs/EncounterPlotsTab.tsx @@ -30,7 +30,7 @@ export const EncounterPlotsTab = (props: EncounterTabProps) => { return ; } - const currentTabId = qParams.plot || data[0].id; + const currentTabId = qParams.plot || data[0]?.id; const currentTab = data.find((tab) => tab.id === currentTabId); if (!currentTab) { diff --git a/src/pages/FacilityOrganization/components/FacilityOrganizationSelector.tsx b/src/pages/FacilityOrganization/components/FacilityOrganizationSelector.tsx index b9c32974a82..d99cf9382a5 100644 --- a/src/pages/FacilityOrganization/components/FacilityOrganizationSelector.tsx +++ b/src/pages/FacilityOrganization/components/FacilityOrganizationSelector.tsx @@ -100,8 +100,12 @@ export default function FacilityOrganizationSelector( setSelectedLevels(newLevels); if (newLevels.length > 0) { const lastOrg = newLevels[newLevels.length - 1]; - setSelectedOrganization(lastOrg); - onChange(lastOrg.id); + if (lastOrg) { + setSelectedOrganization(lastOrg); + } + if (lastOrg?.id) { + onChange(lastOrg.id); + } } else { setSelectedOrganization(null); } diff --git a/src/service-worker.ts b/src/service-worker.ts index 078e4237c28..d2f832f91de 100644 --- a/src/service-worker.ts +++ b/src/service-worker.ts @@ -35,7 +35,7 @@ self.addEventListener("push", async function (event) { if (["PUSH_MESSAGE", "MESSAGE"].includes(data?.type)) { self.clients.matchAll().then((clients) => { - clients[0].postMessage(data); + clients[0]?.postMessage(data); }); } else { event.waitUntil( diff --git a/tsconfig.json b/tsconfig.json index bba22c5da97..11113ca92df 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,7 +22,8 @@ "@core/*": ["src/*"], "@careConfig": ["./care.config.ts"] }, - "typeRoots": ["./node_modules/@types", "./src/remote-modules.d.ts"] + "typeRoots": ["./node_modules/@types", "./src/remote-modules.d.ts"], + "noUncheckedIndexedAccess": true }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.d.ts", "care.config.ts"], "exclude": ["src/**/*.gen.tsx"] From 2f356a2fa75670dde08e14d1eba4bd4581892de7 Mon Sep 17 00:00:00 2001 From: Rishith25 Date: Fri, 10 Jan 2025 17:50:50 +0530 Subject: [PATCH 02/11] resolved coderabbit changes --- src/Routers/routes/OrganizationRoutes.tsx | 27 +++++++++++++---------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/Routers/routes/OrganizationRoutes.tsx b/src/Routers/routes/OrganizationRoutes.tsx index d560ddd196f..cc7c3fb822c 100644 --- a/src/Routers/routes/OrganizationRoutes.tsx +++ b/src/Routers/routes/OrganizationRoutes.tsx @@ -7,35 +7,38 @@ import OrganizationView from "@/pages/Organization/OrganizationView"; const OrganizationRoutes: AppRoutes = { "/organization": () => , - "/organization/:id": ({ id = "" }) => , - "/organization/:id/users": ({ id = "" }) => , - "/organization/:id/patients": ({ id = "" }) => ( - + "/organization/:id": ({ id }) => , + "/organization/:id/users": ({ id }) => , + "/organization/:id/patients": ({ id }) => ( + ), - "/organization/:id/facilities": ({ id = "" }) => ( - + "/organization/:id/facilities": ({ id }) => ( + ), "/organization/:navOrganizationId/children/:id": ({ navOrganizationId, id, }) => ( ), "/organization/:navOrganizationId/children/:id/users": ({ navOrganizationId, id, }) => ( - + ), "/organization/:navOrganizationId/children/:id/patients": ({ navOrganizationId, id, }) => ( ), @@ -44,8 +47,8 @@ const OrganizationRoutes: AppRoutes = { id, }) => ( ), }; From 260e7fd395973b77eb1475190a5d20c7830cc351 Mon Sep 17 00:00:00 2001 From: Rishith25 Date: Fri, 10 Jan 2025 17:54:00 +0530 Subject: [PATCH 03/11] resolved coderabbit changes --- src/Routers/routes/ConsultationRoutes.tsx | 24 +++++++++---------- src/Routers/routes/FacilityRoutes.tsx | 18 +++++++++----- src/Routers/routes/PatientRoutes.tsx | 18 +++++++------- src/Routers/routes/ResourceRoutes.tsx | 4 ++-- src/Routers/routes/UserRoutes.tsx | 6 ++--- src/Routers/routes/questionnaireRoutes.tsx | 4 ++-- .../Facility/DuplicatePatientDialog.tsx | 5 +++- .../QuestionTypes/DateTimeQuestion.tsx | 2 +- src/components/Schedule/routes.tsx | 4 ++-- src/hooks/useAppHistory.ts | 5 +--- 10 files changed, 48 insertions(+), 42 deletions(-) diff --git a/src/Routers/routes/ConsultationRoutes.tsx b/src/Routers/routes/ConsultationRoutes.tsx index 313e357af0e..fd5584d8511 100644 --- a/src/Routers/routes/ConsultationRoutes.tsx +++ b/src/Routers/routes/ConsultationRoutes.tsx @@ -13,8 +13,8 @@ const consultationRoutes: AppRoutes = { encounterId, }) => ( ), "/facility/:facilityId/encounter/:encounterId/:tab": ({ @@ -23,8 +23,8 @@ const consultationRoutes: AppRoutes = { tab, }) => ( ), @@ -33,18 +33,18 @@ const consultationRoutes: AppRoutes = { patientId, }) => ( ), "/facility/:facilityId/patient/:patientId/encounter/:encounterId/edit_encounter": ({ facilityId, encounterId, patientId }) => ( ), "/facility/:facilityId/patient/:patientId/questionnaire": ({ @@ -52,17 +52,17 @@ const consultationRoutes: AppRoutes = { patientId, }) => ( ), "/facility/:facilityId/patient/:patientId/encounter/:encounterId/questionnaire": ({ facilityId, encounterId, patientId }) => ( ), "/facility/:facilityId/patient/:patientId/encounter/:encounterId/questionnaire/:slug": diff --git a/src/Routers/routes/FacilityRoutes.tsx b/src/Routers/routes/FacilityRoutes.tsx index 02b0e0aa78c..6365e88a41b 100644 --- a/src/Routers/routes/FacilityRoutes.tsx +++ b/src/Routers/routes/FacilityRoutes.tsx @@ -17,22 +17,28 @@ const FacilityRoutes: AppRoutes = { ), "/facility/:facilityId": ({ facilityId }) => ( - + ), "/facility/:facilityId/users": ({ facilityId }) => ( - + ), "/facility/:facilityId/resource/new": ({ facilityId }) => ( - + ), "/facility/:facilityId/organization": ({ facilityId }) => ( - + ), "/facility/:facilityId/organization/:id": ({ facilityId, id }) => ( - + ), "/facility/:facilityId/organization/:id/users": ({ facilityId, id }) => ( - + ), }; diff --git a/src/Routers/routes/PatientRoutes.tsx b/src/Routers/routes/PatientRoutes.tsx index e140dd9f7e0..57aefb55086 100644 --- a/src/Routers/routes/PatientRoutes.tsx +++ b/src/Routers/routes/PatientRoutes.tsx @@ -10,40 +10,40 @@ import VerifyPatient from "@/pages/Patients/VerifyPatient"; const PatientRoutes: AppRoutes = { "/facility/:facilityId/patients": ({ facilityId }) => ( - + ), "/facility/:facilityId/encounters": ({ facilityId }) => ( ), "/facility/:facilityId/patients/verify": ({ facilityId }) => ( - + ), - "/patient/:id": ({ id }) => , + "/patient/:id": ({ id }) => , "/facility/:facilityId/patient/create": ({ facilityId }) => ( - + ), "/facility/:facilityId/patient/:id": ({ facilityId, id }) => ( - + ), ...patientTabs.reduce((acc: AppRoutes, tab) => { acc["/facility/:facilityId/patient/:id/" + tab.route] = ({ facilityId, id, }) => ( - + ); return acc; }, {}), "/facility/:facilityId/patient/:id/update": ({ facilityId, id }) => ( - + ), "/facility/:facilityId/patient/:patientId/files": ({ facilityId, patientId, }) => ( ), diff --git a/src/Routers/routes/ResourceRoutes.tsx b/src/Routers/routes/ResourceRoutes.tsx index 7f730c6a45b..3b5ec42901f 100644 --- a/src/Routers/routes/ResourceRoutes.tsx +++ b/src/Routers/routes/ResourceRoutes.tsx @@ -14,8 +14,8 @@ const ResourceRoutes: AppRoutes = { "/resource": () => , "/resource/board": () => , "/resource/list": () => , - "/resource/:id": ({ id }) => , - "/resource/:id/update": ({ id }) => , + "/resource/:id": ({ id }) => , + "/resource/:id/update": ({ id }) => , }; export default ResourceRoutes; diff --git a/src/Routers/routes/UserRoutes.tsx b/src/Routers/routes/UserRoutes.tsx index abf35f3c1ea..7b7923c753d 100644 --- a/src/Routers/routes/UserRoutes.tsx +++ b/src/Routers/routes/UserRoutes.tsx @@ -11,15 +11,15 @@ const UserRoutes: AppRoutes = { username, tab, }) => ( - + ), "/users/:username": ({ username }) => ( ), "/users/:username/:tab": ({ username, tab }) => ( - + ), - "/user/:tab": ({ tab }) => , + "/user/:tab": ({ tab }) => , }; export default UserRoutes; diff --git a/src/Routers/routes/questionnaireRoutes.tsx b/src/Routers/routes/questionnaireRoutes.tsx index b9f2d4e610c..d11557f0e70 100644 --- a/src/Routers/routes/questionnaireRoutes.tsx +++ b/src/Routers/routes/questionnaireRoutes.tsx @@ -6,8 +6,8 @@ import { AppRoutes } from "../AppRouter"; const QuestionnaireRoutes: AppRoutes = { "/questionnaire": () => , - "/questionnaire/:id": ({ id }) => , - "/questionnaire/:id/edit": ({ id }) => , + "/questionnaire/:id": ({ id }) => , + "/questionnaire/:id/edit": ({ id }) => , }; export default QuestionnaireRoutes; diff --git a/src/components/Facility/DuplicatePatientDialog.tsx b/src/components/Facility/DuplicatePatientDialog.tsx index 03bc3538815..7429fc207d8 100644 --- a/src/components/Facility/DuplicatePatientDialog.tsx +++ b/src/components/Facility/DuplicatePatientDialog.tsx @@ -39,7 +39,10 @@ const DuplicatePatientDialog = (props: Props) => {

{t("patient_records_found_description")}( - {patientList[0]?.phone_number}) + + {patientList[0] && patientList[0]?.phone_number} + + )

diff --git a/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx b/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx index ddb13b16e6f..ea104df49ec 100644 --- a/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx @@ -57,7 +57,7 @@ export function DateTimeQuestion({ const handleTimeChange = (event: React.ChangeEvent) => { const [hours, minutes] = event.target.value.split(":").map((value) => { const number = Number(value); - return isNaN(number) ? undefined : number; + return Number.isNaN(number) ? undefined : number; }); if (hours === undefined || minutes === undefined) return; diff --git a/src/components/Schedule/routes.tsx b/src/components/Schedule/routes.tsx index bbe4ca8c0f9..98453b24380 100644 --- a/src/components/Schedule/routes.tsx +++ b/src/components/Schedule/routes.tsx @@ -37,8 +37,8 @@ const ScheduleRoutes: AppRoutes = { appointmentId, }) => ( ), }; diff --git a/src/hooks/useAppHistory.ts b/src/hooks/useAppHistory.ts index 32aa3d316f8..fd83ca49501 100644 --- a/src/hooks/useAppHistory.ts +++ b/src/hooks/useAppHistory.ts @@ -13,10 +13,7 @@ export default function useAppHistory() { const goBack = (fallbackUrl?: string) => { if (history.length > 1) { // Otherwise, navigate to history present in the app navigation history stack. - const target = history[1]; - if (target) { - return history[1]; - } + return history[1] || fallbackUrl; } if (fallbackUrl) From 5c5d3cde95cdbbeb817413e05908f3da869c0a41 Mon Sep 17 00:00:00 2001 From: Rishith25 Date: Fri, 10 Jan 2025 18:40:52 +0530 Subject: [PATCH 04/11] optimized and removed redundant conditions --- src/CAREUI/interactive/HumanChart.tsx | 2 +- src/Routers/routes/FacilityRoutes.tsx | 2 +- src/Utils/AutoSave.tsx | 4 +--- src/common/schemaParser.ts | 6 +++--- src/common/utils.tsx | 20 ++++++++++--------- src/components/Common/AudioPlayer.tsx | 2 -- src/components/Common/Avatar.tsx | 2 +- src/components/Common/DateTextInput.tsx | 5 ++++- .../Common/ExcelFIleDragAndDrop.tsx | 13 +++++------- .../Common/SearchByMultipleFields.tsx | 6 +++--- .../Form/FormFields/PhoneNumberFormField.tsx | 2 +- .../Questionnaire/structured/handlers.ts | 3 ++- src/components/Schedule/routes.tsx | 4 ++-- src/components/Users/UserAvailabilityTab.tsx | 4 ++-- src/components/ui/input-otp.tsx | 2 +- src/hooks/useFileUpload.tsx | 2 +- src/hooks/useFilters.tsx | 6 +++--- .../FacilityOrganizationSelector.tsx | 2 -- 18 files changed, 42 insertions(+), 45 deletions(-) diff --git a/src/CAREUI/interactive/HumanChart.tsx b/src/CAREUI/interactive/HumanChart.tsx index 119fe4e0a78..2ae90408362 100644 --- a/src/CAREUI/interactive/HumanChart.tsx +++ b/src/CAREUI/interactive/HumanChart.tsx @@ -36,7 +36,7 @@ export default function HumanBodyChart({ > {getTitle( `${path.region}`.replace( - new RegExp(Object.keys(HumanBodyPaths)[i] || "", "i"), + new RegExp(Object.keys(HumanBodyPaths)[i] ?? "", "i"), "", ), )} diff --git a/src/Routers/routes/FacilityRoutes.tsx b/src/Routers/routes/FacilityRoutes.tsx index 6365e88a41b..90df37b44c7 100644 --- a/src/Routers/routes/FacilityRoutes.tsx +++ b/src/Routers/routes/FacilityRoutes.tsx @@ -20,7 +20,7 @@ const FacilityRoutes: AppRoutes = { ), "/facility/:facilityId/users": ({ facilityId }) => ( - + ), "/facility/:facilityId/resource/new": ({ facilityId }) => ( diff --git a/src/Utils/AutoSave.tsx b/src/Utils/AutoSave.tsx index 32525c6d7f3..6e539b0b12c 100644 --- a/src/Utils/AutoSave.tsx +++ b/src/Utils/AutoSave.tsx @@ -181,9 +181,7 @@ export const RestoreDraftButton = () => { className="flex items-center space-x-2" onClick={() => handleDraftSelect( - (draftStarted - ? drafts[0]?.draft - : drafts[drafts.length - 1]?.draft) || {}, + (draftStarted ? drafts[0] : drafts[drafts.length - 1])?.draft, ) } > diff --git a/src/common/schemaParser.ts b/src/common/schemaParser.ts index 42818582a89..8e139237c9f 100644 --- a/src/common/schemaParser.ts +++ b/src/common/schemaParser.ts @@ -92,13 +92,13 @@ const parseDataWithSchema = ( const dataWithErrors: DataWithError[] = data.map((item, index) => { return Object.keys(schema).reduce((acc, key) => { const { value, error } = - validateAndParse(key, item[key], schema[key] as SingleKeySchema)[key] || + validateAndParse(key, item[key], schema[key] as SingleKeySchema)[key] ?? {}; - const parsedRow = { [schema[key]?.prop || key]: value }; + const parsedRow = { [schema[key]?.prop ?? key]: value }; if (error) { errors.push({ index, key, error }); } - const prop = schema[key]?.prop || key; + const prop = schema[key]?.prop ?? key; if (schema[key]?.parent) { const indexKey = schema[key].parent || key; diff --git a/src/common/utils.tsx b/src/common/utils.tsx index de7f626b5e6..cdbb726d1a4 100644 --- a/src/common/utils.tsx +++ b/src/common/utils.tsx @@ -36,15 +36,17 @@ export const useAbortableEffect = ( export const parseOptionId: ( options: readonly OptionsType[], id: string | string[], -) => string | undefined = (options, id) => { - return humanizeStrings( - options - .filter((option) => { - return id instanceof Array - ? id.map((i) => String(i)).includes(String(option.id)) - : String(option.id) === String(id); - }) - .map((option) => option.text), +) => string = (options, id) => { + return ( + humanizeStrings( + options + .filter((option) => { + return id instanceof Array + ? id.map((i) => String(i)).includes(String(option.id)) + : String(option.id) === String(id); + }) + .map((option) => option.text), + ) ?? "" ); }; diff --git a/src/components/Common/AudioPlayer.tsx b/src/components/Common/AudioPlayer.tsx index 87749a6aa5e..de2e000618d 100644 --- a/src/components/Common/AudioPlayer.tsx +++ b/src/components/Common/AudioPlayer.tsx @@ -93,8 +93,6 @@ function AudioPlayer({ src, className }: AudioPlayerProps) { if (audioRef.current) { if (value[0] !== undefined) { audioRef.current.currentTime = value[0]; - } - if (value[0] !== undefined) { setCurrentTime(value[0]); } } diff --git a/src/components/Common/Avatar.tsx b/src/components/Common/Avatar.tsx index 057404b8e4c..2950e077c2d 100644 --- a/src/components/Common/Avatar.tsx +++ b/src/components/Common/Avatar.tsx @@ -30,7 +30,7 @@ const stringToInt = (name: string): number => { const toColor = (name: string): [string, string] => { const index = stringToInt(name) % colors.length; - const backgroundColor = colors[index] || "#FFFFFF"; // Default to white if undefined + const backgroundColor = colors[index] ?? "#FFFFFF"; return [backgroundColor, "#333333"]; // Using dark gray for text }; diff --git a/src/components/Common/DateTextInput.tsx b/src/components/Common/DateTextInput.tsx index 12661f66a12..053efa4208f 100644 --- a/src/components/Common/DateTextInput.tsx +++ b/src/components/Common/DateTextInput.tsx @@ -62,7 +62,10 @@ export default function DateTextInput(props: { const getBlurredValue = (rawValue: string, key: string) => { const maxMap = [31, 12, 2999, 23, 59]; const index = Object.keys(editingText).findIndex((et) => et === key); - const value = Math.min(maxMap[index] ?? 0, parseInt(rawValue)); + const value = + index !== -1 && maxMap[index] != null + ? Math.min(maxMap[index], parseInt(rawValue)) + : parseInt(rawValue); const finalValue = rawValue.trim() !== "" ? ("000" + value).slice(key === "year" ? -4 : -2) diff --git a/src/components/Common/ExcelFIleDragAndDrop.tsx b/src/components/Common/ExcelFIleDragAndDrop.tsx index 07cbb677d76..d4b6fd26f63 100644 --- a/src/components/Common/ExcelFIleDragAndDrop.tsx +++ b/src/components/Common/ExcelFIleDragAndDrop.tsx @@ -63,13 +63,10 @@ export default function ExcelFileDragAndDrop({ cellDates: true, }); const worksheetName = workbook.SheetNames[0]; - const worksheet = worksheetName - ? workbook.Sheets[worksheetName] - : undefined; - if (!worksheet) { - throw new Error("Worksheet not found"); - } - const data = XLSX.utils.sheet_to_json(worksheet, { defval: "" }); + const worksheet = worksheetName && workbook.Sheets[worksheetName]; + const data = worksheet + ? XLSX.utils.sheet_to_json(worksheet, { defval: "" }) + : []; //converts the date to string data.forEach((row: any) => { Object.keys(row).forEach((key) => { @@ -124,7 +121,7 @@ export default function ExcelFileDragAndDrop({ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ]; - if (!fileTypes.includes(droppedFile?.type || "")) { + if (!fileTypes.includes(droppedFile?.type ?? "")) { dragProps.setFileDropError("Please drop a Excel / CSV file to upload!"); setSelectedFile(null); return; diff --git a/src/components/Common/SearchByMultipleFields.tsx b/src/components/Common/SearchByMultipleFields.tsx index 3355e93b554..c5249827330 100644 --- a/src/components/Common/SearchByMultipleFields.tsx +++ b/src/components/Common/SearchByMultipleFields.tsx @@ -77,7 +77,7 @@ const SearchByMultipleFields: React.FC = ({ useEffect(() => { if (!(selectedOption?.type === "phone" && searchValue.length < 13)) { - setSearchValue(options[selectedOptionIndex]?.value || ""); + setSearchValue(options[selectedOptionIndex]?.value ?? ""); } }, [options]); @@ -100,7 +100,7 @@ const SearchByMultipleFields: React.FC = ({ setOpen(false); inputRef.current?.focus(); setError(false); - onSearch(option?.key || "", option?.value || ""); + onSearch(option?.key ?? "", option?.value ?? ""); if (option) { onFieldChange?.(option); } @@ -160,7 +160,7 @@ const SearchByMultipleFields: React.FC = ({ useEffect(() => { if (selectedOption?.value !== searchValue) { - onSearch(selectedOption?.key || "", searchValue); + onSearch(selectedOption?.key ?? "", searchValue); } }, [searchValue, selectedOption?.key, selectedOption?.value, onSearch]); diff --git a/src/components/Form/FormFields/PhoneNumberFormField.tsx b/src/components/Form/FormFields/PhoneNumberFormField.tsx index 284b9353cb6..905d6e92226 100644 --- a/src/components/Form/FormFields/PhoneNumberFormField.tsx +++ b/src/components/Form/FormFields/PhoneNumberFormField.tsx @@ -192,7 +192,7 @@ const PhoneNumberTypesHelp = (props: { types: PhoneNumberType[] }) => { ); }; const conditionPhoneCode = (code: string) => { - code = (code || "").split(" ")[0] || ""; + code = code.split(" ")[0] ?? ""; return code.startsWith("+") ? code : "+" + code; }; diff --git a/src/components/Questionnaire/structured/handlers.ts b/src/components/Questionnaire/structured/handlers.ts index a7536997a70..baf496aa8d4 100644 --- a/src/components/Questionnaire/structured/handlers.ts +++ b/src/components/Questionnaire/structured/handlers.ts @@ -149,7 +149,8 @@ const handlers: { }, follow_up_appointment: { getRequests: (followUpAppointment, { facilityId, patientId }) => { - const { reason_for_visit = "", slot_id } = followUpAppointment[0] || {}; + const { reason_for_visit = "", slot_id = "" } = + followUpAppointment[0] ?? {}; return [ { url: `/api/v1/facility/${facilityId}/slots/${slot_id}/create_appointment/`, diff --git a/src/components/Schedule/routes.tsx b/src/components/Schedule/routes.tsx index 98453b24380..c5580fc7259 100644 --- a/src/components/Schedule/routes.tsx +++ b/src/components/Schedule/routes.tsx @@ -27,8 +27,8 @@ const ScheduleRoutes: AppRoutes = { patientId, }) => ( ), diff --git a/src/components/Users/UserAvailabilityTab.tsx b/src/components/Users/UserAvailabilityTab.tsx index b28066533e1..d0a69e83eb2 100644 --- a/src/components/Users/UserAvailabilityTab.tsx +++ b/src/components/Users/UserAvailabilityTab.tsx @@ -299,7 +299,7 @@ const diagonalStripes = { export const formatAvailabilityTime = ( availability: ScheduleAvailability["availability"], ) => { - const startTime = availability[0]?.start_time || "00:00"; - const endTime = availability[0]?.end_time || "23:59"; + const startTime = availability[0]?.start_time ?? "00:00"; + const endTime = availability[0]?.end_time ?? "23:59"; return `${formatTimeShort(startTime)} - ${formatTimeShort(endTime)}`; }; diff --git a/src/components/ui/input-otp.tsx b/src/components/ui/input-otp.tsx index 62ebf77d903..b870e03e450 100644 --- a/src/components/ui/input-otp.tsx +++ b/src/components/ui/input-otp.tsx @@ -34,7 +34,7 @@ const InputOTPSlot = React.forwardRef< >(({ index, className, ...props }, ref) => { const inputOTPContext = React.useContext(OTPInputContext); const slot = inputOTPContext.slots[index]; - const { char, hasFakeCaret, isActive } = slot || {}; + const { char, hasFakeCaret, isActive } = slot ?? {}; return (
[...prev, ...selectedFiles]); selectedFiles.forEach((file) => { - const ext: string = file.name.split(".")[1] || ""; + const ext: string = file.name.split(".")[1] ?? ""; if (ExtImage.includes(ext)) { const options = { initialQuality: 0.6, diff --git a/src/hooks/useFilters.tsx b/src/hooks/useFilters.tsx index bcdc4daa5ab..8f80228189c 100644 --- a/src/hooks/useFilters.tsx +++ b/src/hooks/useFilters.tsx @@ -94,9 +94,9 @@ export default function useFilters({ name={name} value={ value === undefined - ? humanizeStrings( + ? (humanizeStrings( paramKey.map((k) => qParams[k]).filter(Boolean), - ) || "" + ) ?? "") : value } onRemove={() => removeFilters(paramKey)} @@ -130,7 +130,7 @@ export default function useFilters({ }, range(name: string, paramKey: string, minKey = "min", maxKey = "max") { const paramKeys = [paramKey + "_" + minKey, paramKey + "_" + maxKey]; - const values = [qParams[paramKeys[0] || ""], qParams[paramKeys[1] || ""]]; + const values = [qParams[paramKeys[0] ?? ""], qParams[paramKeys[1] ?? ""]]; if (values[0] === values[1]) return [{ name, value: values[0], paramKey: paramKeys }]; return [name + " " + minKey, name + " " + maxKey].map((name, i) => { diff --git a/src/pages/FacilityOrganization/components/FacilityOrganizationSelector.tsx b/src/pages/FacilityOrganization/components/FacilityOrganizationSelector.tsx index d99cf9382a5..5267da41a1c 100644 --- a/src/pages/FacilityOrganization/components/FacilityOrganizationSelector.tsx +++ b/src/pages/FacilityOrganization/components/FacilityOrganizationSelector.tsx @@ -102,8 +102,6 @@ export default function FacilityOrganizationSelector( const lastOrg = newLevels[newLevels.length - 1]; if (lastOrg) { setSelectedOrganization(lastOrg); - } - if (lastOrg?.id) { onChange(lastOrg.id); } } else { From 7e25a9b01d0d406c9baa04cc902c50ba475777d0 Mon Sep 17 00:00:00 2001 From: Rishith25 Date: Fri, 10 Jan 2025 18:58:02 +0530 Subject: [PATCH 05/11] naviagte in useAppHistory --- src/hooks/useAppHistory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useAppHistory.ts b/src/hooks/useAppHistory.ts index fd83ca49501..e87c2fb0c52 100644 --- a/src/hooks/useAppHistory.ts +++ b/src/hooks/useAppHistory.ts @@ -13,7 +13,7 @@ export default function useAppHistory() { const goBack = (fallbackUrl?: string) => { if (history.length > 1) { // Otherwise, navigate to history present in the app navigation history stack. - return history[1] || fallbackUrl; + return navigate(history[1] || fallbackUrl || "/"); } if (fallbackUrl) From 57c8e5aad682ecceb3f0dd18e83bd454f85c5413 Mon Sep 17 00:00:00 2001 From: Rishith25 Date: Fri, 10 Jan 2025 19:07:54 +0530 Subject: [PATCH 06/11] coderabiitai change --- src/common/utils.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/utils.tsx b/src/common/utils.tsx index cdbb726d1a4..148de278759 100644 --- a/src/common/utils.tsx +++ b/src/common/utils.tsx @@ -41,7 +41,7 @@ export const parseOptionId: ( humanizeStrings( options .filter((option) => { - return id instanceof Array + return Array.isArray(id) ? id.map((i) => String(i)).includes(String(option.id)) : String(option.id) === String(id); }) From 6de2db1a8c9eb12e7a4105ee247877c6222ca2a1 Mon Sep 17 00:00:00 2001 From: Rishith25 Date: Fri, 10 Jan 2025 19:40:21 +0530 Subject: [PATCH 07/11] wrong file added --- .../Schedule/ScheduleTemplatesList.tsx | 140 ------------------ 1 file changed, 140 deletions(-) delete mode 100644 src/components/Schedule/ScheduleTemplatesList.tsx diff --git a/src/components/Schedule/ScheduleTemplatesList.tsx b/src/components/Schedule/ScheduleTemplatesList.tsx deleted file mode 100644 index db1cc5456b1..00000000000 --- a/src/components/Schedule/ScheduleTemplatesList.tsx +++ /dev/null @@ -1,140 +0,0 @@ -import { DotsHorizontalIcon } from "@radix-ui/react-icons"; -import { format, parseISO } from "date-fns"; -import { useTranslation } from "react-i18next"; - -import ColoredIndicator from "@/CAREUI/display/ColoredIndicator"; -import CareIcon from "@/CAREUI/icons/CareIcon"; - -import { Button } from "@/components/ui/button"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; - -import Loading from "@/components/Common/Loading"; -import { - getDaysOfWeekFromAvailabilities, - getSlotsPerSession, -} from "@/components/Schedule/helpers"; -import { - ScheduleSlotTypes, - ScheduleTemplate, -} from "@/components/Schedule/types"; -import { formatAvailabilityTime } from "@/components/Users/UserAvailabilityTab"; - -interface Props { - items?: ScheduleTemplate[]; -} - -export default function ScheduleTemplatesList({ items }: Props) { - if (items == null) { - return ; - } - - if (items.length === 0) { - return ( -
- -

No schedule templates found for this month.

-
- ); - } - - return ( -
    - {items.map((template) => ( -
  • - -
  • - ))} -
- ); -} - -const ScheduleTemplateItem = (props: ScheduleTemplate) => { - const { t } = useTranslation(); - return ( -
-
-
- -
- {props.name} - - Scheduled for{" "} - - {getDaysOfWeekFromAvailabilities(props.availabilities) - .map((day) => t(`DAYS_OF_WEEK_SHORT__${day}`)) - .join(", ")} - - -
-
- - - - - - Delete - - -
-
-
    - {props.availabilities.map((slot) => ( -
  • -
    -
    -
    - {slot.name} -

    - - {/* TODO: Temp. hack since backend is giving slot_type as number in Response */} - { - ScheduleSlotTypes[ - (slot.slot_type as unknown as number) - 1 - ] - } - - | - - {Math.floor( - getSlotsPerSession( - slot.availability[0]?.start_time ?? "00:00", - slot.availability[0]?.end_time ?? "23:59", - slot.slot_size_in_minutes, - ) ?? 0, - )}{" "} - slots of {slot.slot_size_in_minutes} mins. - -

    -
    - - {formatAvailabilityTime(slot.availability)} - -
    -
    -
  • - ))} -
- - Valid from{" "} - - {format(parseISO(props.valid_from), "EEE, dd MMM yyyy")} - {" "} - till{" "} - - {format(parseISO(props.valid_to), "EEE, dd MMM yyyy")} - - -
-
- ); -}; From 46d564dbb7be79f223350ba0ae5e18d4379030bb Mon Sep 17 00:00:00 2001 From: Rishith25 Date: Fri, 10 Jan 2025 19:47:14 +0530 Subject: [PATCH 08/11] resolved the errors --- src/pages/Scheduling/ScheduleTemplates.tsx | 4 ++-- .../Scheduling/components/EditScheduleTemplateSheet.tsx | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pages/Scheduling/ScheduleTemplates.tsx b/src/pages/Scheduling/ScheduleTemplates.tsx index 5d32b332910..909ca0113ec 100644 --- a/src/pages/Scheduling/ScheduleTemplates.tsx +++ b/src/pages/Scheduling/ScheduleTemplates.tsx @@ -127,8 +127,8 @@ const ScheduleTemplateItem = ({ {Math.floor( getSlotsPerSession( - slot.availability[0].start_time, - slot.availability[0].end_time, + slot.availability[0]?.start_time ?? "00:00", + slot.availability[0]?.end_time ?? "23:59", slot.slot_size_in_minutes, ) ?? 0, )}{" "} diff --git a/src/pages/Scheduling/components/EditScheduleTemplateSheet.tsx b/src/pages/Scheduling/components/EditScheduleTemplateSheet.tsx index cd8b01d7020..d2fbaf98b7b 100644 --- a/src/pages/Scheduling/components/EditScheduleTemplateSheet.tsx +++ b/src/pages/Scheduling/components/EditScheduleTemplateSheet.tsx @@ -332,8 +332,8 @@ const AvailabilityEditor = ({ const slots = Math.floor( getSlotsPerSession( - availability.availability[0].start_time, - availability.availability[0].end_time, + availability.availability[0]?.start_time ?? "00:00", + availability.availability[0]?.end_time ?? "23:59", availability.slot_size_in_minutes, ) ?? 0, ); @@ -435,8 +435,8 @@ const AvailabilityEditor = ({ {Object.entries(availabilitiesByDay).map(([day, times]) => (

- {DayOfWeek[parseInt(day)].charAt(0) + - DayOfWeek[parseInt(day)].slice(1).toLowerCase()} + {(DayOfWeek[parseInt(day)] || "").charAt(0) + + DayOfWeek[parseInt(day)]?.slice(1).toLowerCase()} {times From 8671dfdf1fe61451bddf987952836740a83c2f0f Mon Sep 17 00:00:00 2001 From: Rishith25 Date: Sat, 11 Jan 2025 01:31:49 +0530 Subject: [PATCH 09/11] done suggested changes --- src/CAREUI/interactive/HumanChart.tsx | 91 ------------------- src/Utils/AutoSave.tsx | 16 +--- src/Utils/utils.ts | 33 ++++--- src/common/schemaParser.ts | 4 +- src/components/Common/Avatar.tsx | 2 +- src/components/Common/DateTextInput.tsx | 6 +- src/components/Common/GLocationPicker.tsx | 6 +- .../Common/SearchByMultipleFields.tsx | 4 +- .../Facility/DuplicatePatientDialog.tsx | 5 +- .../Patient/PatientRegistration.tsx | 14 ++- .../QuestionTypes/AppointmentQuestion.tsx | 5 +- .../QuestionTypes/DateTimeQuestion.tsx | 12 ++- .../Questionnaire/QuestionnaireForm.tsx | 2 +- .../Questionnaire/structured/handlers.ts | 2 +- src/components/Users/UserAvailabilityTab.tsx | 23 +++-- src/components/ui/input-otp.tsx | 3 +- src/hooks/useAppHistory.ts | 2 +- src/hooks/useFilters.tsx | 5 +- src/pages/Appointments/utils.ts | 12 +-- .../Encounters/tabs/EncounterNotesTab.tsx | 8 +- src/pages/Scheduling/ScheduleTemplates.tsx | 15 +-- .../components/EditScheduleTemplateSheet.tsx | 47 ++++++---- 22 files changed, 116 insertions(+), 201 deletions(-) delete mode 100644 src/CAREUI/interactive/HumanChart.tsx diff --git a/src/CAREUI/interactive/HumanChart.tsx b/src/CAREUI/interactive/HumanChart.tsx deleted file mode 100644 index 2ae90408362..00000000000 --- a/src/CAREUI/interactive/HumanChart.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import { Fragment } from "react/jsx-runtime"; - -import { HumanBodyPaths, HumanBodyRegion } from "@/common/constants"; - -type Props = { - regionColor: (region: HumanBodyRegion) => string; - regionLabelClassName: (region: HumanBodyRegion) => string; - regionText: (region: HumanBodyRegion) => string; - onPartSelect: (region: HumanBodyRegion) => void; -}; - -export default function HumanBodyChart({ - regionLabelClassName, - regionColor, - regionText, - onPartSelect, -}: Props) { - const getTitle = (text: string) => text.split(/(?=[A-Z])/).join(" "); - - return ( -

- {[HumanBodyPaths.anterior, HumanBodyPaths.posterior].map((paths, i) => ( -
-

- {i === 0 ? "Front" : "Back"} -

-
- {paths.map((path, j) => ( - - ))} -
- - {paths.map((path, j) => { - const value = regionText(path.region); - return ( - - {value && ( - - {value} - - )} - onPartSelect(path.region)} - > - {getTitle(path.region)} - - - ); - })} - -
- ))} -
- ); -} diff --git a/src/Utils/AutoSave.tsx b/src/Utils/AutoSave.tsx index 6e539b0b12c..0ba6c012034 100644 --- a/src/Utils/AutoSave.tsx +++ b/src/Utils/AutoSave.tsx @@ -174,27 +174,19 @@ export const RestoreDraftButton = () => { return null; } + const draft = draftStarted ? drafts[0] : drafts[drafts.length - 1]; + return ( ); diff --git a/src/Utils/utils.ts b/src/Utils/utils.ts index 3e11055a908..4da578ec8d7 100644 --- a/src/Utils/utils.ts +++ b/src/Utils/utils.ts @@ -285,12 +285,11 @@ export const formatPhoneNumber = (phoneNumber: string) => { const countryCode = getCountryCode(phoneNumber); if (!countryCode) return phoneNumber; const phoneCodes: Record = phoneCodesJson; - return ( - "+" + - (phoneCodes[countryCode]?.code ?? "") + - " " + - phoneNumber.slice((phoneCodes[countryCode]?.code.length ?? 0) + 1) - ); + const countryData = phoneCodes[countryCode]; + + if (!countryData) return phoneNumber; + + return `+${countryData.code} ${phoneNumber.slice(countryData.code.length + 1)}`; } return phoneNumber; }; @@ -302,18 +301,18 @@ export const getCountryCode = (phoneNumber: string) => { phoneNumber = phoneNumber.slice(1); const allMatchedCountries: { name: string; code: string }[] = []; for (let i = 0; i < phoneCodesArr.length; i++) { - if ( - phoneNumber.startsWith( - phoneCodesArr[i] && phoneCodes[phoneCodesArr[i] as string]?.code - ? phoneCodes[phoneCodesArr[i] as string]!.code.replaceAll("-", "") - : "", - ) - ) { + const countryCode = phoneCodesArr[i]; + if (!countryCode) continue; + + const countryData = phoneCodes[countryCode]; + if (!countryData || !countryData.code) continue; + + const formattedCode = countryData.code.replaceAll("-", ""); + + if (phoneNumber.startsWith(formattedCode)) { allMatchedCountries.push({ - name: phoneCodesArr[i] ?? "", - code: - phoneCodes[phoneCodesArr[i] as string]?.code.replaceAll("-", "") ?? - "", + name: countryCode, + code: formattedCode, }); } } diff --git a/src/common/schemaParser.ts b/src/common/schemaParser.ts index 8e139237c9f..dacd7c5c337 100644 --- a/src/common/schemaParser.ts +++ b/src/common/schemaParser.ts @@ -98,7 +98,7 @@ const parseDataWithSchema = ( if (error) { errors.push({ index, key, error }); } - const prop = schema[key]?.prop ?? key; + const prop = schema[key]?.prop || key; if (schema[key]?.parent) { const indexKey = schema[key].parent || key; @@ -185,7 +185,7 @@ const schemaParser = ( const ParsedDataWithOutErrors = parsedData.filter((item, index) => { return ( dataWithErrors[index] && - !Object.values(dataWithErrors[index])?.some((item) => item.error) + !Object.values(dataWithErrors[index]).some((item) => item.error) ); }); diff --git a/src/components/Common/Avatar.tsx b/src/components/Common/Avatar.tsx index 2950e077c2d..728fa6a37fd 100644 --- a/src/components/Common/Avatar.tsx +++ b/src/components/Common/Avatar.tsx @@ -58,7 +58,7 @@ const Avatar: React.FC = ({ className, icon, }) => { - const [bgColor] = propColors || (name ? toColor(name) : toColor("")); + const [bgColor] = propColors || toColor(name || ""); return (
{ const maxMap = [31, 12, 2999, 23, 59]; const index = Object.keys(editingText).findIndex((et) => et === key); - const value = - index !== -1 && maxMap[index] != null - ? Math.min(maxMap[index], parseInt(rawValue)) - : parseInt(rawValue); + const maxValue = maxMap[index]; + const value = maxValue && Math.min(maxValue, parseInt(rawValue)); const finalValue = rawValue.trim() !== "" ? ("000" + value).slice(key === "year" ? -4 : -2) diff --git a/src/components/Common/GLocationPicker.tsx b/src/components/Common/GLocationPicker.tsx index fd84dc55ed0..0f55ebafa00 100644 --- a/src/components/Common/GLocationPicker.tsx +++ b/src/components/Common/GLocationPicker.tsx @@ -137,7 +137,7 @@ const Map: React.FC = ({ React.useEffect(() => { if (searchRef.current && map && !searchBox) { - map?.controls[google.maps.ControlPosition.TOP_CENTER]?.push( + map.controls[google.maps.ControlPosition.TOP_CENTER]?.push( searchRef.current, ); @@ -168,7 +168,7 @@ const Map: React.FC = ({ React.useEffect(() => { if (mapCloseRef.current && map) { - map?.controls[google.maps.ControlPosition.TOP_RIGHT]?.push( + map.controls[google.maps.ControlPosition.TOP_RIGHT]?.push( mapCloseRef.current, ); } @@ -176,7 +176,7 @@ const Map: React.FC = ({ React.useEffect(() => { if (currentLocationSelectRef.current && map) { - map?.controls[google.maps.ControlPosition.TOP_LEFT]?.push( + map.controls[google.maps.ControlPosition.TOP_LEFT]?.push( currentLocationSelectRef.current, ); } diff --git a/src/components/Common/SearchByMultipleFields.tsx b/src/components/Common/SearchByMultipleFields.tsx index c5249827330..5e297355254 100644 --- a/src/components/Common/SearchByMultipleFields.tsx +++ b/src/components/Common/SearchByMultipleFields.tsx @@ -95,13 +95,13 @@ const SearchByMultipleFields: React.FC = ({ (index: number) => { setSelectedOptionIndex(index); const option = options[index]; - setSearchValue(option?.value || ""); setFocusedIndex(options.findIndex((op) => op.key === option?.key)); setOpen(false); inputRef.current?.focus(); setError(false); - onSearch(option?.key ?? "", option?.value ?? ""); if (option) { + setSearchValue(option.value); + onSearch(option.key, option.value); onFieldChange?.(option); } }, diff --git a/src/components/Facility/DuplicatePatientDialog.tsx b/src/components/Facility/DuplicatePatientDialog.tsx index 7429fc207d8..03bc3538815 100644 --- a/src/components/Facility/DuplicatePatientDialog.tsx +++ b/src/components/Facility/DuplicatePatientDialog.tsx @@ -39,10 +39,7 @@ const DuplicatePatientDialog = (props: Props) => {

{t("patient_records_found_description")}( - - {patientList[0] && patientList[0]?.phone_number} - - ) + {patientList[0]?.phone_number})

diff --git a/src/components/Patient/PatientRegistration.tsx b/src/components/Patient/PatientRegistration.tsx index 4e137328ea2..df404990c83 100644 --- a/src/components/Patient/PatientRegistration.tsx +++ b/src/components/Patient/PatientRegistration.tsx @@ -467,11 +467,15 @@ export default function PatientRegistration( } > - {[ - ["dob", t("date_of_birth")], - ["age", t("age")], - ].map(([key, label]) => ( - {label} + {( + [ + ["dob", t("date_of_birth")], + ["age", t("age")], + ] as const + ).map(([key, label]) => ( + + {label} + ))} diff --git a/src/components/Questionnaire/QuestionTypes/AppointmentQuestion.tsx b/src/components/Questionnaire/QuestionTypes/AppointmentQuestion.tsx index 9820d5ea885..c3828a07625 100644 --- a/src/components/Questionnaire/QuestionTypes/AppointmentQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/AppointmentQuestion.tsx @@ -50,10 +50,7 @@ export function AppointmentQuestion({ (questionnaireResponse.values?.[0] ?.value as unknown as CreateAppointmentQuestion[]) || []; - const value: CreateAppointmentQuestion = values[0] ?? { - reason_for_visit: "", - slot_id: "", - }; + const value: Partial = values[0] ?? {}; const handleUpdate = (updates: Partial) => { const appointment = { ...value, ...updates }; diff --git a/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx b/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx index ea104df49ec..122083f913f 100644 --- a/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx @@ -55,11 +55,13 @@ export function DateTimeQuestion({ }; const handleTimeChange = (event: React.ChangeEvent) => { - const [hours, minutes] = event.target.value.split(":").map((value) => { - const number = Number(value); - return Number.isNaN(number) ? undefined : number; - }); - if (hours === undefined || minutes === undefined) return; + const [hoursStr, minutesStr] = event.target.value.split(":"); + const hours = Number(hoursStr); + const minutes = Number(minutesStr); + + if (isNaN(hours) || isNaN(minutes)) { + return; + } const date = currentValue || new Date(); date.setHours(hours); diff --git a/src/components/Questionnaire/QuestionnaireForm.tsx b/src/components/Questionnaire/QuestionnaireForm.tsx index a3e90ea70be..b6a40c3851e 100644 --- a/src/components/Questionnaire/QuestionnaireForm.tsx +++ b/src/components/Questionnaire/QuestionnaireForm.tsx @@ -151,7 +151,7 @@ export function QuestionnaireForm({ const updatedForms = [...questionnaireForms]; const errorMessages: string[] = []; - results.forEach((result, index) => { + results?.forEach((result, index) => { const form = updatedForms[index]; result.data.errors.forEach( diff --git a/src/components/Questionnaire/structured/handlers.ts b/src/components/Questionnaire/structured/handlers.ts index 078df81b26c..5e281dc641d 100644 --- a/src/components/Questionnaire/structured/handlers.ts +++ b/src/components/Questionnaire/structured/handlers.ts @@ -149,7 +149,7 @@ const handlers: { }, appointment: { getRequests: (appointment, { facilityId, patientId }) => { - const { reason_for_visit = "", slot_id = "" } = appointment[0] ?? {}; + const { reason_for_visit = "", slot_id } = appointment[0] ?? {}; return [ { url: `/api/v1/facility/${facilityId}/slots/${slot_id}/create_appointment/`, diff --git a/src/components/Users/UserAvailabilityTab.tsx b/src/components/Users/UserAvailabilityTab.tsx index 868941d3ff3..0f657edc97e 100644 --- a/src/components/Users/UserAvailabilityTab.tsx +++ b/src/components/Users/UserAvailabilityTab.tsx @@ -197,13 +197,14 @@ export default function UserAvailabilityTab({ userData: user }: Props) {

{slot_type === "appointment" && (

- {Math.floor( - getSlotsPerSession( - availability[0]?.start_time ?? "00:00", - availability[0]?.end_time ?? "23:59", - slot_size_in_minutes, - ) ?? 0, - )}{" "} + {availability[0] && + Math.floor( + getSlotsPerSession( + availability[0].start_time, + availability[0].end_time, + slot_size_in_minutes, + ) ?? 0, + )}{" "} slots of {slot_size_in_minutes} mins.

)} @@ -303,7 +304,9 @@ const diagonalStripes = { export const formatAvailabilityTime = ( availability: AvailabilityDateTime[], ) => { - const startTime = availability[0]?.start_time ?? "00:00"; - const endTime = availability[0]?.end_time ?? "23:59"; - return `${formatTimeShort(startTime)} - ${formatTimeShort(endTime)}`; + if (availability[0]) { + const startTime = availability[0].start_time; + const endTime = availability[0].end_time; + return `${formatTimeShort(startTime)} - ${formatTimeShort(endTime)}`; + } }; diff --git a/src/components/ui/input-otp.tsx b/src/components/ui/input-otp.tsx index b870e03e450..9d150705448 100644 --- a/src/components/ui/input-otp.tsx +++ b/src/components/ui/input-otp.tsx @@ -33,8 +33,7 @@ const InputOTPSlot = React.forwardRef< React.ComponentPropsWithoutRef<"div"> & { index: number } >(({ index, className, ...props }, ref) => { const inputOTPContext = React.useContext(OTPInputContext); - const slot = inputOTPContext.slots[index]; - const { char, hasFakeCaret, isActive } = slot ?? {}; + const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index] ?? {}; return (
{ if (history.length > 1) { // Otherwise, navigate to history present in the app navigation history stack. - return navigate(history[1] || fallbackUrl || "/"); + if (history[1]) return navigate(history[1]); } if (fallbackUrl) diff --git a/src/hooks/useFilters.tsx b/src/hooks/useFilters.tsx index 8f80228189c..66a48e9bbc1 100644 --- a/src/hooks/useFilters.tsx +++ b/src/hooks/useFilters.tsx @@ -130,7 +130,10 @@ export default function useFilters({ }, range(name: string, paramKey: string, minKey = "min", maxKey = "max") { const paramKeys = [paramKey + "_" + minKey, paramKey + "_" + maxKey]; - const values = [qParams[paramKeys[0] ?? ""], qParams[paramKeys[1] ?? ""]]; + const values = [ + paramKeys[0] && qParams[paramKeys[0]], + paramKeys[1] && qParams[paramKeys[1]], + ]; if (values[0] === values[1]) return [{ name, value: values[0], paramKey: paramKeys }]; return [name + " " + minKey, name + " " + maxKey].map((name, i) => { diff --git a/src/pages/Appointments/utils.ts b/src/pages/Appointments/utils.ts index 9d10dabc6f8..66fcd6d59f4 100644 --- a/src/pages/Appointments/utils.ts +++ b/src/pages/Appointments/utils.ts @@ -51,12 +51,12 @@ export const groupSlotsByAvailability = (slots: TokenSlot[]) => { ); // sort availability by first slot start time - result.sort((a, b) => - compareAsc( - a.slots[0]?.start_datetime ?? "00:00", - b.slots[0]?.start_datetime ?? "00:00", - ), - ); + result.sort((a, b) => { + if (a.slots[0]?.start_datetime && b.slots[0]?.start_datetime) { + return compareAsc(a.slots[0].start_datetime, b.slots[0].start_datetime); + } + return 0; + }); return result; }; diff --git a/src/pages/Encounters/tabs/EncounterNotesTab.tsx b/src/pages/Encounters/tabs/EncounterNotesTab.tsx index 88cf7db9bac..8cb2b176d3c 100644 --- a/src/pages/Encounters/tabs/EncounterNotesTab.tsx +++ b/src/pages/Encounters/tabs/EncounterNotesTab.tsx @@ -330,8 +330,12 @@ export const EncounterNotesTab = ({ encounter }: EncounterTabProps) => { // Auto-select first thread useEffect(() => { - if (threadsData?.results.length && !selectedThread) { - setSelectedThread(threadsData?.results[0]?.id ?? null); + if ( + threadsData?.results.length && + threadsData.results[0] && + !selectedThread + ) { + setSelectedThread(threadsData.results[0].id); } }, [threadsData, selectedThread]); diff --git a/src/pages/Scheduling/ScheduleTemplates.tsx b/src/pages/Scheduling/ScheduleTemplates.tsx index 909ca0113ec..7877efbf3a0 100644 --- a/src/pages/Scheduling/ScheduleTemplates.tsx +++ b/src/pages/Scheduling/ScheduleTemplates.tsx @@ -125,13 +125,14 @@ const ScheduleTemplateItem = ({ <> | - {Math.floor( - getSlotsPerSession( - slot.availability[0]?.start_time ?? "00:00", - slot.availability[0]?.end_time ?? "23:59", - slot.slot_size_in_minutes, - ) ?? 0, - )}{" "} + {slot.availability[0] && + Math.floor( + getSlotsPerSession( + slot.availability[0].start_time, + slot.availability[0].end_time, + slot.slot_size_in_minutes, + ) ?? 0, + )}{" "} slots of {slot.slot_size_in_minutes} mins. diff --git a/src/pages/Scheduling/components/EditScheduleTemplateSheet.tsx b/src/pages/Scheduling/components/EditScheduleTemplateSheet.tsx index d2fbaf98b7b..0e55eef5bbc 100644 --- a/src/pages/Scheduling/components/EditScheduleTemplateSheet.tsx +++ b/src/pages/Scheduling/components/EditScheduleTemplateSheet.tsx @@ -330,13 +330,15 @@ const AvailabilityEditor = ({ if (availability.slot_type !== "appointment") return { totalSlots: null, tokenDuration: null }; - const slots = Math.floor( - getSlotsPerSession( - availability.availability[0]?.start_time ?? "00:00", - availability.availability[0]?.end_time ?? "23:59", - availability.slot_size_in_minutes, - ) ?? 0, - ); + const slots = + availability.availability[0] && + Math.floor( + getSlotsPerSession( + availability.availability[0].start_time, + availability.availability[0].end_time, + availability.slot_size_in_minutes, + ) ?? 0, + ); const duration = getTokenDuration( availability.slot_size_in_minutes, @@ -432,19 +434,24 @@ const AvailabilityEditor = ({ {t("schedule")}
- {Object.entries(availabilitiesByDay).map(([day, times]) => ( -

- - {(DayOfWeek[parseInt(day)] || "").charAt(0) + - DayOfWeek[parseInt(day)]?.slice(1).toLowerCase()} - - - {times - .map((time) => formatAvailabilityTime([time])) - .join(", ")} - -

- ))} + {Object.entries(availabilitiesByDay).map(([day, times]) => { + const dayofWeek = DayOfWeek[parseInt(day)]; + if (!dayofWeek) return; + const formattedDay = + dayofWeek?.charAt(0) + dayofWeek?.slice(1).toLowerCase(); + return ( +

+ + {formattedDay} + + + {times + .map((time) => formatAvailabilityTime([time])) + .join(", ")} + +

+ ); + })}
From 2a73a3103b7d3ea3bbc3dcc3082ee72af3a7dfb1 Mon Sep 17 00:00:00 2001 From: Rishith25 Date: Sat, 11 Jan 2025 09:36:20 +0530 Subject: [PATCH 10/11] coderabbit changes --- .../Questionnaire/QuestionTypes/DateTimeQuestion.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx b/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx index 122083f913f..2a1a9c15ba4 100644 --- a/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx @@ -55,13 +55,13 @@ export function DateTimeQuestion({ }; const handleTimeChange = (event: React.ChangeEvent) => { - const [hoursStr, minutesStr] = event.target.value.split(":"); + const parts = event.target.value.split(":"); + if (parts.length !== 2) return; + const [hoursStr, minutesStr] = parts; const hours = Number(hoursStr); const minutes = Number(minutesStr); - if (isNaN(hours) || isNaN(minutes)) { - return; - } + if (Number.isNaN(hours) || Number.isNaN(minutes)) return; const date = currentValue || new Date(); date.setHours(hours); From c667672737389cfc5ba58bfa19db999d16321172 Mon Sep 17 00:00:00 2001 From: Rishith25 Date: Sat, 11 Jan 2025 20:56:12 +0530 Subject: [PATCH 11/11] resolved the deploy failed error --- src/Routers/routes/FacilityRoutes.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Routers/routes/FacilityRoutes.tsx b/src/Routers/routes/FacilityRoutes.tsx index 90df37b44c7..39b030186fe 100644 --- a/src/Routers/routes/FacilityRoutes.tsx +++ b/src/Routers/routes/FacilityRoutes.tsx @@ -20,7 +20,7 @@ const FacilityRoutes: AppRoutes = { ), "/facility/:facilityId/users": ({ facilityId }) => ( - + ), "/facility/:facilityId/resource/new": ({ facilityId }) => (