From e4b291ab95fb43f9cc8f400ced3d9176e370e673 Mon Sep 17 00:00:00 2001 From: Jacob John Jeevan <40040905+Jacobjeevan@users.noreply.github.com> Date: Fri, 31 Jan 2025 16:24:25 +0530 Subject: [PATCH 01/21] Dob/Age and Lat/Log Override (#10280) --- src/components/Facility/FacilityForm.tsx | 24 +++++++++++++++---- .../Patient/PatientRegistration.tsx | 8 ++++++- src/components/ui/sidebar/nav-user.tsx | 9 ------- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/components/Facility/FacilityForm.tsx b/src/components/Facility/FacilityForm.tsx index 1aea913355c..09833e2cc6d 100644 --- a/src/components/Facility/FacilityForm.tsx +++ b/src/components/Facility/FacilityForm.tsx @@ -140,7 +140,11 @@ export default function FacilityForm(props: FacilityProps) { data: FacilityFormValues, ) => { if (facilityId) { - updateFacility(data); + updateFacility({ + ...data, + latitude: data.latitude ?? 0, + longitude: data.longitude ?? 0, + }); } else { createFacility(data); } @@ -224,8 +228,12 @@ export default function FacilityForm(props: FacilityProps) { )?.id, address: facilityData.address, phone_number: facilityData.phone_number, - latitude: Number(facilityData.latitude), - longitude: Number(facilityData.longitude), + latitude: facilityData.latitude + ? Number(facilityData.latitude) + : undefined, + longitude: facilityData.longitude + ? Number(facilityData.longitude) + : undefined, is_public: facilityData.is_public, }); } @@ -466,7 +474,10 @@ export default function FacilityForm(props: FacilityProps) { {...field} type="number" onChange={(e) => { - form.setValue("latitude", Number(e.target.value)); + form.setValue( + "latitude", + e.target.value ? Number(e.target.value) : undefined, + ); }} data-cy="facility-latitude" placeholder="Enter latitude" @@ -490,7 +501,10 @@ export default function FacilityForm(props: FacilityProps) { {...field} type="number" onChange={(e) => { - form.setValue("longitude", Number(e.target.value)); + form.setValue( + "longitude", + e.target.value ? Number(e.target.value) : undefined, + ); }} data-cy="facility-longitude" placeholder="Enter longitude" diff --git a/src/components/Patient/PatientRegistration.tsx b/src/components/Patient/PatientRegistration.tsx index 6471b8d4205..7edbffcc9e2 100644 --- a/src/components/Patient/PatientRegistration.tsx +++ b/src/components/Patient/PatientRegistration.tsx @@ -215,7 +215,13 @@ export default function PatientRegistration( function onSubmit(values: z.infer) { if (patientId) { - updatePatient({ ...values, ward_old: undefined }); + updatePatient({ + ...values, + ward_old: undefined, + age: values.age_or_dob === "age" ? values.age : undefined, + date_of_birth: + values.age_or_dob === "dob" ? values.date_of_birth : undefined, + }); return; } diff --git a/src/components/ui/sidebar/nav-user.tsx b/src/components/ui/sidebar/nav-user.tsx index 426ec8b5bee..3508e1beb70 100644 --- a/src/components/ui/sidebar/nav-user.tsx +++ b/src/components/ui/sidebar/nav-user.tsx @@ -191,15 +191,6 @@ export function PatientNavUser() { - - {patient && ( - - - {t("profile")} - - )} - - {t("logout")} From 71439baeebfa373b77f3226a171fdb9be6fcb000 Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Fri, 31 Jan 2025 11:11:13 +0000 Subject: [PATCH 02/21] Remove pin-code autofill feature (#10291) --- .../e2e/facility_spec/facility_creation.cy.ts | 2 + .../pageObject/facility/FacilityCreation.ts | 13 ++- src/Providers/PatientUserProvider.tsx | 15 ++-- src/Utils/permissions.ts | 36 +-------- src/Utils/request/api.tsx | 9 +-- src/Utils/utils.ts | 29 ++++--- src/common/constants.tsx | 22 ----- src/components/Common/FacilitySelect.tsx | 7 +- src/components/Facility/FacilityForm.tsx | 70 +--------------- .../Patient/PatientDetailsTab/Demography.tsx | 44 ---------- .../Patient/PatientRegistration.tsx | 41 ---------- src/components/Users/UserListAndCard.tsx | 14 +--- src/components/Users/models.tsx | 6 -- src/components/ui/sidebar/patient-nav.tsx | 4 +- src/hooks/useStateAndDistrictFromPincode.ts | 79 ------------------ src/pages/Appointments/AppointmentDetail.tsx | 12 +-- src/pages/Encounters/EncounterShow.tsx | 81 ------------------- .../Facility/hooks/useFacilityFilters.ts | 23 ------ src/pages/Patient/Utils.tsx | 20 ----- .../PatientRegistration.tsx | 8 +- .../PublicAppointments/PatientSelect.tsx | 13 ++- src/types/emr/patient.ts | 3 - src/types/scheduling/schedule.ts | 4 +- 23 files changed, 63 insertions(+), 492 deletions(-) delete mode 100644 src/hooks/useStateAndDistrictFromPincode.ts delete mode 100644 src/pages/Facility/hooks/useFacilityFilters.ts diff --git a/cypress/e2e/facility_spec/facility_creation.cy.ts b/cypress/e2e/facility_spec/facility_creation.cy.ts index 430a1c5b40b..28c8dad55ee 100644 --- a/cypress/e2e/facility_spec/facility_creation.cy.ts +++ b/cypress/e2e/facility_spec/facility_creation.cy.ts @@ -3,6 +3,8 @@ import { generatePhoneNumber } from "@/utils/commonUtils"; import { generateFacilityData } from "@/utils/facilityData"; const LOCATION_HIERARCHY = { + state: "Kerala", + district: "Ernakulam", localBody: "Aluva", ward: "4", }; diff --git a/cypress/pageObject/facility/FacilityCreation.ts b/cypress/pageObject/facility/FacilityCreation.ts index 8f7e0edf319..054cb3539e9 100644 --- a/cypress/pageObject/facility/FacilityCreation.ts +++ b/cypress/pageObject/facility/FacilityCreation.ts @@ -126,7 +126,18 @@ export class FacilityCreation { .should("not.be.empty"); } - fillLocationHierarchy(location: { localBody: string; ward: string }) { + fillLocationHierarchy(location: { + state: string; + district: string; + localBody: string; + ward: string; + }) { + cy.typeAndSelectOption('[data-cy="select-state"]', location.state, false); + cy.typeAndSelectOption( + '[data-cy="select-district"]', + location.district, + false, + ); // Don't verify selection for local body (false parameter) cy.typeAndSelectOption( '[data-cy="select-local_body"]', diff --git a/src/Providers/PatientUserProvider.tsx b/src/Providers/PatientUserProvider.tsx index 1ae9a9af8f1..2319d9a2d45 100644 --- a/src/Providers/PatientUserProvider.tsx +++ b/src/Providers/PatientUserProvider.tsx @@ -6,13 +6,13 @@ import { useAuthContext } from "@/hooks/useAuthUser"; import routes from "@/Utils/request/api"; import query from "@/Utils/request/query"; -import { AppointmentPatient } from "@/pages/Patient/Utils"; import { TokenData } from "@/types/auth/otpToken"; +import { Patient } from "@/types/emr/newPatient"; export type PatientUserContextType = { - patients?: AppointmentPatient[]; - selectedPatient: AppointmentPatient | null; - setSelectedPatient: (patient: AppointmentPatient) => void; + patients?: Patient[]; + selectedPatient: Patient | null; + setSelectedPatient: (patient: Patient) => void; tokenData: TokenData; }; @@ -25,9 +25,8 @@ interface Props { } export default function PatientUserProvider({ children }: Props) { - const [patients, setPatients] = useState([]); - const [selectedPatient, setSelectedPatient] = - useState(null); + const [patients, setPatients] = useState([]); + const [selectedPatient, setSelectedPatient] = useState(null); const { patientToken: tokenData } = useAuthContext(); @@ -44,7 +43,7 @@ export default function PatientUserProvider({ children }: Props) { useEffect(() => { if (userData?.results && userData.results.length > 0) { setPatients(userData.results); - const localPatient: AppointmentPatient | undefined = JSON.parse( + const localPatient: Patient | undefined = JSON.parse( localStorage.getItem("selectedPatient") || "{}", ); const selectedPatient = diff --git a/src/Utils/permissions.ts b/src/Utils/permissions.ts index b8b521c758b..9dd82d9c1f6 100644 --- a/src/Utils/permissions.ts +++ b/src/Utils/permissions.ts @@ -2,40 +2,9 @@ import { UserModel } from "@/components/Users/models"; import { UserBase } from "@/types/user/user"; -// To do: Rewrite to check if belongs to same org and in higher -// hierarchy -/* const checkIfStateOrDistrictAdminInSameLocation = ( - authUser: UserBaseModel, - targetUser: UserBaseModel, -) => { - const hasLocation = Boolean( - targetUser.state_object || targetUser.district_object, - ); - - const isStateAdminOfSameState = - authUser.user_type === "StateAdmin" && - targetUser.state_object?.id === authUser.state; - - const isDistrictAdminOfSameDistrict = - authUser.user_type === "DistrictAdmin" && - targetUser.district_object?.id === authUser.district; - - return ( - hasLocation && (isStateAdminOfSameState || isDistrictAdminOfSameDistrict) - ); -}; - */ export const showUserDelete = (authUser: UserModel, targetUser: UserBase) => { // Auth user should be higher in hierarchy than target user // User can't delete their own account - /* if ( - USER_TYPES.indexOf(authUser.user_type) <= - USER_TYPES.indexOf(targetUser.user_type) || - authUser.username === targetUser.username - ) - return false; */ - // To do: check above - //return checkIfStateOrDistrictAdminInSameLocation(authUser, targetUser); if (authUser.username === targetUser.username) return false; return false; }; @@ -55,8 +24,5 @@ export const editUserPermissions = ( authUser: UserModel, targetUser: UserBase, ) => { - if (authUser.username === targetUser.username) return true; - return false; - // To do: check above - //return checkIfStateOrDistrictAdminInSameLocation(authUser, targetUser); + return authUser.username === targetUser.username; }; diff --git a/src/Utils/request/api.tsx b/src/Utils/request/api.tsx index 0e3aab2f217..45eddeedb24 100644 --- a/src/Utils/request/api.tsx +++ b/src/Utils/request/api.tsx @@ -15,10 +15,7 @@ import { } from "@/components/Users/models"; import { PaginatedResponse } from "@/Utils/request/types"; -import { - AppointmentPatient, - AppointmentPatientRegister, -} from "@/pages/Patient/Utils"; +import { AppointmentPatientRegister } from "@/pages/Patient/Utils"; import { Encounter, EncounterEditRequest } from "@/types/emr/encounter"; import { MedicationStatement } from "@/types/emr/medicationStatement"; import { PartialPatientModel, Patient } from "@/types/emr/newPatient"; @@ -625,7 +622,7 @@ const routes = { getPatient: { path: "/api/v1/otp/patient/", method: "GET", - TRes: Type>(), + TRes: Type>(), auth: { key: "Authorization", value: "Bearer {token}", @@ -636,7 +633,7 @@ const routes = { path: "/api/v1/otp/patient/", method: "POST", TBody: Type>(), - TRes: Type(), + TRes: Type(), auth: { key: "Authorization", value: "Bearer {token}", diff --git a/src/Utils/utils.ts b/src/Utils/utils.ts index dbd4119dc7b..add2677343b 100644 --- a/src/Utils/utils.ts +++ b/src/Utils/utils.ts @@ -1,11 +1,14 @@ import { differenceInMinutes, format } from "date-fns"; import { toPng } from "html-to-image"; -import { toast } from "sonner"; import dayjs from "@/Utils/dayjs"; import { Time } from "@/Utils/types"; import { Patient } from "@/types/emr/newPatient"; import { PatientModel } from "@/types/emr/patient"; +import { + Organization, + OrganizationParent, +} from "@/types/organization/organization"; import { Quantity } from "@/types/questionnaire/quantity"; const DATE_FORMAT = "DD/MM/YYYY"; @@ -105,18 +108,6 @@ export const classNames = (...classes: (string | boolean | undefined)[]) => { return classes.filter(Boolean).join(" "); }; -export const getPincodeDetails = async (pincode: string, apiKey: string) => { - const response = await fetch( - `https://api.data.gov.in/resource/6176ee09-3d56-4a3b-8115-21841576b2f6?api-key=${apiKey}&format=json&filters[pincode]=${pincode}&limit=1`, - ); - const data = await response.json(); - if (!data.records || data.records.length === 0) { - toast.error("Invalid pincode"); - return null; - } - return data.records[0]; -}; - export const isUserOnline = (user: { last_login: DateLike }) => { return user.last_login ? dayjs().subtract(5, "minutes").isBefore(user.last_login) @@ -281,3 +272,15 @@ export const conditionalArrayAttribute = ( ) => { return condition ? attributes : []; }; + +export const stringifyGeoOrganization = (org: Organization) => { + const levels: string[] = []; + + let current: OrganizationParent | undefined = org; + while (current?.name) { + levels.push(current.name); + current = current.parent; + } + + return levels.join(", "); +}; diff --git a/src/common/constants.tsx b/src/common/constants.tsx index 820ace57839..ac4db173498 100644 --- a/src/common/constants.tsx +++ b/src/common/constants.tsx @@ -768,25 +768,3 @@ export const PREVIEWABLE_FILE_EXTENSIONS = [ "gif", "webp", ] as const; - -export const HEADER_CONTENT_TYPES = { - pdf: "application/pdf", - txt: "text/plain", - jpeg: "image/jpeg", - jpg: "image/jpeg", - doc: "application/msword", - xls: "application/vnd.ms-excel", - docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", - epub: "application/epub+zip", - gif: "image/gif", - html: "text/html", - htm: "text/html", - mp4: "video/mp4", - png: "image/png", - ppt: "application/vnd.ms-powerpoint", - pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation", - svg: "image/svg+xml", - xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", -} as const; - -export const ADMIN_USER_TYPES = ["DistrictAdmin", "StateAdmin"] as const; diff --git a/src/components/Common/FacilitySelect.tsx b/src/components/Common/FacilitySelect.tsx index 74eb8ac4231..4209de3fc89 100644 --- a/src/components/Common/FacilitySelect.tsx +++ b/src/components/Common/FacilitySelect.tsx @@ -17,8 +17,6 @@ interface BaseFacilitySelectProps { disabled?: boolean; multiple?: boolean; facilityType?: number; - district?: string; - state?: string; showAll?: boolean; showNOptions?: number | undefined; freeText?: boolean; @@ -100,10 +98,7 @@ export const FacilitySelect = ({ onChange={setSelected} fetchData={facilitySearch} showNOptions={showNOptions} - optionLabel={(option: any) => - option.name + - (option.district_object ? `, ${option.district_object.name}` : "") - } + optionLabel={(option: any) => option.name} compareBy="id" className={className} error={errors} diff --git a/src/components/Facility/FacilityForm.tsx b/src/components/Facility/FacilityForm.tsx index 09833e2cc6d..097341b411a 100644 --- a/src/components/Facility/FacilityForm.tsx +++ b/src/components/Facility/FacilityForm.tsx @@ -32,8 +32,6 @@ import { Textarea } from "@/components/ui/textarea"; import { FacilityModel } from "@/components/Facility/models"; -import { useStateAndDistrictFromPincode } from "@/hooks/useStateAndDistrictFromPincode"; - import { FACILITY_FEATURE_TYPES, FACILITY_TYPES } from "@/common/constants"; import { validatePincode } from "@/common/validation"; @@ -44,7 +42,6 @@ import validators from "@/Utils/validators"; import GovtOrganizationSelector from "@/pages/Organization/components/GovtOrganizationSelector"; import { BaseFacility } from "@/types/facility/facility"; import { Organization } from "@/types/organization/organization"; -import organizationApi from "@/types/organization/organizationApi"; interface FacilityProps { organizationId?: string; @@ -52,22 +49,14 @@ interface FacilityProps { onSubmitSuccess?: () => void; } -function extractHierarchyLevels(org: Organization | undefined): Organization[] { - const levels: Organization[] = []; - while (org && org.level_cache >= 0) { - levels.unshift(org as Organization); - org = org.parent as Organization | undefined; - } - return levels; -} - -export default function FacilityForm(props: FacilityProps) { +export default function FacilityForm({ + facilityId, + onSubmitSuccess, +}: FacilityProps) { const { t } = useTranslation(); const queryClient = useQueryClient(); const [isGettingLocation, setIsGettingLocation] = useState(false); - const { facilityId, organizationId, onSubmitSuccess } = props; const [selectedLevels, setSelectedLevels] = useState([]); - const [showAutoFilledPincode, setShowAutoFilledPincode] = useState(false); const facilityFormSchema = z.object({ facility_type: z.string().min(1, t("facility_type_required")), @@ -176,41 +165,6 @@ export default function FacilityForm(props: FacilityProps) { } }; - const { stateOrg, districtOrg } = useStateAndDistrictFromPincode({ - pincode: form.watch("pincode")?.toString() || "", - }); - - const { data: org } = useQuery({ - queryKey: ["organization", organizationId], - queryFn: query(organizationApi.get, { - pathParams: { id: organizationId }, - }), - enabled: !!organizationId && !facilityId, - }); - - useEffect(() => { - if (facilityId) return; - const orgLevels = extractHierarchyLevels(org); - const districtMatch = - districtOrg && orgLevels.some((level) => level.name === districtOrg.name); - const levels: Organization[] = []; - if (districtMatch) return; - if (stateOrg) levels.push(stateOrg); - if (districtOrg) levels.push(districtOrg); - if (!stateOrg && !districtOrg && org) levels.push(org); - - setSelectedLevels(levels); - - if (levels.length == 2) { - setShowAutoFilledPincode(true); - const timer = setTimeout(() => { - setShowAutoFilledPincode(false); - }, 5000); - return () => clearTimeout(timer); - } - return () => setShowAutoFilledPincode(false); - }, [stateOrg, districtOrg, organizationId, facilityId]); - // Update form when facility data is loaded useEffect(() => { if (facilityData) { @@ -375,22 +329,6 @@ export default function FacilityForm(props: FacilityProps) { /> - {showAutoFilledPincode && ( -
-
- )} )} /> diff --git a/src/components/Patient/PatientDetailsTab/Demography.tsx b/src/components/Patient/PatientDetailsTab/Demography.tsx index 466385286be..6a8c9f58927 100644 --- a/src/components/Patient/PatientDetailsTab/Demography.tsx +++ b/src/components/Patient/PatientDetailsTab/Demography.tsx @@ -196,52 +196,8 @@ export const Demography = (props: PatientProps) => { value: patientData.permanent_address, }, ...getGeoOrgDetails(patientData.geo_organization), - - // TODO: Replace with Geo_Org - // { - // label: t("nationality"), - // value: patientData.nationality, - // }, - // { - // label: t("state"), - // value: patientData.state, - // }, - // { - // label: t("district"), - // value: patientData.district_object?.name, - // }, - // { - // label: t("local_body"), - // value: patientData.local_body_object?.name, - // }, - // { - // label: t("ward"), - // value: ( - // <> - // {(patientData.ward_object && - // patientData.ward_object.number + - // ", " + - // patientData.ward_object.name) || - // "-"} - // - // ), - // }, ], }, - // { - // id: "volunteer-contact", - // hidden: !patientData.assigned_to_object, - // details: [ - // , - // ], - // }, ]; return ( diff --git a/src/components/Patient/PatientRegistration.tsx b/src/components/Patient/PatientRegistration.tsx index 7edbffcc9e2..155ecbb85b5 100644 --- a/src/components/Patient/PatientRegistration.tsx +++ b/src/components/Patient/PatientRegistration.tsx @@ -8,7 +8,6 @@ import { isValidPhoneNumber } from "react-phone-number-input"; import { toast } from "sonner"; import { z } from "zod"; -import CareIcon from "@/CAREUI/icons/CareIcon"; import SectionNavigator from "@/CAREUI/misc/SectionNavigator"; import Autocomplete from "@/components/ui/autocomplete"; @@ -42,7 +41,6 @@ import Page from "@/components/Common/Page"; import DuplicatePatientDialog from "@/components/Facility/DuplicatePatientDialog"; import useAppHistory from "@/hooks/useAppHistory"; -import { useStateAndDistrictFromPincode } from "@/hooks/useStateAndDistrictFromPincode"; import { BLOOD_GROUP_CHOICES, // DOMESTIC_HEALTHCARE_SUPPORT_CHOICES, @@ -83,7 +81,6 @@ export default function PatientRegistration( const [suppressDuplicateWarning, setSuppressDuplicateWarning] = useState(!!patientId); const [selectedLevels, setSelectedLevels] = useState([]); - const [showAutoFilledPincode, setShowAutoFilledPincode] = useState(false); const formSchema = useMemo( () => @@ -191,28 +188,6 @@ export default function PatientRegistration( }, }); - const { stateOrg, districtOrg } = useStateAndDistrictFromPincode({ - pincode: form.watch("pincode")?.toString() || "", - }); - - useEffect(() => { - // Fill by pincode for patient registration - if (patientId) return; - const levels: Organization[] = []; - if (stateOrg) levels.push(stateOrg); - if (districtOrg) levels.push(districtOrg); - setSelectedLevels(levels); - - if (levels.length == 2) { - setShowAutoFilledPincode(true); - const timer = setTimeout(() => { - setShowAutoFilledPincode(false); - }, 5000); - return () => clearTimeout(timer); - } - return () => setShowAutoFilledPincode(false); - }, [stateOrg, districtOrg, patientId]); - function onSubmit(values: z.infer) { if (patientId) { updatePatient({ @@ -674,22 +649,6 @@ export default function PatientRegistration( /> - {showAutoFilledPincode && ( -
-
- )} )} /> diff --git a/src/components/Users/UserListAndCard.tsx b/src/components/Users/UserListAndCard.tsx index da6489af294..ee6753c1472 100644 --- a/src/components/Users/UserListAndCard.tsx +++ b/src/components/Users/UserListAndCard.tsx @@ -128,11 +128,7 @@ export const UserGrid = ({ users }: { users?: UserBase[] }) => ( ); -const UserListHeader = ({ - showDistrictColumn, -}: { - showDistrictColumn: boolean; -}) => { +const UserListHeader = () => { const { t } = useTranslation(); return ( @@ -143,9 +139,6 @@ const UserListHeader = ({ {t("status")} {t("role")} {t("contact_number")} - {showDistrictColumn && ( - {t("district")} - )} ); @@ -195,13 +188,10 @@ const UserListRow = ({ user }: { user: UserBase }) => { ); }; export const UserList = ({ users }: { users?: UserBase[] }) => { - const showDistrictColumn = users?.some( - (user) => "district_object" in user || "district" in user, - ); return (
- + {users?.map((user) => )} diff --git a/src/components/Users/models.tsx b/src/components/Users/models.tsx index 43c3f6a2ec3..f7a7307e7f7 100644 --- a/src/components/Users/models.tsx +++ b/src/components/Users/models.tsx @@ -29,9 +29,6 @@ export type UserFacilityModel = { export type UserModel = UserBareMinimum & { external_id: string; - local_body?: number; - district?: number; - state?: number; video_connect_link: string; phone_number?: string; alt_phone_number?: string; @@ -51,9 +48,6 @@ export type UserModel = UserBareMinimum & { }; export interface UserAssignedModel extends UserBareMinimum { - local_body?: number; - district?: number; - state?: number; phone_number?: string; alt_phone_number?: string; video_connect_link: string; diff --git a/src/components/ui/sidebar/patient-nav.tsx b/src/components/ui/sidebar/patient-nav.tsx index bc7c9772fce..823256c49f8 100644 --- a/src/components/ui/sidebar/patient-nav.tsx +++ b/src/components/ui/sidebar/patient-nav.tsx @@ -6,7 +6,7 @@ import { PatientSwitcher } from "@/components/ui/sidebar/patient-switcher"; import { usePatientContext } from "@/hooks/usePatientUser"; -import { AppointmentPatient } from "@/pages/Patient/Utils"; +import { Patient } from "@/types/emr/newPatient"; interface NavigationLink { name: string; @@ -15,7 +15,7 @@ interface NavigationLink { } function generatePatientLinks( - selectedUser: AppointmentPatient | null, + selectedUser: Patient | null, t: TFunction, ): NavigationLink[] { if (!selectedUser) return []; diff --git a/src/hooks/useStateAndDistrictFromPincode.ts b/src/hooks/useStateAndDistrictFromPincode.ts deleted file mode 100644 index 1e8b31f3207..00000000000 --- a/src/hooks/useStateAndDistrictFromPincode.ts +++ /dev/null @@ -1,79 +0,0 @@ -import careConfig from "@careConfig"; -import { useQuery } from "@tanstack/react-query"; -import { t } from "i18next"; -import { useEffect } from "react"; -import { toast } from "sonner"; - -import { useOrganization } from "@/hooks/useOrganization"; - -import { validatePincode } from "@/common/validation"; - -import { getPincodeDetails } from "@/Utils/utils"; - -interface UseStateAndDistrictProps { - pincode: string; -} - -interface PincodeResponse { - statename: string; - districtname: string; -} - -export function useStateAndDistrictFromPincode({ - pincode, -}: UseStateAndDistrictProps) { - const { - data: pincodeDetails, - isLoading: isPincodeLoading, - isError: isPincodeError, - } = useQuery({ - queryKey: ["pincode-details", pincode], - queryFn: () => getPincodeDetails(pincode, careConfig.govDataApiKey), - enabled: pincode !== "" && validatePincode(pincode), - }); - - const stateName = pincodeDetails?.statename; - const districtName = pincodeDetails?.districtname; - - const { - organizations: stateOrgs, - isLoading: isStateLoading, - isError: isStateError, - } = useOrganization({ - orgType: "govt", - parentId: "", - name: stateName, - enabled: !!stateName, - }); - - const stateOrg = stateOrgs?.[0]; - - const { - organizations: districtOrgs, - isLoading: isDistrictLoading, - isError: isDistrictError, - } = useOrganization({ - orgType: "govt", - parentId: stateOrg?.id, - name: districtName, - enabled: !!stateOrg?.id && !!districtName, - }); - - useEffect(() => { - if (isStateError || isPincodeError) { - toast.info(t("pincode_state_auto_fill_error")); - } - if (isDistrictError && !isStateError) { - toast.info(t("pincode_district_auto_fill_error")); - } - }, [isStateError, isPincodeError, isDistrictError]); - - const districtOrg = districtOrgs[0]; - - return { - stateOrg, - districtOrg, - isLoading: isPincodeLoading || isStateLoading || isDistrictLoading, - isError: isPincodeError || isStateError || isDistrictError, - }; -} diff --git a/src/pages/Appointments/AppointmentDetail.tsx b/src/pages/Appointments/AppointmentDetail.tsx index 96d6732d15e..2809c96dbe1 100644 --- a/src/pages/Appointments/AppointmentDetail.tsx +++ b/src/pages/Appointments/AppointmentDetail.tsx @@ -54,6 +54,7 @@ import { formatName, getReadableDuration, saveElementAsImage, + stringifyGeoOrganization, } from "@/Utils/utils"; import { AppointmentTokenCard } from "@/pages/Appointments/components/AppointmentTokenCard"; import { @@ -211,7 +212,7 @@ const AppointmentDetails = ({ appointment: Appointment; facility: FacilityData; }) => { - const { patient, user } = appointment; + const { user } = appointment; const { t } = useTranslation(); return ( @@ -331,14 +332,7 @@ const AppointmentDetails = ({ {appointment.patient.address || t("no_address_provided")}

- {[ - patient.ward, - patient.local_body, - patient.district, - patient.state, - ] - .filter(Boolean) - .join(", ")} + {stringifyGeoOrganization(appointment.patient.geo_organization)}

{t("pincode")}: {appointment.patient.pincode} diff --git a/src/pages/Encounters/EncounterShow.tsx b/src/pages/Encounters/EncounterShow.tsx index f27e4817518..1f065b6e50c 100644 --- a/src/pages/Encounters/EncounterShow.tsx +++ b/src/pages/Encounters/EncounterShow.tsx @@ -56,31 +56,6 @@ export const EncounterShow = (props: Props) => { ...pluginTabs, }; - // if (Object.keys(tabs).includes(tab.toUpperCase())) { - // tab = tab.toUpperCase(); - // } - // const [showDoctors, setShowDoctors] = useState(false); - // const [patientData, setPatientData] = useState(); - // const [activeShiftingData, setActiveShiftingData] = useState>([]); - - // const getPatientGender = (patientData: any) => - // GENDER_TYPES.find((i) => i.id === patientData.gender)?.text; - - // const getPatientAddress = (patientData: any) => - // `${patientData.address},\n${patientData.ward_object?.name},\n${patientData.local_body_object?.name},\n${patientData.district_object?.name},\n${patientData.state_object?.name}`; - - // const getPatientComorbidities = (patientData: any) => { - // if (patientData?.medical_history?.length) { - // return humanizeStrings( - // patientData.medical_history.map((item: any) => item.disease), - // ); - // } else { - // return "None"; - // } - // }; - - // const authUser = useAuthUser(); - const { data: encounterData, isLoading } = useQuery({ queryKey: ["encounter", encounterId], queryFn: query(routes.encounter.get, { @@ -92,62 +67,6 @@ export const EncounterShow = (props: Props) => { enabled: !!encounterId, }); - // const encounterQuery = useTanStackQueryInstead(routes.encounter.get, { - // pathParams: { id: consultationId }, - // }); - - // const consultationData = encounterQuery.data; - // const bedId = consultationData?.current_bed?.bed_object?.id; - - // const isCameraAttached = useTanStackQueryInstead(routes.listAssetBeds, { - // prefetch: !!bedId, - // query: { bed: bedId }, - // }).data?.results.some((a) => a.asset_object.asset_class === "ONVIF"); - - // const patientDataQuery = useTanStackQueryInstead(routes.getPatient, { - // pathParams: { id: consultationQuery.data?.patient ?? "" }, - // prefetch: !!consultationQuery.data?.patient, - // onResponse: ({ data }) => { - // if (!data) { - // return; - // } - // setPatientData({ - // ...data, - // gender: getPatientGender(data), - // address: getPatientAddress(data), - // comorbidities: getPatientComorbidities(data), - // is_declared_positive: data.is_declared_positive ? "Yes" : "No", - // is_vaccinated: patientData?.is_vaccinated ? "Yes" : "No", - // } as any); - // }, - // }); - - // const fetchData = useCallback( - // async (id: string) => { - // // Get shifting data - // const shiftRequestsQuery = await request(routes.listShiftRequests, { - // query: { patient: id }, - // }); - // if (shiftRequestsQuery.data?.results) { - // setActiveShiftingData(shiftRequestsQuery.data.results); - // } - // }, - // [consultationId, patientData?.is_vaccinated], - // ); - - // useEffect(() => { - // const id = patientDataQuery.data?.id; - // if (!id) { - // return; - // } - // fetchData(id); - // triggerGoal("Patient Consultation Viewed", { - // facilityId: facilityId, - // consultationId: consultationId, - // userId: authUser.id, - // }); - // }, [patientDataQuery.data?.id]); - if (isLoading || !encounterData) { return ; } diff --git a/src/pages/Facility/hooks/useFacilityFilters.ts b/src/pages/Facility/hooks/useFacilityFilters.ts deleted file mode 100644 index cb3fae51ff2..00000000000 --- a/src/pages/Facility/hooks/useFacilityFilters.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { useState } from "react"; - -interface Filters { - district: string; - local_body: string; - page: string; - limit: string; - [key: string]: string; -} - -interface Props { - initialFilters: Filters; - qParams: Partial; -} - -export function useFacilityFilters({ initialFilters }: Props) { - const [filters, setFilters] = useState(initialFilters); - - return { - filters, - setFilters, - }; -} diff --git a/src/pages/Patient/Utils.tsx b/src/pages/Patient/Utils.tsx index 68f3ae524a3..76910dffe96 100644 --- a/src/pages/Patient/Utils.tsx +++ b/src/pages/Patient/Utils.tsx @@ -1,5 +1,3 @@ -import { Organization } from "@/types/organization/organization"; - export type AppointmentPatientRegister = { name: string; gender: string; @@ -10,21 +8,3 @@ export type AppointmentPatientRegister = { geo_organization?: string; pincode?: string; }; - -export type AppointmentPatient = { - id: string; - external_id: string; - name: string; - phone_number: string; - emergency_phone_number: string; - address: string; - date_of_birth?: string; - year_of_birth?: string; - state: number; - district: number; - local_body: number; - ward: number; - pincode: number; - gender: string; - geo_organization: Organization; -}; diff --git a/src/pages/PublicAppointments/PatientRegistration.tsx b/src/pages/PublicAppointments/PatientRegistration.tsx index 855e3fe1336..db65c045a48 100644 --- a/src/pages/PublicAppointments/PatientRegistration.tsx +++ b/src/pages/PublicAppointments/PatientRegistration.tsx @@ -33,10 +33,8 @@ import mutate from "@/Utils/request/mutate"; import { HTTPError } from "@/Utils/request/types"; import { dateQueryString } from "@/Utils/utils"; import GovtOrganizationSelector from "@/pages/Organization/components/GovtOrganizationSelector"; -import { - AppointmentPatient, - AppointmentPatientRegister, -} from "@/pages/Patient/Utils"; +import { AppointmentPatientRegister } from "@/pages/Patient/Utils"; +import { Patient } from "@/types/emr/newPatient"; import PublicAppointmentApi from "@/types/scheduling/PublicAppointmentApi"; import { Appointment, @@ -174,7 +172,7 @@ export function PatientRegistration(props: PatientRegistrationProps) { Authorization: `Bearer ${tokenData.token}`, }, })(body), - onSuccess: (data: AppointmentPatient) => { + onSuccess: (data: Patient) => { toast.success(t("patient_created_successfully")); publish("patient:upsert", data); createAppointment({ diff --git a/src/pages/PublicAppointments/PatientSelect.tsx b/src/pages/PublicAppointments/PatientSelect.tsx index 75c8422c8ba..0385c3ffd4f 100644 --- a/src/pages/PublicAppointments/PatientSelect.tsx +++ b/src/pages/PublicAppointments/PatientSelect.tsx @@ -14,8 +14,7 @@ import { usePatientContext } from "@/hooks/usePatientUser"; import routes from "@/Utils/request/api"; import mutate from "@/Utils/request/mutate"; import query from "@/Utils/request/query"; -import { PaginatedResponse } from "@/Utils/request/types"; -import { AppointmentPatient } from "@/pages/Patient/Utils"; +import { Patient } from "@/types/emr/newPatient"; import PublicAppointmentApi from "@/types/scheduling/PublicAppointmentApi"; import { Appointment, @@ -55,9 +54,7 @@ export default function PatientSelect({ ); } - const { data: patientData, isLoading } = useQuery< - PaginatedResponse - >({ + const { data: patientData, isLoading } = useQuery({ queryKey: ["otp-patient"], queryFn: query(routes.otp.getPatient, { headers: { @@ -106,11 +103,11 @@ export default function PatientSelect({ ); }; - const getPatienDoBorAge = (patient: AppointmentPatient) => { + const getPatienDoBorAge = (patient: Patient) => { if (patient.date_of_birth) { return dayjs(patient.date_of_birth).format("DD MMM YYYY"); } - const yearOfBirth = parseInt(patient.year_of_birth ?? ""); + const yearOfBirth = patient.year_of_birth; const age = dayjs().year() - yearOfBirth; return `${age} years`; }; @@ -178,7 +175,7 @@ export default function PatientSelect({ {patient.phone_number}

- {getPatienDoBorAge(patient as AppointmentPatient)} + {getPatienDoBorAge(patient)} {t(`GENDER__${patient.gender}`)} diff --git a/src/types/emr/patient.ts b/src/types/emr/patient.ts index eebe4b9e305..0724dd45eb5 100644 --- a/src/types/emr/patient.ts +++ b/src/types/emr/patient.ts @@ -56,9 +56,6 @@ export interface PatientModel { transit_details?: string; present_health?: string; has_SARI?: boolean; - local_body?: number; - district?: number; - state?: number; nationality?: string; passport_no?: string; ration_card_category?: (typeof RATION_CARD_CATEGORY)[number] | null; diff --git a/src/types/scheduling/schedule.ts b/src/types/scheduling/schedule.ts index 62fe2793a3c..cc895624513 100644 --- a/src/types/scheduling/schedule.ts +++ b/src/types/scheduling/schedule.ts @@ -1,7 +1,7 @@ import { DayOfWeek } from "@/CAREUI/interactive/WeekdayCheckbox"; import { Time } from "@/Utils/types"; -import { AppointmentPatient } from "@/pages/Patient/Utils"; +import { Patient } from "@/types/emr/newPatient"; import { FacilityBareMinimum } from "@/types/facility/facility"; import { UserBase } from "@/types/user/user"; @@ -140,7 +140,7 @@ export type AppointmentStatus = (typeof AppointmentStatuses)[number]; export interface Appointment { id: string; token_slot: TokenSlot; - patient: AppointmentPatient; + patient: Patient; booked_on: string; status: AppointmentNonCancelledStatus; reason_for_visit: string; From c9a3764cff58d21915c605637097ab1cc3896faf Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Fri, 31 Jan 2025 11:11:26 +0000 Subject: [PATCH 03/21] fix responsiveness of date field and gender in public patient registration form (#10294) --- src/components/ui/date-field.tsx | 15 +++++------ .../PatientRegistration.tsx | 25 +++++++++++++------ 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/components/ui/date-field.tsx b/src/components/ui/date-field.tsx index bd1506184f1..daeff36be5f 100644 --- a/src/components/ui/date-field.tsx +++ b/src/components/ui/date-field.tsx @@ -102,8 +102,8 @@ export default function DateField({ return (
-
- +
+
-
- +
+
-
- +
+
diff --git a/src/pages/PublicAppointments/PatientRegistration.tsx b/src/pages/PublicAppointments/PatientRegistration.tsx index db65c045a48..1571cbd06fc 100644 --- a/src/pages/PublicAppointments/PatientRegistration.tsx +++ b/src/pages/PublicAppointments/PatientRegistration.tsx @@ -265,19 +265,30 @@ export function PatientRegistration(props: PatientRegistrationProps) { control={form.control} name="gender" render={({ field }) => ( - + {t("sex")} {GENDER_TYPES.map((g) => ( - - - - + + + + + + {t(`GENDER__${g.id}`)} + + ))} From 4694c21d3023a56d13a3f0d7bd432ab5d3318dfc Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Fri, 31 Jan 2025 11:11:41 +0000 Subject: [PATCH 04/21] Make autocompletes mobile friendly (#10336) --- index.html | 2 +- .../Questionnaire/ValueSetSelect.tsx | 35 +++++- src/components/ui/autocomplete.tsx | 111 ++++++++++++------ 3 files changed, 110 insertions(+), 38 deletions(-) diff --git a/index.html b/index.html index 1a7a6c5abe5..d4a02a4d6eb 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ %REACT_APP_TITLE% diff --git a/src/components/Questionnaire/ValueSetSelect.tsx b/src/components/Questionnaire/ValueSetSelect.tsx index c2a018be9f2..e3bfa1b25bc 100644 --- a/src/components/Questionnaire/ValueSetSelect.tsx +++ b/src/components/Questionnaire/ValueSetSelect.tsx @@ -1,3 +1,4 @@ +import { CaretSortIcon } from "@radix-ui/react-icons"; import { useQuery } from "@tanstack/react-query"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -7,6 +8,7 @@ import { cn } from "@/lib/utils"; import { Button } from "@/components/ui/button"; import { Command, + CommandDialog, CommandEmpty, CommandGroup, CommandInput, @@ -19,6 +21,8 @@ import { PopoverTrigger, } from "@/components/ui/popover"; +import useBreakpoints from "@/hooks/useBreakpoints"; + import routes from "@/Utils/request/api"; import query from "@/Utils/request/query"; import { Code, ValueSetSystem } from "@/types/questionnaire/code"; @@ -51,6 +55,7 @@ export default function ValueSetSelect({ const { t } = useTranslation(); const [internalOpen, setInternalOpen] = useState(false); const [search, setSearch] = useState(""); + const isMobile = useBreakpoints({ default: true, sm: false }); const searchQuery = useQuery({ queryKey: ["valueset", system, "expand", count, search], @@ -103,6 +108,33 @@ export default function ValueSetSelect({ ); + + if (isMobile && !hideTrigger) { + return ( + <> + + + {content} + + + ); + } + return ( - {value?.display || placeholder} + {value?.display || placeholder} + )} diff --git a/src/components/ui/autocomplete.tsx b/src/components/ui/autocomplete.tsx index 46265446533..e9b4942d3b5 100644 --- a/src/components/ui/autocomplete.tsx +++ b/src/components/ui/autocomplete.tsx @@ -6,6 +6,7 @@ import { cn } from "@/lib/utils"; import { Button } from "@/components/ui/button"; import { Command, + CommandDialog, CommandEmpty, CommandGroup, CommandInput, @@ -18,6 +19,8 @@ import { PopoverTrigger, } from "@/components/ui/popover"; +import useBreakpoints from "@/hooks/useBreakpoints"; + interface AutoCompleteOption { label: string; value: string; @@ -49,6 +52,77 @@ export default function Autocomplete({ "data-cy": dataCy, }: AutocompleteProps) { const [open, setOpen] = React.useState(false); + const isMobile = useBreakpoints({ default: true, sm: false }); + + const commandContent = ( + <> + + + {noOptionsMessage} + + {options.map((option) => ( + { + const currentValue = + options.find( + (option) => option.label.toLowerCase() === v.toLowerCase(), + )?.value || ""; + onChange(currentValue === value ? "" : currentValue); + setOpen(false); + }} + > + + {option.label} + + ))} + + + + ); + + if (isMobile) { + return ( + <> + + + {commandContent} + + + ); + } return ( @@ -78,42 +152,7 @@ export default function Autocomplete({ className="sm:w-full p-0 pointer-events-auto w-[var(--radix-popover-trigger-width)]" align={align} > - - - - {noOptionsMessage} - - {options.map((option) => ( - { - const currentValue = - options.find( - (option) => - option.label.toLowerCase() === v.toLowerCase(), - )?.value || ""; - onChange(currentValue === value ? "" : currentValue); - setOpen(false); - }} - > - - {option.label} - - ))} - - - + {commandContent} ); From a7fca70a811303e4b11180ba705c70d8a57546fb Mon Sep 17 00:00:00 2001 From: Bodhish Thomas Date: Fri, 31 Jan 2025 16:56:32 +0530 Subject: [PATCH 05/21] Add empty parent parameter to location and organization list queries --- src/pages/Facility/settings/locations/LocationList.tsx | 1 + .../settings/organizations/FacilityOrganizationIndex.tsx | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/pages/Facility/settings/locations/LocationList.tsx b/src/pages/Facility/settings/locations/LocationList.tsx index 5b20c8b2451..7b56e9ac929 100644 --- a/src/pages/Facility/settings/locations/LocationList.tsx +++ b/src/pages/Facility/settings/locations/LocationList.tsx @@ -40,6 +40,7 @@ export default function LocationList({ facilityId }: Props) { queryFn: query.debounced(locationApi.list, { pathParams: { facility_id: facilityId }, queryParams: { + parent: "", offset: (page - 1) * limit, limit, name: searchQuery || undefined, diff --git a/src/pages/Facility/settings/organizations/FacilityOrganizationIndex.tsx b/src/pages/Facility/settings/organizations/FacilityOrganizationIndex.tsx index a9a70b48598..7c7d9dec2ae 100644 --- a/src/pages/Facility/settings/organizations/FacilityOrganizationIndex.tsx +++ b/src/pages/Facility/settings/organizations/FacilityOrganizationIndex.tsx @@ -34,6 +34,9 @@ export default function FacilityOrganizationIndex({ queryKey: ["facilityOrganization", "list", facilityId], queryFn: query(routes.facilityOrganization.list, { pathParams: { facilityId }, + queryParams: { + parent: "", + }, }), enabled: !!facilityId, }); From db359748d57def09082ea3ccdc9387c154df196c Mon Sep 17 00:00:00 2001 From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> Date: Fri, 31 Jan 2025 17:10:02 +0530 Subject: [PATCH 06/21] removed hard corded values in the appointments (#10337) --- src/pages/Appointments/AppointmentsPage.tsx | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/pages/Appointments/AppointmentsPage.tsx b/src/pages/Appointments/AppointmentsPage.tsx index 6a78b24ceb5..6b939f54fac 100644 --- a/src/pages/Appointments/AppointmentsPage.tsx +++ b/src/pages/Appointments/AppointmentsPage.tsx @@ -839,18 +839,9 @@ function AppointmentRow(props: { {t("patient")} - - {t("room_apt")} - {t("consulting_doctor")} - - {t("labels")} - - - {t("triage_category")} - {t("current_status")} @@ -912,18 +903,9 @@ function AppointmentRowItem({ {/* TODO: Replace with relevant information */} - -

{"Need Room Information"}

-
{formatDisplayName(appointment.user)} - -

{"Need Labels"}

-
- -

{"Need Triage Category"}

-
Date: Fri, 31 Jan 2025 17:26:47 +0530 Subject: [PATCH 07/21] Refactor location list views with reusable LocationCard component --- .../settings/locations/LocationList.tsx | 71 +-------- .../settings/locations/LocationView.tsx | 78 +--------- .../locations/components/LocationCard.tsx | 145 ++++++++++++++++++ 3 files changed, 158 insertions(+), 136 deletions(-) create mode 100644 src/pages/Facility/settings/locations/components/LocationCard.tsx diff --git a/src/pages/Facility/settings/locations/LocationList.tsx b/src/pages/Facility/settings/locations/LocationList.tsx index 7b56e9ac929..4cb04e934ee 100644 --- a/src/pages/Facility/settings/locations/LocationList.tsx +++ b/src/pages/Facility/settings/locations/LocationList.tsx @@ -1,11 +1,9 @@ import { useQuery } from "@tanstack/react-query"; -import { Link } from "raviger"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import CareIcon from "@/CAREUI/icons/CareIcon"; -import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; @@ -14,13 +12,11 @@ import Pagination from "@/components/Common/Pagination"; import { CardGridSkeleton } from "@/components/Common/SkeletonLoading"; import query from "@/Utils/request/query"; -import { - LocationList as LocationListType, - getLocationFormLabel, -} from "@/types/location/location"; +import { LocationList as LocationListType } from "@/types/location/location"; import locationApi from "@/types/location/locationApi"; import LocationSheet from "./LocationSheet"; +import { LocationCard } from "./components/LocationCard"; interface Props { facilityId: string; @@ -95,64 +91,11 @@ export default function LocationList({ facilityId }: Props) {
{data?.results?.length ? ( data.results.map((location: LocationListType) => ( - - -
-
-
-
-
-

- {location.name} -

- -
-
- - {getLocationFormLabel(location.form)} - - - {location.status} - - - {location.availability_status} - -
-
-
-
-
- -
-
-
-
+ )) ) : ( diff --git a/src/pages/Facility/settings/locations/LocationView.tsx b/src/pages/Facility/settings/locations/LocationView.tsx index 52cffb87388..d5527d5fe4f 100644 --- a/src/pages/Facility/settings/locations/LocationView.tsx +++ b/src/pages/Facility/settings/locations/LocationView.tsx @@ -1,5 +1,4 @@ import { useQuery, useQueryClient } from "@tanstack/react-query"; -import { Link } from "raviger"; import { useState } from "react"; import { useTranslation } from "react-i18next"; @@ -20,6 +19,7 @@ import { LocationList, getLocationFormLabel } from "@/types/location/location"; import locationApi from "@/types/location/locationApi"; import LocationSheet from "./LocationSheet"; +import { LocationCard } from "./components/LocationCard"; interface Props { id: string; @@ -159,77 +159,11 @@ export default function LocationView({ id, facilityId }: Props) {
{children?.results?.length ? ( children.results.map((childLocation: LocationList) => ( - - -
-
-
-

- {childLocation.name} -

-
- - {childLocation.form.toUpperCase()} - - - {childLocation.status} - - - {childLocation.availability_status} - -
-
-
- - -
-
- {childLocation.description && ( -

- {childLocation.description} -

- )} - {childLocation.has_children && ( -
- - {t("has_child_locations")} -
- )} -
-
-
+ )) ) : ( diff --git a/src/pages/Facility/settings/locations/components/LocationCard.tsx b/src/pages/Facility/settings/locations/components/LocationCard.tsx new file mode 100644 index 00000000000..60a427a4945 --- /dev/null +++ b/src/pages/Facility/settings/locations/components/LocationCard.tsx @@ -0,0 +1,145 @@ +import { + Bed, + Building, + Building2, + Car, + ChevronRight, + Eye, + Folder, + FolderOpen, + Home, + Hospital, + Map, + PenLine, +} from "lucide-react"; +import { Link } from "raviger"; +import { useTranslation } from "react-i18next"; + +import { cn } from "@/lib/utils"; + +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Card } from "@/components/ui/card"; + +import { LocationList, getLocationFormLabel } from "@/types/location/location"; + +interface Props { + location: LocationList; + onEdit?: (location: LocationList) => void; + className?: string; +} + +export function LocationCard({ location, onEdit, className }: Props) { + const { t } = useTranslation(); + + const getLocationTypeIcon = (form: string) => { + switch (form.toLowerCase()) { + case "bd": // bed + return ; + case "wa": // ward + return ; + case "lvl": // level/floor + return ; + case "bu": // building + return ; + case "si": // site + return ; + case "wi": // wing + return ; + case "co": // corridor + return ; + case "ro": // room + return ; + case "ve": // vehicle + return ; + case "ho": // house + return ; + case "ca": // carpark + return ; + case "rd": // road + return ; + case "area": // area + return ; + case "jdn": // garden + return ; + case "vi": // virtual + return ; + default: + return ; + } + }; + + return ( + +
+
+
+
+ {getLocationTypeIcon(location.form)} +
+ +
+

+ {location.name} +

+

+ {getLocationFormLabel(location.form)} +

+ +
+ + {location.status} + + + {location.availability_status} + + {location.has_children && ( + + + {t("has_child_locations")} + + )} +
+
+ + {onEdit && ( + + )} +
+
+ +
+
+ +
+
+
+
+ ); +} From 55d5790722ab33e312f6feed29d16b218e045c92 Mon Sep 17 00:00:00 2001 From: G O Ashwin Praveen <143274955+ashwinpraveengo@users.noreply.github.com> Date: Fri, 31 Jan 2025 17:37:21 +0530 Subject: [PATCH 08/21] fix: Align and format cards in Health Profile (#10298) --- public/locale/en.json | 2 ++ src/components/Patient/MedicationStatementList.tsx | 4 ++-- src/components/Patient/allergy/list.tsx | 2 +- src/components/Patient/diagnosis/list.tsx | 4 +++- src/components/Patient/symptoms/list.tsx | 4 +++- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/public/locale/en.json b/public/locale/en.json index 470fc7b31ca..161a1140fd5 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -1323,6 +1323,7 @@ "no_country_found": "No country found", "no_data_found": "No data found", "no_departments_teams_found": "No Departments or Teams found", + "no_diagnoses_recorded": "No diagnoses recorded", "no_doctors_found": "No Doctors Found", "no_duplicate_facility": "You should not create duplicate facilities", "no_encounters_found": "No encounters found", @@ -1373,6 +1374,7 @@ "no_social_profile_details_available": "No Social Profile Details Available", "no_staff": "No staff found", "no_sub_organizations_found": "No sub-organizations found", + "no_symptoms_recorded": "No symptoms recorded", "no_tags_found": "No tags found", "no_tags_selected": "No tags selected", "no_tests_taken": "No tests taken", diff --git a/src/components/Patient/MedicationStatementList.tsx b/src/components/Patient/MedicationStatementList.tsx index 9d2549eb3ba..495b8ee4904 100644 --- a/src/components/Patient/MedicationStatementList.tsx +++ b/src/components/Patient/MedicationStatementList.tsx @@ -139,10 +139,10 @@ export function MedicationStatementList({ if (!filteredMedications?.length) { return ( - + {t("ongoing_medications")} - +

{t("no_ongoing_medications")}

diff --git a/src/components/Patient/allergy/list.tsx b/src/components/Patient/allergy/list.tsx index 8e1a9686a90..c255b1e490f 100644 --- a/src/components/Patient/allergy/list.tsx +++ b/src/components/Patient/allergy/list.tsx @@ -74,7 +74,7 @@ export function AllergyList({ patientId={patientId} encounterId={encounterId} > - +

{t("no_allergies_recorded")}

diff --git a/src/components/Patient/diagnosis/list.tsx b/src/components/Patient/diagnosis/list.tsx index d0e8c4acede..10d3a9d2d5d 100644 --- a/src/components/Patient/diagnosis/list.tsx +++ b/src/components/Patient/diagnosis/list.tsx @@ -63,7 +63,9 @@ export function DiagnosisList({ patientId={patientId} encounterId={encounterId} > -

{t("no_diagnoses_recorded")}

+ +

{t("no_diagnoses_recorded")}

+
); } diff --git a/src/components/Patient/symptoms/list.tsx b/src/components/Patient/symptoms/list.tsx index 24f7a8142c8..5034364e078 100644 --- a/src/components/Patient/symptoms/list.tsx +++ b/src/components/Patient/symptoms/list.tsx @@ -62,7 +62,9 @@ export function SymptomsList({ patientId={patientId} encounterId={encounterId} > -

{t("no_symptoms_recorded")}

+ +

{t("no_symptoms_recorded")}

+
); } From 2298ed5be9f7f3c89a4663c6d288ee8e8479f733 Mon Sep 17 00:00:00 2001 From: Raj kumar <150310085+rajku-dev@users.noreply.github.com> Date: Fri, 31 Jan 2025 17:40:28 +0530 Subject: [PATCH 09/21] Fix Camera Capture and Upload Workflow (#10326) --- src/components/Files/CameraCaptureDialog.tsx | 10 +++++++++- src/components/Files/FilesTab.tsx | 8 ++++++-- src/hooks/useFileUpload.tsx | 5 +++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/components/Files/CameraCaptureDialog.tsx b/src/components/Files/CameraCaptureDialog.tsx index cfbaff19dab..54b9debc21e 100644 --- a/src/components/Files/CameraCaptureDialog.tsx +++ b/src/components/Files/CameraCaptureDialog.tsx @@ -16,10 +16,11 @@ export interface CameraCaptureDialogProps { onHide: () => void; onCapture: (file: File, fileName: string) => void; onResetCapture: () => void; + setPreview?: (isPreview: boolean) => void; } export default function CameraCaptureDialog(props: CameraCaptureDialogProps) { - const { show, onHide, onCapture, onResetCapture } = props; + const { show, onHide, onCapture, onResetCapture, setPreview } = props; const isLaptopScreen = useBreakpoints({ lg: true, default: false }); const [cameraFacingMode, setCameraFacingMode] = useState( @@ -149,6 +150,7 @@ export default function CameraCaptureDialog(props: CameraCaptureDialogProps) { variant="primary" onClick={() => { captureImage(); + setPreview?.(true); }} className="m-2" > @@ -164,6 +166,7 @@ export default function CameraCaptureDialog(props: CameraCaptureDialogProps) { onClick={() => { setPreviewImage(null); onResetCapture(); + setPreview?.(false); }} className="m-2" > @@ -174,6 +177,7 @@ export default function CameraCaptureDialog(props: CameraCaptureDialogProps) { onClick={() => { setPreviewImage(null); onHide(); + setPreview?.(false); }} className="m-2" > @@ -215,6 +219,7 @@ export default function CameraCaptureDialog(props: CameraCaptureDialogProps) { variant="primary" onClick={() => { captureImage(); + setPreview?.(true); }} > @@ -230,6 +235,7 @@ export default function CameraCaptureDialog(props: CameraCaptureDialogProps) { onClick={() => { setPreviewImage(null); onResetCapture(); + setPreview?.(false); }} > {t("retake")} @@ -239,6 +245,7 @@ export default function CameraCaptureDialog(props: CameraCaptureDialogProps) { onClick={() => { onHide(); setPreviewImage(null); + setPreview?.(false); }} > {t("submit")} @@ -254,6 +261,7 @@ export default function CameraCaptureDialog(props: CameraCaptureDialogProps) { setPreviewImage(null); onResetCapture(); onHide(); + setPreview?.(false); }} > {`${t("close")} ${t("camera")}`} diff --git a/src/components/Files/FilesTab.tsx b/src/components/Files/FilesTab.tsx index e3797c79ea4..8a3078ae2ec 100644 --- a/src/components/Files/FilesTab.tsx +++ b/src/components/Files/FilesTab.tsx @@ -157,12 +157,16 @@ export const FilesTab = (props: FilesTabProps) => { }); useEffect(() => { - if (fileUpload.files.length > 0 && fileUpload.files[0] !== undefined) { + if ( + fileUpload.files.length > 0 && + fileUpload.files[0] !== undefined && + !fileUpload.previewing + ) { setOpenUploadDialog(true); } else { setOpenUploadDialog(false); } - }, [fileUpload.files]); + }, [fileUpload.files, fileUpload.previewing]); useEffect(() => { if (!openUploadDialog) { diff --git a/src/hooks/useFileUpload.tsx b/src/hooks/useFileUpload.tsx index 04128a169a3..0cf0ac09fd8 100644 --- a/src/hooks/useFileUpload.tsx +++ b/src/hooks/useFileUpload.tsx @@ -61,6 +61,7 @@ export type FileUploadReturn = { removeFile: (index: number) => void; clearFiles: () => void; uploading: boolean; + previewing?: boolean; }; // Array of image extensions @@ -92,6 +93,7 @@ export default function useFileUpload( const [cameraModalOpen, setCameraModalOpen] = useState(false); const [audioModalOpen, setAudioModalOpen] = useState(false); const [uploading, setUploading] = useState(false); + const [previewing, setPreviewing] = useState(false); const [files, setFiles] = useState([]); const queryClient = useQueryClient(); @@ -285,6 +287,7 @@ export default function useFileUpload( setFiles(errors); setUploadFileNames(errors?.map((f) => f.name) ?? []); setError(t("file_error__network")); + setCameraModalOpen(false); }; const clearFiles = () => { @@ -302,6 +305,7 @@ export default function useFileUpload( setFiles((prev) => [...prev, file]); }} onResetCapture={clearFiles} + setPreview={setPreviewing} /> Date: Fri, 31 Jan 2025 17:59:44 +0530 Subject: [PATCH 10/21] Fix: Resource Letter printing issue (#10230) * fix resource letter print crash * add TFunction * Empty-Commit * created new print comp for resource letter * replace classNames with cn * rm data from top * Empty-Commit * Empty-Commit * Empty-Commit --- src/CAREUI/misc/PrintPreview.tsx | 6 +- src/Routers/routes/ResourceRoutes.tsx | 2 + .../Resource/PrintResourceLetter.tsx | 129 ++++++++++++++++ src/components/Resource/ResourceDetails.tsx | 142 ++---------------- src/style/index.css | 3 + 5 files changed, 147 insertions(+), 135 deletions(-) create mode 100644 src/components/Resource/PrintResourceLetter.tsx diff --git a/src/CAREUI/misc/PrintPreview.tsx b/src/CAREUI/misc/PrintPreview.tsx index c34c75f3299..3479b6a0347 100644 --- a/src/CAREUI/misc/PrintPreview.tsx +++ b/src/CAREUI/misc/PrintPreview.tsx @@ -1,6 +1,8 @@ import { ReactNode } from "react"; import { useTranslation } from "react-i18next"; +import { cn } from "@/lib/utils"; + import CareIcon from "@/CAREUI/icons/CareIcon"; import { ZoomControls, @@ -14,8 +16,6 @@ import Page from "@/components/Common/Page"; import useBreakpoints from "@/hooks/useBreakpoints"; -import { classNames } from "@/Utils/utils"; - type Props = { children: ReactNode; disabled?: boolean; @@ -41,7 +41,7 @@ export default function PrintPreview(props: Props) {
{props.children}
diff --git a/src/Routers/routes/ResourceRoutes.tsx b/src/Routers/routes/ResourceRoutes.tsx index 357b7812513..cdd39b91213 100644 --- a/src/Routers/routes/ResourceRoutes.tsx +++ b/src/Routers/routes/ResourceRoutes.tsx @@ -1,4 +1,5 @@ import View from "@/components/Common/View"; +import PrintResourceLetter from "@/components/Resource/PrintResourceLetter"; import BoardView from "@/components/Resource/ResourceBoard"; import ResourceDetails from "@/components/Resource/ResourceDetails"; import { ResourceDetailsUpdate } from "@/components/Resource/ResourceDetailsUpdate"; @@ -10,6 +11,7 @@ const ResourceRoutes: AppRoutes = { "/resource": () => , "/resource/:id": ({ id }) => , "/resource/:id/update": ({ id }) => , + "/resource/:id/print": ({ id }) => , }; export default ResourceRoutes; diff --git a/src/components/Resource/PrintResourceLetter.tsx b/src/components/Resource/PrintResourceLetter.tsx new file mode 100644 index 00000000000..bc1a80f72a8 --- /dev/null +++ b/src/components/Resource/PrintResourceLetter.tsx @@ -0,0 +1,129 @@ +import { useQuery } from "@tanstack/react-query"; +import { useTranslation } from "react-i18next"; + +import PrintPreview from "@/CAREUI/misc/PrintPreview"; + +import Loading from "@/components/Common/Loading"; + +import { RESOURCE_CATEGORY_CHOICES } from "@/common/constants"; + +import routes from "@/Utils/request/api"; +import query from "@/Utils/request/query"; +import { formatDateTime, formatName } from "@/Utils/utils"; + +export default function PrintResourceLetter({ id }: { id: string }) { + const { t } = useTranslation(); + + const { data, isLoading } = useQuery({ + queryKey: ["resource_request_letter", id], + queryFn: query(routes.getResourceDetails, { + pathParams: { id: id }, + }), + }); + + if (isLoading || !data) { + return ; + } + return ( + +
+
+ {/* Header */} +
+
{t("request_letter")}
+
+ {t("reference_no")}: {data.id} +
+
+ + {/* Date */} +
+
+ {t("date")}: {formatDateTime(data.created_date)} +
+
+ + {/* From Address */} +
+
{t("From")}:
+
{data.origin_facility.name}
+
+ + {/* Subject Line */} +
+
+ {t("subject")}: {t("request_for")} {data.title} +
+
+ + {/* Main Content */} +
+

+ {t("request_the_following_resource")} + {data.emergency ? t("on_emergency_basis") : ""}: +

+ +
+
+ {t("request_title")}:{" "} + {data.title} +
+
+ {t("category")}:{" "} + {RESOURCE_CATEGORY_CHOICES.find( + (item) => item.id === data.category, + )?.text || "--"} +
+
+ {t("quantity_required")}:{" "} + {data.requested_quantity} +
+
+ + {t("reason_for_request")}: + +

{data.reason || "--"}

+
+
+ + {/* Status Section */} +
+ {t("current_status")}: + + {data.status} + +
+
+ + {/* Signature Section */} +
+
+
+
{t("requested_by")}:
+
{formatName(data.created_by)}
+
+ {formatDateTime(data.created_date)} +
+
+
+ + {data.status !== "PENDING" && ( +
+
+
+ {data.status === "REJECTED" ? t("rejected") : t("approved")}{" "} + {t("by")}: +
+
{formatName(data.updated_by)}
+
+ {formatDateTime(data.modified_date)} +
+
+
+ )} +
+
+
+
+ ); +} diff --git a/src/components/Resource/ResourceDetails.tsx b/src/components/Resource/ResourceDetails.tsx index 8308935f197..6a0af2c62a8 100644 --- a/src/components/Resource/ResourceDetails.tsx +++ b/src/components/Resource/ResourceDetails.tsx @@ -1,5 +1,5 @@ +import { useQuery } from "@tanstack/react-query"; import { navigate } from "raviger"; -import { useState } from "react"; import { useTranslation } from "react-i18next"; import CareIcon from "@/CAREUI/icons/CareIcon"; @@ -17,10 +17,9 @@ import CommentSection from "@/components/Resource/ResourceCommentSection"; import { RESOURCE_CATEGORY_CHOICES } from "@/common/constants"; import routes from "@/Utils/request/api"; -import useTanStackQueryInstead from "@/Utils/request/useQuery"; +import query from "@/Utils/request/query"; import { formatDateTime, formatName } from "@/Utils/utils"; import { PatientModel } from "@/types/emr/patient"; -import { ResourceRequest } from "@/types/resourceRequest/resourceRequest"; function PatientCard({ patient }: { patient: PatientModel }) { const { t } = useTranslation(); @@ -103,119 +102,17 @@ function FacilityCard({ ); } -const RequestLetter = (data: ResourceRequest) => { - const { t } = useTranslation(); - return ( -
-
- {/* Header */} -
-
{t("request_letter")}
-
- {t("reference_no")}: {data.id} -
-
- - {/* Date */} -
-
- {t("date")}: {formatDateTime(data.created_date)} -
-
- - {/* From Address */} -
-
{t("from")}:
-
{data.origin_facility.name}
-
- - {/* Subject Line */} -
-
- {t("subject")}: {t("request_for")} {data.title} -
-
- - {/* Main Content */} -
-

- {t("request_the_following_resource")} - {data.emergency ? t("on_emergency_basis") : ""}: -

- -
-
- {t("request_title")}:{" "} - {data.title} -
-
- {t("category")}:{" "} - {RESOURCE_CATEGORY_CHOICES.find( - (item) => item.id === data.category, - )?.text || "--"} -
-
- {t("quantity_required")}:{" "} - {data.requested_quantity} -
-
- {t("reason_for_request")}: -

{data.reason || "--"}

-
-
- - {/* Status Section */} -
- {t("current_status")}: - {data.status} -
-
- - {/* Signature Section */} -
-
-
-
{t("requested_by")}:
-
{formatName(data.created_by)}
-
- {formatDateTime(data.created_date)} -
-
-
- - {data.status !== "PENDING" && ( -
-
-
- {data.status === "REJECTED" ? t("rejected") : t("approved")} - {t("by")}: -
-
{formatName(data.updated_by)}
-
- {formatDateTime(data.modified_date)} -
-
-
- )} -
-
-
- ); -}; - export default function ResourceDetails(props: { id: string }) { - const [isPrintMode, setIsPrintMode] = useState(false); const { t } = useTranslation(); - const { data, loading } = useTanStackQueryInstead(routes.getResourceDetails, { - pathParams: { id: props.id }, - onResponse: ({ res, data }) => { - if (!res && !data) { - navigate("/not-found"); - } - }, + + const { data, isLoading } = useQuery({ + queryKey: ["resource_request", props.id], + queryFn: query(routes.getResourceDetails, { + pathParams: { id: props.id }, + }), }); - if (loading || !data) { + if (isLoading || !data) { return ; } @@ -230,7 +127,7 @@ export default function ResourceDetails(props: { id: string }) {
- - {/* Print Mode */} - {isPrintMode && ( -
-
-
- - -
- {RequestLetter(data)} -
-
- )} ); } diff --git a/src/style/index.css b/src/style/index.css index a779daf3e88..2f14f673a18 100644 --- a/src/style/index.css +++ b/src/style/index.css @@ -431,6 +431,9 @@ button:disabled, } @media print { + @page { + margin-top: 0; + } body * { visibility: hidden; } From 7b6165286f1ec06349dce71b4422ee65221cf0ed Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Fri, 31 Jan 2025 12:38:29 +0000 Subject: [PATCH 11/21] Remove index-based numbering from appointments table row (#10338) Fixes #10307 --- src/components/Patient/PatientDetailsTab/Appointments.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/Patient/PatientDetailsTab/Appointments.tsx b/src/components/Patient/PatientDetailsTab/Appointments.tsx index 8b6228c4125..069d2f0d070 100644 --- a/src/components/Patient/PatientDetailsTab/Appointments.tsx +++ b/src/components/Patient/PatientDetailsTab/Appointments.tsx @@ -93,10 +93,9 @@ export const Appointments = (props: PatientProps) => { ) : appointments.length ? ( - appointments.map((appointment, i) => ( + appointments.map((appointment) => ( - {i + 1} {appointment.token_slot.availability.name} From 46caeffd3d5168a3939b5f4513ad90f0cbb4c4fb Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Fri, 31 Jan 2025 18:48:53 +0530 Subject: [PATCH 12/21] Patient Updates Tab, Structured responses filter by Encounter (#10329) --- public/locale/en.json | 1 + .../Common/Charts/ObservationChart.tsx | 4 +- .../Common/Charts/ObservationHistoryTable.tsx | 4 +- .../Common/ComboboxQuantityInput.tsx | 2 +- .../Common/SearchByMultipleFields.tsx | 2 +- .../Encounter/CreateEncounterForm.tsx | 2 +- .../ConsultationDetails/ObservationsList.tsx | 14 +- .../QuestionnaireResponseView.tsx | 10 +- .../QuestionnaireResponsesList.tsx | 367 +++++++++++------- src/components/Facility/FacilityForm.tsx | 2 +- src/components/Facility/FacilityHome.tsx | 2 +- .../Medicine/MedicationRequestTable/index.tsx | 10 +- src/components/Medicine/MedicationsTable.tsx | 2 +- .../Patient/LinkDepartmentsSheet.tsx | 4 +- .../Patient/MedicationStatementList.tsx | 2 +- .../PatientDetailsTab/Appointments.tsx | 8 +- .../Patient/PatientDetailsTab/Demography.tsx | 6 +- .../PatientDetailsTab/EncounterHistory.tsx | 6 +- .../HealthProfileSummary.tsx | 14 +- .../PatientDetailsTab/PatientUsers.tsx | 12 +- .../PatientDetailsTab/ResourceRequests.tsx | 8 +- .../Patient/PatientDetailsTab/index.tsx | 5 +- .../PatientDetailsTab/patientUpdates.tsx | 10 +- src/components/Patient/PatientHome.tsx | 2 +- src/components/Patient/PatientIndex.tsx | 6 +- src/components/Patient/PatientInfoCard.tsx | 10 +- .../Patient/allergy/AllergyTable.tsx | 4 +- src/components/Patient/allergy/list.tsx | 3 +- src/components/Patient/diagnosis/list.tsx | 2 +- src/components/Patient/symptoms/list.tsx | 2 +- .../Questionnaire/CloneQuestionnaireSheet.tsx | 4 +- .../ManageQuestionnaireOrganizationsSheet.tsx | 4 +- .../ManageQuestionnaireTagsSheet.tsx | 4 +- .../QuestionTypes/AppointmentQuestion.tsx | 2 +- .../QuestionTypes/DateTimeQuestion.tsx | 2 +- .../QuestionTypes/DiagnosisQuestion.tsx | 3 + .../MedicationRequestQuestion.tsx | 3 + .../MedicationStatementQuestion.tsx | 3 + .../QuestionTypes/QuestionGroup.tsx | 4 +- .../QuestionTypes/QuestionInput.tsx | 40 +- .../QuestionTypes/SymptomQuestion.tsx | 3 + .../Questionnaire/QuestionnaireEditor.tsx | 16 +- .../Questionnaire/QuestionnaireForm.tsx | 4 +- .../Questionnaire/QuestionnaireSearch.tsx | 6 +- src/components/Resource/ResourceCreate.tsx | 6 +- src/components/Resource/ResourceDetails.tsx | 24 +- src/components/ui/chart.tsx | 2 +- src/components/ui/date-picker.tsx | 2 +- src/components/ui/date-range-picker.tsx | 2 +- src/components/ui/date-time-picker.tsx | 2 +- src/components/ui/textarea.tsx | 2 +- src/pages/Encounters/EncounterList.tsx | 2 +- src/pages/Encounters/PrintPrescription.tsx | 4 +- .../Encounters/tabs/EncounterUpdatesTab.tsx | 5 +- src/pages/Facility/FacilitiesPage.tsx | 4 +- src/pages/Facility/FacilityDetailsPage.tsx | 2 +- .../Facility/components/FacilityCard.tsx | 2 +- src/pages/Facility/components/UserCard.tsx | 6 +- .../FacilityOrganizationIndex.tsx | 2 +- src/pages/Organization/OrganizationIndex.tsx | 2 +- src/pages/Patients/VerifyPatient.tsx | 4 +- .../PublicAppointments/PatientSelect.tsx | 4 +- src/pages/PublicAppointments/Schedule.tsx | 6 +- src/pages/UserDashboard.tsx | 10 +- 64 files changed, 409 insertions(+), 308 deletions(-) diff --git a/public/locale/en.json b/public/locale/en.json index 161a1140fd5..1768903d45f 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -1047,6 +1047,7 @@ "has_domestic_healthcare_support": "Has domestic healthcare support?", "has_sari": "Has SARI (Severe Acute Respiratory illness)?", "health-profile": "Health Profile", + "health_profile": "Health Profile", "hearing": "We are hearing you...", "help_confirmed": "There is sufficient diagnostic and/or clinical evidence to treat this as a confirmed condition.", "help_differential": "One of a set of potential (and typically mutually exclusive) diagnoses asserted to further guide the diagnostic process and preliminary treatment.", diff --git a/src/components/Common/Charts/ObservationChart.tsx b/src/components/Common/Charts/ObservationChart.tsx index d210255a181..cb892d834ff 100644 --- a/src/components/Common/Charts/ObservationChart.tsx +++ b/src/components/Common/Charts/ObservationChart.tsx @@ -152,7 +152,7 @@ export const ObservationVisualizer = ({ {codeGroups.map((group, index) => (
No data available @@ -365,7 +365,7 @@ export const ObservationVisualizer = ({ details.note && (
{code.display}: diff --git a/src/components/Common/Charts/ObservationHistoryTable.tsx b/src/components/Common/Charts/ObservationHistoryTable.tsx index 240bfea2790..4a8fcee44d4 100644 --- a/src/components/Common/Charts/ObservationHistoryTable.tsx +++ b/src/components/Common/Charts/ObservationHistoryTable.tsx @@ -92,7 +92,7 @@ export const ObservationHistoryTable = ({ if (!data?.pages[0]?.results.length) { return ( -
+
No data available
); @@ -134,7 +134,7 @@ export const ObservationHistoryTable = ({ {name}
- + {observation.note} diff --git a/src/components/Common/ComboboxQuantityInput.tsx b/src/components/Common/ComboboxQuantityInput.tsx index 19674422d81..e28b246118e 100644 --- a/src/components/Common/ComboboxQuantityInput.tsx +++ b/src/components/Common/ComboboxQuantityInput.tsx @@ -120,7 +120,7 @@ export function ComboboxQuantityInput({ autoFocus={autoFocus} /> {selectedUnit && ( -
+
{selectedUnit.display}
)} diff --git a/src/components/Common/SearchByMultipleFields.tsx b/src/components/Common/SearchByMultipleFields.tsx index 531f5caf1b7..242266ae23e 100644 --- a/src/components/Common/SearchByMultipleFields.tsx +++ b/src/components/Common/SearchByMultipleFields.tsx @@ -365,7 +365,7 @@ const SearchByMultipleFields: React.FC = ({
diff --git a/src/components/Patient/PatientDetailsTab/ResourceRequests.tsx b/src/components/Patient/PatientDetailsTab/ResourceRequests.tsx index 0df4ec5b404..8180bd75bcd 100644 --- a/src/components/Patient/PatientDetailsTab/ResourceRequests.tsx +++ b/src/components/Patient/PatientDetailsTab/ResourceRequests.tsx @@ -25,17 +25,17 @@ import { ResourceRequest } from "@/types/resourceRequest/resourceRequest"; import { PatientProps } from "."; export const ResourceRequests = (props: PatientProps) => { - const { patientData, facilityId, id } = props; + const { patientData, facilityId, patientId } = props; const { t } = useTranslation(); const { data: resourceRequests, isLoading: loading } = useQuery({ - queryKey: ["resourceRequests", id], + queryKey: ["resourceRequests", patientId], queryFn: query(routes.listResourceRequests, { queryParams: { - related_patient: id, + related_patient: patientId, }, }), - enabled: !!id, + enabled: !!patientId, }); const getStatusBadge = (status: ResourceRequest["status"]) => { diff --git a/src/components/Patient/PatientDetailsTab/index.tsx b/src/components/Patient/PatientDetailsTab/index.tsx index c6bf06c8ce6..8e7de28b091 100644 --- a/src/components/Patient/PatientDetailsTab/index.tsx +++ b/src/components/Patient/PatientDetailsTab/index.tsx @@ -1,3 +1,4 @@ +import QuestionnaireResponsesList from "@/components/Facility/ConsultationDetails/QuestionnaireResponsesList"; import EncounterHistory from "@/components/Patient/PatientDetailsTab//EncounterHistory"; import { HealthProfileSummary } from "@/components/Patient/PatientDetailsTab//HealthProfileSummary"; import { Demography } from "@/components/Patient/PatientDetailsTab/Demography"; @@ -12,7 +13,7 @@ import { ResourceRequests } from "./ResourceRequests"; export interface PatientProps { facilityId: string; - id: string; + patientId: string; patientData: Patient; } @@ -66,7 +67,7 @@ export const facilityPatientTabs = [ }, { route: "updates", - component: Updates, + component: QuestionnaireResponsesList, }, { route: "resource_requests", diff --git a/src/components/Patient/PatientDetailsTab/patientUpdates.tsx b/src/components/Patient/PatientDetailsTab/patientUpdates.tsx index baabad49ed9..f82f1489fb5 100644 --- a/src/components/Patient/PatientDetailsTab/patientUpdates.tsx +++ b/src/components/Patient/PatientDetailsTab/patientUpdates.tsx @@ -16,7 +16,7 @@ import { QuestionnaireResponse } from "@/types/questionnaire/questionnaireRespon import { PatientProps } from "."; export const Updates = (props: PatientProps) => { - const { facilityId, id: patientId } = props; + const { facilityId, patientId } = props; const { t } = useTranslation(); return ( @@ -42,7 +42,7 @@ export const Updates = (props: PatientProps) => {
-
+
{t("no_update_available")}
@@ -63,7 +63,7 @@ export const Updates = (props: PatientProps) => {

@@ -72,11 +72,11 @@ export const Updates = (props: PatientProps) => { item.structured_responses, )}

-
+
{formatDateTime(item.created_date)}
-
+
by {item.created_by?.first_name || ""}{" "} {item.created_by?.last_name || ""} {` (${item.created_by?.user_type})`} diff --git a/src/components/Patient/PatientHome.tsx b/src/components/Patient/PatientHome.tsx index 373494a4a3f..e3b8e0b28d8 100644 --- a/src/components/Patient/PatientHome.tsx +++ b/src/components/Patient/PatientHome.tsx @@ -134,7 +134,7 @@ export const PatientHome = (props: { {Tab && ( )} diff --git a/src/components/Patient/PatientIndex.tsx b/src/components/Patient/PatientIndex.tsx index 20d5c345c23..e2c753e96df 100644 --- a/src/components/Patient/PatientIndex.tsx +++ b/src/components/Patient/PatientIndex.tsx @@ -140,9 +140,7 @@ export default function PatientIndex({ facilityId }: { facilityId: string }) {

{t("search_patients")}

-

- {t("search_patient_page_text")} -

+

{t("search_patient_page_text")}

@@ -168,7 +166,7 @@ export default function PatientIndex({ facilityId }: { facilityId: string }) {

{t("no_patient_record_found")}

-

+

{t("no_patient_record_text")}

diff --git a/src/components/Patient/PatientInfoCard.tsx b/src/components/Patient/PatientInfoCard.tsx index 4ec59158b5f..84e3336a15e 100644 --- a/src/components/Patient/PatientInfoCard.tsx +++ b/src/components/Patient/PatientInfoCard.tsx @@ -119,7 +119,7 @@ export default function PatientInfoCard(props: PatientInfoCardProps) {
- + Start Date @@ -129,7 +129,7 @@ export default function PatientInfoCard(props: PatientInfoCardProps) {
- + End Date @@ -140,7 +140,7 @@ export default function PatientInfoCard(props: PatientInfoCardProps) {
{props.encounter.external_identifier && (
- + Hospital Identifier @@ -186,7 +186,7 @@ export default function PatientInfoCard(props: PatientInfoCardProps) { key={index} className="flex items-center gap-2 text-sm" > - + {formatDateTime(history.moved_at)} @@ -227,7 +227,7 @@ export default function PatientInfoCard(props: PatientInfoCardProps) { key={index} className="flex items-center gap-2 text-sm" > - + {formatDateTime(history.moved_at)} diff --git a/src/components/Patient/allergy/AllergyTable.tsx b/src/components/Patient/allergy/AllergyTable.tsx index 2d5fc8f84be..8aaf982a91c 100644 --- a/src/components/Patient/allergy/AllergyTable.tsx +++ b/src/components/Patient/allergy/AllergyTable.tsx @@ -95,9 +95,7 @@ export function AllergyTable({ {allergy.note && ( -
- Notes -
+
Notes
{allergy.note}
diff --git a/src/components/Patient/allergy/list.tsx b/src/components/Patient/allergy/list.tsx index c255b1e490f..a4a91bae6a1 100644 --- a/src/components/Patient/allergy/list.tsx +++ b/src/components/Patient/allergy/list.tsx @@ -40,7 +40,6 @@ export function AllergyList({ queryKey: ["allergies", patientId, encounterId], queryFn: query(allergyIntoleranceApi.getAllergy, { pathParams: { patientId }, - queryParams: encounterId ? { encounter: encounterId } : undefined, }), }); @@ -75,7 +74,7 @@ export function AllergyList({ encounterId={encounterId} > -

{t("no_allergies_recorded")}

+

{t("no_allergies_recorded")}

); diff --git a/src/components/Patient/diagnosis/list.tsx b/src/components/Patient/diagnosis/list.tsx index 10d3a9d2d5d..40ae25b3faf 100644 --- a/src/components/Patient/diagnosis/list.tsx +++ b/src/components/Patient/diagnosis/list.tsx @@ -64,7 +64,7 @@ export function DiagnosisList({ encounterId={encounterId} > -

{t("no_diagnoses_recorded")}

+

{t("no_diagnoses_recorded")}

); diff --git a/src/components/Patient/symptoms/list.tsx b/src/components/Patient/symptoms/list.tsx index 5034364e078..d095b851330 100644 --- a/src/components/Patient/symptoms/list.tsx +++ b/src/components/Patient/symptoms/list.tsx @@ -63,7 +63,7 @@ export function SymptomsList({ encounterId={encounterId} > -

{t("no_symptoms_recorded")}

+

{t("no_symptoms_recorded")}

); diff --git a/src/components/Questionnaire/CloneQuestionnaireSheet.tsx b/src/components/Questionnaire/CloneQuestionnaireSheet.tsx index 9b95c751731..3a61ce1910a 100644 --- a/src/components/Questionnaire/CloneQuestionnaireSheet.tsx +++ b/src/components/Questionnaire/CloneQuestionnaireSheet.tsx @@ -147,7 +147,7 @@ export default function CloneQuestionnaireSheet({ )) ) : ( -

+

No organizations selected

)} @@ -180,7 +180,7 @@ export default function CloneQuestionnaireSheet({ {org.name} {org.description && ( - + - {org.description} )} diff --git a/src/components/Questionnaire/ManageQuestionnaireOrganizationsSheet.tsx b/src/components/Questionnaire/ManageQuestionnaireOrganizationsSheet.tsx index 22c589dbb87..8d405641b04 100644 --- a/src/components/Questionnaire/ManageQuestionnaireOrganizationsSheet.tsx +++ b/src/components/Questionnaire/ManageQuestionnaireOrganizationsSheet.tsx @@ -152,7 +152,7 @@ export default function ManageQuestionnaireOrganizationsSheet({ {!isLoading && (!selectedOrganizations || selectedOrganizations.length === 0) && ( -

+

{t("no_organizations_selected")}

)} @@ -185,7 +185,7 @@ export default function ManageQuestionnaireOrganizationsSheet({ {org.name} {org.description && ( - + - {org.description} )} diff --git a/src/components/Questionnaire/ManageQuestionnaireTagsSheet.tsx b/src/components/Questionnaire/ManageQuestionnaireTagsSheet.tsx index 6f7918d2214..0ace0998366 100644 --- a/src/components/Questionnaire/ManageQuestionnaireTagsSheet.tsx +++ b/src/components/Questionnaire/ManageQuestionnaireTagsSheet.tsx @@ -175,9 +175,7 @@ export default function ManageQuestionnaireTagsSheet({ ))} {!isLoading && (!selectedTags || selectedTags.length === 0) && ( -

- {t("no_tags_selected")} -

+

{t("no_tags_selected")}

)}
diff --git a/src/components/Questionnaire/QuestionTypes/AppointmentQuestion.tsx b/src/components/Questionnaire/QuestionTypes/AppointmentQuestion.tsx index 7f30558df4f..ee9174f00e7 100644 --- a/src/components/Questionnaire/QuestionTypes/AppointmentQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/AppointmentQuestion.tsx @@ -150,7 +150,7 @@ export function AppointmentQuestion({ slotsQuery.data.results.length === 0) && selectedDate && resource ? ( -
+
{t("no_slots_available")}
) : ( diff --git a/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx b/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx index 9fa2e201157..b8aafb2e1df 100644 --- a/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/DateTimeQuestion.tsx @@ -99,7 +99,7 @@ export function DateTimeQuestion({ variant="outline" className={cn( "flex-1 justify-start text-left font-normal", - !currentValue && "text-muted-foreground", + !currentValue && "text-gray-500", classes, )} disabled={disabled} diff --git a/src/components/Questionnaire/QuestionTypes/DiagnosisQuestion.tsx b/src/components/Questionnaire/QuestionTypes/DiagnosisQuestion.tsx index b4aab2c07c4..f40485d97c0 100644 --- a/src/components/Questionnaire/QuestionTypes/DiagnosisQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/DiagnosisQuestion.tsx @@ -46,6 +46,7 @@ import { interface DiagnosisQuestionProps { patientId: string; + encounterId: string; questionnaireResponse: QuestionnaireResponse; updateQuestionnaireResponseCB: ( values: ResponseValue[], @@ -84,6 +85,7 @@ function convertToDiagnosisRequest(diagnosis: Diagnosis): DiagnosisRequest { export function DiagnosisQuestion({ patientId, + encounterId, questionnaireResponse, updateQuestionnaireResponseCB, disabled, @@ -96,6 +98,7 @@ export function DiagnosisQuestion({ queryFn: query(diagnosisApi.listDiagnosis, { pathParams: { patientId }, queryParams: { + encounter: encounterId, limit: 100, }, }), diff --git a/src/components/Questionnaire/QuestionTypes/MedicationRequestQuestion.tsx b/src/components/Questionnaire/QuestionTypes/MedicationRequestQuestion.tsx index fb2fb85fd54..f9ff069f431 100644 --- a/src/components/Questionnaire/QuestionTypes/MedicationRequestQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/MedicationRequestQuestion.tsx @@ -78,6 +78,7 @@ interface MedicationRequestQuestionProps { note?: string, ) => void; disabled?: boolean; + encounterId: string; } export function MedicationRequestQuestion({ @@ -85,6 +86,7 @@ export function MedicationRequestQuestion({ updateQuestionnaireResponseCB, disabled, patientId, + encounterId, }: MedicationRequestQuestionProps) { const medications = (questionnaireResponse.values?.[0]?.value as MedicationRequest[]) || []; @@ -94,6 +96,7 @@ export function MedicationRequestQuestion({ queryFn: query(medicationRequestApi.list, { pathParams: { patientId }, queryParams: { + encounter: encounterId, limit: 100, }, }), diff --git a/src/components/Questionnaire/QuestionTypes/MedicationStatementQuestion.tsx b/src/components/Questionnaire/QuestionTypes/MedicationStatementQuestion.tsx index 936a2b3b0b3..f56be1b82dc 100644 --- a/src/components/Questionnaire/QuestionTypes/MedicationStatementQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/MedicationStatementQuestion.tsx @@ -61,6 +61,7 @@ import { Question } from "@/types/questionnaire/question"; interface MedicationStatementQuestionProps { patientId: string; + encounterId: string; question: Question; questionnaireResponse: QuestionnaireResponse; updateQuestionnaireResponseCB: ( @@ -90,6 +91,7 @@ export function MedicationStatementQuestion({ updateQuestionnaireResponseCB, disabled, patientId, + encounterId, }: MedicationStatementQuestionProps) { const { t } = useTranslation(); const desktopLayout = useBreakpoints({ lg: true, default: false }); @@ -110,6 +112,7 @@ export function MedicationStatementQuestion({ pathParams: { patientId }, queryParams: { limit: 100, + encounter: encounterId, }, }), }); diff --git a/src/components/Questionnaire/QuestionTypes/QuestionGroup.tsx b/src/components/Questionnaire/QuestionTypes/QuestionGroup.tsx index aeb8704b699..d38be63abcb 100644 --- a/src/components/Questionnaire/QuestionTypes/QuestionGroup.tsx +++ b/src/components/Questionnaire/QuestionTypes/QuestionGroup.tsx @@ -130,9 +130,7 @@ export const QuestionGroup = memo(function QuestionGroup({
{question.description && ( -

- {question.description} -

+

{question.description}

)}
)} diff --git a/src/components/Questionnaire/QuestionTypes/QuestionInput.tsx b/src/components/Questionnaire/QuestionTypes/QuestionInput.tsx index 16957d63c68..deec52da280 100644 --- a/src/components/Questionnaire/QuestionTypes/QuestionInput.tsx +++ b/src/components/Questionnaire/QuestionTypes/QuestionInput.tsx @@ -115,15 +115,45 @@ export function QuestionInput({ case "structured": switch (question.structured_type) { case "medication_request": - return ; + if (encounterId) { + return ( + + ); + } + return null; case "medication_statement": - return ; + if (encounterId) { + return ( + + ); + } + return null; case "allergy_intolerance": return ; case "symptom": - return ; + if (encounterId) { + return ( + + ); + } + return null; case "diagnosis": - return ; + if (encounterId) { + return ( + + ); + } + return null; case "appointment": return ; case "encounter": @@ -131,8 +161,8 @@ export function QuestionInput({ return ( ); } diff --git a/src/components/Questionnaire/QuestionTypes/SymptomQuestion.tsx b/src/components/Questionnaire/QuestionTypes/SymptomQuestion.tsx index 94eba927251..0a175ae9219 100644 --- a/src/components/Questionnaire/QuestionTypes/SymptomQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/SymptomQuestion.tsx @@ -47,6 +47,7 @@ import { interface SymptomQuestionProps { patientId: string; + encounterId: string; questionnaireResponse: QuestionnaireResponse; updateQuestionnaireResponseCB: ( values: ResponseValue[], @@ -281,6 +282,7 @@ export function SymptomQuestion({ questionnaireResponse, updateQuestionnaireResponseCB, disabled, + encounterId, }: SymptomQuestionProps) { const symptoms = (questionnaireResponse.values?.[0]?.value as SymptomRequest[]) || []; @@ -291,6 +293,7 @@ export function SymptomQuestion({ pathParams: { patientId }, queryParams: { limit: 100, + encounter: encounterId, }, }), }); diff --git a/src/components/Questionnaire/QuestionnaireEditor.tsx b/src/components/Questionnaire/QuestionnaireEditor.tsx index ada4383307f..22f4a701058 100644 --- a/src/components/Questionnaire/QuestionnaireEditor.tsx +++ b/src/components/Questionnaire/QuestionnaireEditor.tsx @@ -154,9 +154,7 @@ export default function QuestionnaireEditor({ id }: QuestionnaireEditorProps) {

Edit Questionnaire

-

- {questionnaire.description} -

+

{questionnaire.description}

@@ -348,7 +348,7 @@ export default function ResourceCreate(props: ResourceProps) {

{t("contact_information")}

-

+

{t("contact_information_description")}

diff --git a/src/components/Resource/ResourceDetails.tsx b/src/components/Resource/ResourceDetails.tsx index 6a0af2c62a8..e73bcbb657e 100644 --- a/src/components/Resource/ResourceDetails.tsx +++ b/src/components/Resource/ResourceDetails.tsx @@ -37,7 +37,7 @@ function PatientCard({ patient }: { patient: PatientModel }) {

{t("name")}

-

{patient.name}

+

{patient.name}

@@ -60,12 +60,12 @@ function PatientCard({ patient }: { patient: PatientModel }) {
) : ( -

--

+

--

)}

{t("address")}

-

+

{[patient.address].filter(Boolean).join(", ") || "--"}

@@ -92,7 +92,7 @@ function FacilityCard({

{t("name")}

-

+

{facilityData?.name || "--"}

@@ -162,7 +162,7 @@ export default function ResourceDetails(props: { id: string }) {

{t("category")}

-

+

{RESOURCE_CATEGORY_CHOICES.find( (item) => item.id === data.category, )?.text || "--"} @@ -170,7 +170,7 @@ export default function ResourceDetails(props: { id: string }) {

{t("contact_person")}

-

+

{data.referring_facility_contact_name || "--"}

@@ -194,7 +194,7 @@ export default function ResourceDetails(props: { id: string }) {
) : ( -

--

+

--

)}
@@ -203,7 +203,7 @@ export default function ResourceDetails(props: { id: string }) {

{t("reason")}

-

+

{data.reason || "--"}

@@ -237,20 +237,20 @@ export default function ResourceDetails(props: { id: string }) { {data.created_by && (

{t("created_by")}

-

+

{formatName(data.created_by)}

-

+

{formatDateTime(data.created_date)}

)}

{t("last_modified_by")}

-

+

{formatName(data.updated_by)}

-

+

{formatDateTime(data.modified_date)}

diff --git a/src/components/ui/chart.tsx b/src/components/ui/chart.tsx index 11a65a13e9d..6ff21377000 100644 --- a/src/components/ui/chart.tsx +++ b/src/components/ui/chart.tsx @@ -50,7 +50,7 @@ const ChartContainer = React.forwardRef< data-chart={chartId} ref={ref} className={cn( - "flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none", + "flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-gray-500 [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none", className, )} {...props} diff --git a/src/components/ui/date-picker.tsx b/src/components/ui/date-picker.tsx index 32d23132362..e8c5587fe2e 100644 --- a/src/components/ui/date-picker.tsx +++ b/src/components/ui/date-picker.tsx @@ -29,7 +29,7 @@ export function DatePicker({ date, onChange, disabled }: DatePickerProps) { variant="outline" className={cn( "w-full justify-start text-left font-normal", - !date && "text-muted-foreground", + !date && "text-gray-500", )} > diff --git a/src/components/ui/date-range-picker.tsx b/src/components/ui/date-range-picker.tsx index 18e467c58b0..ffbbf482bce 100644 --- a/src/components/ui/date-range-picker.tsx +++ b/src/components/ui/date-range-picker.tsx @@ -37,7 +37,7 @@ export function DateRangePicker({ variant={"outline"} className={cn( "justify-center text-left font-normal", - !date && "text-muted-foreground", + !date && "text-gray-500", )} > diff --git a/src/components/ui/date-time-picker.tsx b/src/components/ui/date-time-picker.tsx index 26c93552596..4603f606434 100644 --- a/src/components/ui/date-time-picker.tsx +++ b/src/components/ui/date-time-picker.tsx @@ -68,7 +68,7 @@ export function DateTimePicker({ variant="outline" className={cn( "w-full justify-start text-left font-normal", - !value && "text-muted-foreground", + !value && "text-gray-500", )} > diff --git a/src/components/ui/textarea.tsx b/src/components/ui/textarea.tsx index 9deb3cf02ec..cb3d1045e6c 100644 --- a/src/components/ui/textarea.tsx +++ b/src/components/ui/textarea.tsx @@ -9,7 +9,7 @@ const Textarea = React.forwardRef< return (