Skip to content

Commit

Permalink
vaccination details frontend updated
Browse files Browse the repository at this point in the history
  • Loading branch information
hrit2773 committed Jun 27, 2024
1 parent 889d0ea commit aa4d838
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 134 deletions.
18 changes: 1 addition & 17 deletions src/Components/Patient/PatientRegister.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,7 @@ export const PatientRegister = (props: PatientRegisterProps) => {
useState(false);
const [insuranceDetailsError, setInsuranceDetailsError] =
useState<FieldError>();
const [vaccinesList, setVaccinesList] = useState<any>([]);
const [isVaccineLoading, setIsVaccineLoading] = useState(false);

useEffect(() => {
if (extId && formField) {
setCareExtId(extId);
Expand All @@ -229,19 +228,6 @@ export const PatientRegister = (props: PatientRegisterProps) => {
const headerText = !id ? "Add Details of Patient" : "Update Patient Details";
const buttonText = !id ? "Add Patient" : "Save Details";

const fetchAllVaccines = useCallback(async () => {
setIsVaccineLoading(true);
const { res, data } = await request(routes.getVaccines);
if (res?.ok && data?.results) {
setVaccinesList(data.results);
}
setIsVaccineLoading(false);
console.log(data?.results);
return data?.results || [];
}, []);
useEffect(() => {
fetchAllVaccines();
}, []);
const fetchDistricts = useCallback(async (id: number) => {
if (id > 0) {
setIsDistrictLoading(true);
Expand Down Expand Up @@ -1794,8 +1780,6 @@ export const PatientRegister = (props: PatientRegisterProps) => {
className=" mb-4"
>
<VaccinationDetailsBuilder
vaccineOptions={vaccinesList}
vaccinesLoading={isVaccineLoading}
value={
field("create_vaccination_details")
.value
Expand Down
10 changes: 9 additions & 1 deletion src/Components/Patient/models.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,18 @@ export interface AbhaObject {
}

export interface VaccinesData {
external_id: string;
id: string;
name: string;
}

export interface VaccineRegistrationModel {
vaccine_name?: string;
vaccination_center?: string;
last_vaccinated_date?: any;
number_of_doses?: string;
batch_number?: string;
}

export interface PatientModel {
vaccination_details?: {
vaccine_name: { id: string; name: string };
Expand Down
185 changes: 96 additions & 89 deletions src/Components/VaccinationDetails/AddVaccinationDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,105 +1,112 @@
import { useState } from "react";
import TextFormField from "../Form/FormFields/TextFormField";
import DateFormField from "../Form/FormFields/DateFormField";
import ButtonV2 from "../Common/components/ButtonV2";
import AutocompleteFormField from "../Form/FormFields/Autocomplete";
import Spinner from "../Common/Spinner";
import FormField from "../Form/FormFields/FormField";
import {
FieldChangeEvent,
FormFieldBaseProps,
useFormFieldPropsResolver,
} from "../Form/FormFields/Utils";
import { VaccineRegistrationModel, VaccinesData } from "../Patient/models";
import routes from "../../Redux/api";
import useQuery from "../../Utils/request/useQuery";

const initForm: any = {
vaccination_center: "",
number_of_doses: "",
vaccine_name: "",
batch_number: "",
last_vaccinated_date: "",
};
export const AddVaccinationDetails = (props: any) => {
const [state, setState] = useState<any>({ ...initForm });
const handleFormFieldChange = (e: any) => {
setState((prev: any) => {
return {
...prev,
[e.name]: e.value,
};
type Props = FormFieldBaseProps<VaccineRegistrationModel>;
export const AddVaccinationDetails = (props: Props) => {
const field = useFormFieldPropsResolver(props);
const { data: vaccines, loading: isVaccinesLoading } = useQuery(
routes.getVaccines,
);
const handleVaccineDetailChange = (event: FieldChangeEvent<unknown>) => {
const fieldName: string = event.name;
const fieldValue: any = event.value;
field.handleChange({
...props.value,
[fieldName]: fieldValue,
});
};
const hasError = props.disallowed.includes(state.vaccine_name);

return (
<div className=" flex flex-col gap-2">
<div className="grid w-full grid-cols-1 gap-4 rounded-lg border border-gray-400 bg-gray-100 px-4 pt-4 shadow-md md:grid-cols-2 xl:gap-x-20 xl:gap-y-6">
<div id="vaccination_center-div">
<TextFormField
label="Vaccination Center"
name="vaccination_center"
value={state.vaccination_center}
onChange={handleFormFieldChange}
type="text"
/>
</div>
<FormField field={field}>
<VaccinationDetailsFormCard
vaccineDetails={props.value}
vaccineDetailChange={handleVaccineDetailChange}
fetchedVaccines={vaccines?.results || []}
fetchedVaccinesLoading={isVaccinesLoading}
/>
</FormField>
);
};

<div id="number_of_doses-div">
<TextFormField
label="Number of Doses"
name="number_of_doses"
value={state.number_of_doses}
onChange={handleFormFieldChange}
type="number"
min={1}
/>
</div>
<div id="vaccine_name-div">
{props.vaccinesLoading ? (
<Spinner />
) : (
<AutocompleteFormField
name="vaccine_name"
value={state.vaccine_name}
onChange={handleFormFieldChange}
label="Vaccine Name"
options={props.vaccines}
optionLabel={(o: any) => o.name}
optionValue={(o) => o.name}
error={hasError ? "This vaccine was already added" : undefined}
/>
)}
</div>
const VaccinationDetailsFormCard = ({
vaccineDetails,
vaccineDetailChange,
fetchedVaccines,
fetchedVaccinesLoading,
}: {
vaccineDetails?: VaccineRegistrationModel;
vaccineDetailChange: (event: FieldChangeEvent<unknown>) => void;
fetchedVaccines: VaccinesData[];
fetchedVaccinesLoading?: boolean;
}) => {
return (
<div className="grid w-full grid-cols-1 gap-4 rounded-lg border border-gray-400 bg-gray-100 px-4 pt-4 shadow-md md:grid-cols-2 xl:gap-x-20 xl:gap-y-6">
<div id="vaccination_center-div">
<TextFormField
label="Vaccination Center"
name="vaccination_center"
value={vaccineDetails?.vaccination_center}
onChange={vaccineDetailChange}
type="text"
/>
</div>

<div id="batch_number-div">
<TextFormField
label="Batch Number"
name="batch_number"
value={state.batch_number}
onChange={handleFormFieldChange}
type="text"
<div id="number_of_doses-div">
<TextFormField
label="Number of Doses"
name="number_of_doses"
value={vaccineDetails?.number_of_doses}
onChange={vaccineDetailChange}
type="number"
min={1}
/>
</div>
<div id="vaccine_name-div">
{fetchedVaccinesLoading ? (
<Spinner />
) : (
<AutocompleteFormField
name="vaccine_name"
value={vaccineDetails?.vaccine_name}
onChange={vaccineDetailChange}
label="Vaccine Name"
options={fetchedVaccines}
optionLabel={(o: any) => o.name}
optionValue={(o) => o.name}
/>
</div>
)}
</div>

<div className=" col-span-2" id="last_vaccinated_date-div">
<DateFormField
name="last_vaccinated_date"
value={state.last_vaccinated_date}
onChange={handleFormFieldChange}
label="Last Date of Vaccination"
disableFuture={true}
position="LEFT"
/>
</div>
<div id="batch_number-div">
<TextFormField
label="Batch Number"
name="batch_number"
value={vaccineDetails?.batch_number}
onChange={vaccineDetailChange}
type="text"
/>
</div>
<div className=" my-3">
<ButtonV2
disabled={
(Object.values(state).reduce((acc, val) => {
return acc || val === "";
}, false) as boolean) || hasError
}
variant="alert"
onClick={(e) => {
e.preventDefault();
props.onAdd(state);
setState({ ...initForm });
}}
>
+ Add Vaccination Details
</ButtonV2>

<div className=" col-span-2" id="last_vaccinated_date-div">
<DateFormField
name="last_vaccinated_date"
value={vaccineDetails?.last_vaccinated_date}
onChange={vaccineDetailChange}
label="Last Date of Vaccination"
disableFuture={true}
position="LEFT"
/>
</div>
</div>
);
Expand Down
79 changes: 61 additions & 18 deletions src/Components/VaccinationDetails/VaccinationDetailsBuilder.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,50 @@
import { useState } from "react";
import CareIcon from "../../CAREUI/icons/CareIcon";
import { AddVaccinationDetails } from "./AddVaccinationDetails";
import { VaccinationDetailsEntry } from "./VaccinationDetailsEntry";
import { VaccineRegistrationModel } from "../Patient/models";
import ButtonV2 from "../Common/components/ButtonV2";

const initialState: VaccineRegistrationModel = {
vaccination_center: "",
number_of_doses: "",
vaccine_name: "",
batch_number: "",
last_vaccinated_date: "",
};
export const VaccinationDetailsBuilder = (props: any) => {
const [vaccineDetailState, setVaccineDetailState] =
useState<VaccineRegistrationModel>(initialState);
const [vaccineFormError, setVaccineFormError] = useState("");

const validateVaccineDetails = (detail: any) => {
const vaccine_names = props.value.map((val: any) => val.vaccine_name);
if (vaccine_names.includes(detail.vaccine_name)) {
setVaccineFormError("This Vaccine is already selected");
return false;
}
return true;
};

return (
<div className=" flex w-full flex-col gap-4 rounded-lg border border-gray-400 bg-gray-200 p-8 shadow-md">
{props.value.length !== 0 && (
<div className="my-7 flex flex-col gap-8">
{props.value.map((detail: any, idx: any) => (
<div className="flex w-full gap-2 rounded-lg border border-gray-400 p-3 shadow-md">
<CareIcon
className="mt-3 cursor-pointer text-3xl text-red-600"
icon={"l-trash-alt"}
onClick={() => {
props.onChange(
props.value.filter((_: any, index: any) => {
return index !== idx;
}),
);
}}
/>
<div>
<CareIcon
className="mt-3 cursor-pointer text-3xl text-red-600"
icon={"l-trash-alt"}
onClick={() => {
props.onChange(
props.value.filter((_: any, index: any) => {
return index !== idx;
}),
);
}}
/>
</div>
<VaccinationDetailsEntry
detailsObj={detail}
fieldsClassName="min-w-fit border text-sm text-black rounded-md border-gray-400 p-3"
Expand All @@ -36,15 +61,33 @@ export const VaccinationDetailsBuilder = (props: any) => {
)}
</div>

<div>
<div className="flex flex-col gap-2">
<AddVaccinationDetails
vaccinesLoading={props.vaccinesLoading}
vaccines={props.vaccineOptions}
disallowed={props.value.map((obj: any) => obj.vaccine_name)}
onAdd={(details: any) => {
props.onChange([...props.value, details]);
}}
name="vaccine_Form"
value={vaccineDetailState}
error={vaccineFormError}
onChange={({ value }: any) => setVaccineDetailState(value)}
/>
<div className=" my-3">
<ButtonV2
variant="alert"
disabled={
(Object.values(vaccineDetailState).reduce((acc, val) => {
return acc || val === "";
}, false) as boolean) && vaccineFormError == ""
}
onClick={(e) => {
e.preventDefault();
if (!validateVaccineDetails(vaccineDetailState)) return;
props.onChange([...props.value, { ...vaccineDetailState }]);
setVaccineDetailState({ ...initialState });
setVaccineFormError("");
}}
>
<CareIcon icon="l-plus" className="text-lg" />
<span>Add Vaccination Details</span>
</ButtonV2>
</div>
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { VaccinationDetailsView } from "./VaccinationDetailsView";

export const VaccinationDetailsEntry = (props: any) => {
return (
<div className=" w-full rounded-lg border border-gray-400 bg-white p-3">
<div className=" w-full rounded-lg border border-gray-400 bg-white px-6 py-3">
<AccordionV2
title={
<div>
Expand Down
Loading

0 comments on commit aa4d838

Please sign in to comment.