Skip to content

Commit

Permalink
Merge branch 'develop' into dual-valueset-field-medication
Browse files Browse the repository at this point in the history
  • Loading branch information
amjithtitus09 authored Jan 17, 2025
2 parents 91dcf55 + bef340f commit 74c4c8d
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 50 deletions.
2 changes: 0 additions & 2 deletions cypress/e2e/patient_spec/patient_creation.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ describe("Patient Management", () => {
dateOfBirth: "01-01-1990",
address: generateAddress(),
pincode: "682001",
state: "Kerala",
district: "Ernakulam",
localBody: "Aluva",
ward: "4",
};
Expand Down
14 changes: 0 additions & 14 deletions cypress/pageObject/Patients/PatientCreation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ interface PatientFormData {
bloodGroup: string;
address: string;
pincode: string;
state: string;
district: string;
localBody: string;
ward: string;
}
Expand Down Expand Up @@ -106,22 +104,10 @@ export class PatientCreation {
.enterDateOfBirth(patient.dateOfBirth)
.enterAddress(patient.address)
.enterPincode(patient.pincode)
.selectState(patient.state)
.selectDistrict(patient.district)
.selectLocalBody(patient.localBody)
.selectWard(patient.ward);
}

selectState(state: string) {
cy.typeAndSelectOption('[data-cy="select-state"]', state);
return this;
}

selectDistrict(district: string) {
cy.typeAndSelectOption('[data-cy="select-district"]', district);
return this;
}

selectLocalBody(localBody: string) {
cy.typeAndSelectOption('[data-cy="select-local_body"]', localBody);
return this;
Expand Down
2 changes: 1 addition & 1 deletion src/CAREUI/interactive/WeekdayCheckbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default function WeekdayCheckbox({
<Button
key={dow}
type="button"
variant={isSelected ? "outline_primary" : "outline"}
variant={isSelected ? "primary" : "outline"}
onClick={() => handleDayToggle(dow)}
size={format === "alphabet" ? "icon" : "default"}
aria-pressed={isSelected}
Expand Down
12 changes: 8 additions & 4 deletions src/components/ErrorPages/DefaultErrorPage.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Link } from "raviger";
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";

import { Button } from "../ui/button";

type ErrorType = "PAGE_NOT_FOUND" | "PAGE_LOAD_ERROR" | "CUSTOM_ERROR";

interface ErrorPageProps {
Expand Down Expand Up @@ -54,12 +55,15 @@ export default function ErrorPage({
{message}
<br />
<br />
<Link
href="/"
<Button
onClick={() =>
// Refresh the Page
window.location.reload()
}
className="inline-block rounded-lg bg-primary-600 px-4 py-2 text-white hover:bg-primary-700 hover:text-white"
>
{t("return_to_care")}
</Link>
</Button>
</p>
</div>
</div>
Expand Down
77 changes: 57 additions & 20 deletions src/components/Patient/PatientRegistration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { z } from "zod";

import CareIcon from "@/CAREUI/icons/CareIcon";
import SectionNavigator from "@/CAREUI/misc/SectionNavigator";

import { Button } from "@/components/ui/button";
Expand Down Expand Up @@ -37,6 +38,7 @@ 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,
Expand Down Expand Up @@ -79,7 +81,8 @@ export default function PatientRegistration(

const [suppressDuplicateWarning, setSuppressDuplicateWarning] =
useState(!!patientId);
const [debouncedNumber, setDebouncedNumber] = useState<string>();
const [selectedLevels, setSelectedLevels] = useState<Organization[]>([]);
const [showAutoFilledPincode, setShowAutoFilledPincode] = useState(false);

const formSchema = useMemo(
() =>
Expand Down Expand Up @@ -192,6 +195,28 @@ 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<typeof formSchema>) {
if (patientId) {
updatePatient({ ...values, ward_old: undefined });
Expand Down Expand Up @@ -226,13 +251,13 @@ export default function PatientRegistration(
};

const patientPhoneSearch = useQuery({
queryKey: ["patients", "phone-number", debouncedNumber],
queryFn: query(routes.searchPatient, {
queryKey: ["patients", "phone-number", form.watch("phone_number")],
queryFn: query.debounced(routes.searchPatient, {
body: {
phone_number: parsePhoneNumber(debouncedNumber || "") || "",
phone_number: parsePhoneNumber(form.watch("phone_number") || "") || "",
},
}),
enabled: !!parsePhoneNumber(debouncedNumber || ""),
enabled: !!parsePhoneNumber(form.watch("phone_number") || ""),
});

const duplicatePatients = useMemo(() => {
Expand All @@ -249,6 +274,9 @@ export default function PatientRegistration(

useEffect(() => {
if (patientQuery.data) {
setSelectedLevels([
patientQuery.data.geo_organization as unknown as Organization,
]);
form.reset({
...patientQuery.data,
same_phone_number:
Expand All @@ -257,27 +285,19 @@ export default function PatientRegistration(
same_address:
patientQuery.data.address === patientQuery.data.permanent_address,
age_or_dob: patientQuery.data.date_of_birth ? "dob" : "age",
age: !patientQuery.data.date_of_birth
? patientQuery.data.age
: undefined,
date_of_birth: patientQuery.data.date_of_birth
? patientQuery.data.date_of_birth
: undefined,
geo_organization: (
patientQuery.data.geo_organization as unknown as Organization
)?.id,
} as unknown as z.infer<typeof formSchema>);
}
}, [patientQuery.data]); // eslint-disable-line react-hooks/exhaustive-deps

useEffect(() => {
const handler = setTimeout(() => {
const phoneNumber = form.getValues("phone_number");
if (!patientId || patientQuery.data?.phone_number !== phoneNumber) {
setSuppressDuplicateWarning(false);
}
setDebouncedNumber(phoneNumber);
}, 500);

return () => {
clearTimeout(handler);
};
}, [form.watch("phone_number")]); // eslint-disable-line react-hooks/exhaustive-deps

if (patientId && patientQuery.isLoading) {
return <Loading />;
}
Expand Down Expand Up @@ -707,6 +727,22 @@ export default function PatientRegistration(
/>
</FormControl>
<FormMessage />
{showAutoFilledPincode && (
<div
role="status"
aria-live="polite"
className="flex items-center"
>
<CareIcon
icon="l-check-circle"
className="mr-2 text-sm text-green-500"
aria-hidden="true"
/>
<span className="text-sm text-primary-500">
{t("pincode_autofill")}
</span>
</div>
)}
</FormItem>
)}
/>
Expand Down Expand Up @@ -746,6 +782,7 @@ export default function PatientRegistration(
<OrganizationSelector
{...field}
required={true}
selected={selectedLevels}
value={form.watch("geo_organization")}
onChange={(value) =>
form.setValue("geo_organization", value)
Expand Down Expand Up @@ -781,7 +818,7 @@ export default function PatientRegistration(
</div>
{!patientPhoneSearch.isLoading &&
!!duplicatePatients?.length &&
!!parsePhoneNumber(debouncedNumber || "") &&
!!parsePhoneNumber(form.watch("phone_number") || "") &&
!suppressDuplicateWarning && (
<DuplicatePatientDialog
patientList={duplicatePatients}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ const MedicationRequestGridRow: React.FC<MedicationRequestGridRowProps> = ({
</Label>
<Select
value={
dosageInstruction.as_needed_boolean
dosageInstruction?.as_needed_boolean
? "PRN"
: reverseFrequencyOption(dosageInstruction?.timing)
}
Expand Down Expand Up @@ -582,7 +582,7 @@ const MedicationRequestGridRow: React.FC<MedicationRequestGridRowProps> = ({
<Input
type="number"
min={0}
value={dosageInstruction.timing.repeat.bounds_duration.value}
value={dosageInstruction.timing.repeat.bounds_duration?.value}
onChange={(e) => {
const value = e.target.value;
if (!dosageInstruction.timing) return;
Expand Down
11 changes: 6 additions & 5 deletions src/components/Questionnaire/QuestionnaireForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -298,11 +298,6 @@ export function QuestionnaireForm({
</div>

{/* Main Content */}
<PLUGIN_Component
__name="Scribe"
formState={questionnaireForms}
setFormState={setQuestionnaireForms}
/>
<div className="flex-1 overflow-y-auto w-full pb-8 space-y-2">
{/* Questionnaire Forms */}
{questionnaireForms.map((form, index) => (
Expand Down Expand Up @@ -442,6 +437,12 @@ export function QuestionnaireForm({
</div>
)}

<PLUGIN_Component
__name="Scribe"
formState={questionnaireForms}
setFormState={setQuestionnaireForms}
/>

{/* Add a Preview of the QuestionnaireForm */}
{import.meta.env.DEV && (
<div className="p-4 space-y-6 max-w-4xl">
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
<input
type={type}
className={cn(
"flex w-full rounded-md border border-gray-200 bg-white px-3 py-2 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-gray-950 placeholder:text-gray-500 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-gray-950 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:border-gray-800 dark:file:text-gray-50 dark:placeholder:text-gray-400 dark:focus-visible:ring-gray-300",
"flex w-full rounded-md border border-gray-400/75 bg-white px-3 py-2 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-gray-950 placeholder:text-gray-500 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-gray-950 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:border-gray-800 dark:file:text-gray-50 dark:placeholder:text-gray-400 dark:focus-visible:ring-gray-300",
className,
)}
ref={ref}
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
return (
<textarea
className={cn(
"flex min-h-[80px] w-full rounded-md border border-gray-200 bg-white px-3 py-1 text-base shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:border-primary-500 focus-visible:outline-none focus-visible:ring-primary-500 md:text-sm disabled:opacity-50",
"flex min-h-[80px] w-full rounded-md border border-gray-400/75 bg-white px-3 py-1 text-base shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:border-primary-500 focus-visible:outline-none focus-visible:ring-primary-500 md:text-sm disabled:opacity-50",
className,
)}
ref={ref}
Expand Down

0 comments on commit 74c4c8d

Please sign in to comment.