From 3844b05403ae23ba0dcb52b4907c73afcf6f42dc Mon Sep 17 00:00:00 2001 From: divija-zemoso Date: Thu, 29 Sep 2022 12:20:24 +0530 Subject: [PATCH] creating a new appointment --- .../appointments/AppointmentsList.tsx | 15 +- src/patients/history/mappers/helpers.tsx | 14 +- .../appointments/AppointmentDetailForm.tsx | 162 ++++++++---------- .../appointments/ViewAppointments.tsx | 38 ++-- .../appointments/constants/Appointment.tsx | 1 + .../appointments/edit/EditAppointment.tsx | 6 +- .../appointments/new/NewAppointment.tsx | 100 +++++------ .../appointments/service/Appointments.tsx | 89 ++++++++++ .../appointments/service/Patients.tsx | 2 +- .../util/scheduling-appointment.util.ts | 8 +- .../appointments/util/validate-appointment.ts | 6 +- .../appointments/view/ViewAppointment.tsx | 3 +- .../DateTimePickerWithLabelFormGroup.tsx | 5 +- src/shared/db/AppointmentRepository.ts | 6 +- src/shared/model/Appointment.ts | 18 +- 15 files changed, 281 insertions(+), 192 deletions(-) diff --git a/src/patients/appointments/AppointmentsList.tsx b/src/patients/appointments/AppointmentsList.tsx index 898e3ef697..67f40a3f16 100644 --- a/src/patients/appointments/AppointmentsList.tsx +++ b/src/patients/appointments/AppointmentsList.tsx @@ -61,15 +61,22 @@ const AppointmentsList = ({ patient }: Props) => { label: t('scheduling.appointment.startDate'), key: 'startDateTime', formatter: (row) => - row.startDateTime - ? format(new Date(row.startDateTime), 'yyyy-MM-dd, hh:mm a') - : '', + row.start ? format(new Date(row.start), 'yyyy-MM-dd, hh:mm a') : '', }, { label: t('scheduling.appointment.endDate'), key: 'endDateTime', formatter: (row) => - row.endDateTime ? format(new Date(row.endDateTime), 'yyyy-MM-dd, hh:mm a') : '', + row.start + ? format( + new Date( + new Date(row.start).setMinutes( + new Date(row.start).getMinutes() + row.minutesDuration, + ), + ), + 'yyyy-MM-dd, hh:mm a', + ) + : '', }, { label: t('scheduling.appointment.location'), key: 'location' }, { label: t('scheduling.appointment.type'), key: 'type' }, diff --git a/src/patients/history/mappers/helpers.tsx b/src/patients/history/mappers/helpers.tsx index 1a5ee1f877..5f54de031c 100644 --- a/src/patients/history/mappers/helpers.tsx +++ b/src/patients/history/mappers/helpers.tsx @@ -35,20 +35,22 @@ export const convertLab = (lab: Lab): PatientHistoryRecord[] => { export const convertAppointment = (appt: Appointment): PatientHistoryRecord[] => { const apptEvents = [] - if (appt.startDateTime) { + if (appt.start) { apptEvents.push({ - date: new Date(appt.startDateTime), + date: new Date(appt.start), type: HistoryRecordType.APPOINTMENT, - info: `Started - ${appt.type}`, + info: `Started - ${appt.appointmentType.text}`, recordId: appt.id, id: `startedAppt${appt.id}`, }) } - if (appt.endDateTime) { + if (new Date(appt.start).setMinutes(new Date(appt.start).getMinutes() + appt.minutesDuration)) { apptEvents.push({ - date: new Date(appt.endDateTime), + date: new Date( + new Date(appt.start).setMinutes(new Date(appt.start).getMinutes() + appt.minutesDuration), + ), type: HistoryRecordType.APPOINTMENT, - info: `Ended - ${appt.type}`, + info: `Ended - ${appt.appointmentType.text}`, recordId: appt.id, id: `endedAppt${appt.id}`, }) diff --git a/src/scheduling/appointments/AppointmentDetailForm.tsx b/src/scheduling/appointments/AppointmentDetailForm.tsx index 129e9d1a6e..d62963eb87 100644 --- a/src/scheduling/appointments/AppointmentDetailForm.tsx +++ b/src/scheduling/appointments/AppointmentDetailForm.tsx @@ -1,63 +1,46 @@ -// import { Select, Typeahead, Label, Alert } from '@hospitalrun/components' import { Select, Label, Alert } from '@hospitalrun/components' -import React from 'react' - +import React, { useEffect, useState } from 'react' +import { AsyncTypeahead } from 'react-bootstrap-typeahead' import DateTimePickerWithLabelFormGroup from '../../shared/components/input/DateTimePickerWithLabelFormGroup' -// import { SelectOption } from '../../shared/components/input/SelectOption' -import TextInputWithLabelFormGroup from '../../shared/components/input/TextInputWithLabelFormGroup' -// import TextFieldWithLabelFormGroup from '../../shared/components/input/TextFieldWithLabelFormGroup' -// import TextInputWithLabelFormGroup from '../../shared/components/input/TextInputWithLabelFormGroup' -// import PatientRepository from '../../shared/db/PatientRepository' import useTranslator from '../../shared/hooks/useTranslator' +import Appointment from '../../shared/model/Appointment' import Patient from '../../shared/model/Patient' -// import { Appointment } from './ViewAppointments' import { appointmentTypes, appointmentStatus } from '../appointments/constants/Appointment' - -export interface Appointment { - appointmentType: { - text: string - } - participant: { - actor: { - reference: string - } - }[] - id: string - start: Date - minutesDuration: number - status: string -} +import { getAllPatients } from './service/Patients' interface Props { appointment: Appointment patient?: Patient isEditable: boolean error?: any - onFieldChange?: (key: string, value: string | boolean) => void + onFieldChange?: (key: string, value: string | boolean | Date | number) => void + setAppointment?: (appointment: Appointment) => void } const AppointmentDetailForm = (props: Props) => { - const { onFieldChange, appointment, patient, isEditable, error } = props + const { appointment, patient, isEditable, error, setAppointment } = props const { t } = useTranslator() + const [patientDetails, setPatientDetails] = useState() + const [options, setOptions] = useState([]) + const [isLoading, setIsLoading] = useState(false) - const patientName: string = String(patient) - - const onDateChange = (date: Date, fieldName: string) => - onFieldChange && onFieldChange(fieldName, date.toISOString()) + // const selectedValues: any[] = [] - // const onInputElementChange = (event: React.ChangeEvent, fieldName: string) => - // onFieldChange && onFieldChange(fieldName, event.target.value) + // const patientName: string = String(patient) + // console.log(patientName) + // if (patientName) { + // selectedValues.push(patientName) + // console.log('selected values', selectedValues) + // } - // const typeOptions: SelectOption[] = [ - // { label: t('scheduling.appointment.types.checkup'), value: 'checkup' }, - // { label: t('scheduling.appointment.types.emergency'), value: 'emergency' }, - // { label: t('scheduling.appointment.types.followUp'), value: 'follow up' }, - // { label: t('scheduling.appointment.types.routine'), value: 'routine' }, - // { label: t('scheduling.appointment.types.walkIn'), value: 'walk in' }, - // ] - - var end = new Date(appointment.start) - end.setMinutes(end.getMinutes() + appointment.minutesDuration) + useEffect(() => { + console.log('appointment details', appointment) + if (!patientDetails) { + ;(async () => { + setPatientDetails(await getAllPatients()) + })() + } + }, []) return ( <> @@ -70,24 +53,32 @@ const AppointmentDetailForm = (props: Props) => { isRequired text={t('scheduling.appointment.patient')} /> - {/* - onFieldChange && p[0] && onFieldChange('patient', p[0].id) - } - onSearch={async (query: string) => PatientRepository.search(query)} - searchAccessor="fullName" - renderMenuItemChildren={(p: Patient) =>
{`${p.fullName} (${p.code})`}
} + onChange={(p: any) => { + appointment.patientId = p[0] && p[0].resource.id + }} + onSearch={async (query: string) => { + setIsLoading(true) + setOptions( + patientDetails?.filter((detail: any) => + String(detail.resource.name[0].text) + .toLowerCase() + .includes(query.toLowerCase()), + ), + ) + setIsLoading(false) + }} + options={options} + labelKey={(option) => `${option.resource?.name[0].text} `} + renderMenuItemChildren={(p: any) => { + return
{`${p.resource.name[0].text} ${p.resource.id}`}
+ }} isInvalid={!!error?.patient} - feedback={t(error?.patient)} - /> */} - @@ -97,40 +88,36 @@ const AppointmentDetailForm = (props: Props) => { { - onDateChange(date, 'startDateTime') + appointment.start = String(date) + if (setAppointment) setAppointment(appointment) }} + isRequired />
{ - onDateChange(date, 'endDateTime') + appointment.end = String(date) + if (new Date(appointment.end) < new Date(appointment.start)) { + appointment.end = JSON.stringify(new Date(appointment.start)) + } + appointment.minutesDuration = + new Date(appointment.end).getMinutes() - new Date(appointment.start).getMinutes() + if (setAppointment) setAppointment(appointment) }} + isRequired />
- {/*
-
- { - onInputElementChange(event, 'location') - }} - /> -
-
*/}
@@ -139,9 +126,12 @@ const AppointmentDetailForm = (props: Props) => { id="type" options={appointmentTypes} defaultSelected={appointmentTypes.filter( - ({ value }) => value === appointment.appointmentType.text, + ({ value }) => value === appointment?.appointmentType?.text, )} - // onChange={(values) => onFieldChange && onFieldChange('type', values[0])} + onChange={(values) => { + appointment.appointmentType = { text: values[0] } + if (setAppointment) setAppointment(appointment) + }} disabled={!isEditable} />
@@ -155,29 +145,17 @@ const AppointmentDetailForm = (props: Props) => { id="status" options={appointmentStatus} defaultSelected={appointmentStatus.filter( - ({ value }) => value === appointment.status, + ({ value }) => value == appointment?.status, )} - // onChange={(values) => onFieldChange && onFieldChange('type', values[0])} + onChange={(values) => { + appointment.status = values[0] + if (setAppointment) setAppointment(appointment) + }} disabled={!isEditable} />
- {/*
-
-
- ) => - onFieldChange && onFieldChange('reason', event.currentTarget.value) - } - /> -
-
-
*/} ) } diff --git a/src/scheduling/appointments/ViewAppointments.tsx b/src/scheduling/appointments/ViewAppointments.tsx index 64f53fe935..a00621b936 100644 --- a/src/scheduling/appointments/ViewAppointments.tsx +++ b/src/scheduling/appointments/ViewAppointments.tsx @@ -1,13 +1,13 @@ import { Calendar, Button } from '@hospitalrun/components' import React, { useEffect, useState } from 'react' import { useHistory } from 'react-router-dom' - import useAddBreadcrumbs from '../../page-header/breadcrumbs/useAddBreadcrumbs' import { useButtonToolbarSetter } from '../../page-header/button-toolbar/ButtonBarProvider' import { useUpdateTitle } from '../../page-header/title/TitleContext' import FilterPatientModal from '../../patients/visits/FilterPatientModal' import Loading from '../../shared/components/Loading' import useTranslator from '../../shared/hooks/useTranslator' +import Appointment from '../../shared/model/Appointment' import { getAppointment } from './service/Appointments' import { getPatientNameById } from './service/Patients' @@ -22,22 +22,22 @@ interface Event { status: string } -export interface Appointment { - resource: { - appointmentType: { - text: string - } - participant: { - actor: { - reference: string - } - }[] - id: string - start: Date - minutesDuration: number - status: string - } -} +// export interface Appointment { +// resource: { +// appointmentType: { +// text: string +// } +// participant: { +// actor: { +// reference: string +// } +// }[] +// id: string +// start: Date +// minutesDuration: number +// status: string +// } +// } const breadcrumbs = [{ i18nKey: 'scheduling.appointments.label', location: '/appointments' }] @@ -48,14 +48,12 @@ const ViewAppointments = () => { useEffect(() => { updateTitle(t('scheduling.appointments.label')) }) - // const { data: appointments, isLoading } = useAppointments() const [appointments, setAppointment] = useState() const [isLoading, setIsLoading] = useState(true) const [events, setEvents] = useState([]) const setButtonToolBar = useButtonToolbarSetter() useAddBreadcrumbs(breadcrumbs, true) const [showFilter, setshowFilter] = useState(false) - const [patientStatus, setpatientStatus] = useState('') const [appointmentType, setappointmentType] = useState('') @@ -108,7 +106,7 @@ const ViewAppointments = () => { useEffect(() => { if (appointments) { - appointments.map(async (appointment: Appointment) => { + appointments.map(async (appointment: { resource: Appointment }) => { const patientName = await getPatientNameById( parseInt(String(appointment.resource.participant[0].actor.reference.substr(8))), ) diff --git a/src/scheduling/appointments/constants/Appointment.tsx b/src/scheduling/appointments/constants/Appointment.tsx index 60bf695c0c..e3517d1e62 100644 --- a/src/scheduling/appointments/constants/Appointment.tsx +++ b/src/scheduling/appointments/constants/Appointment.tsx @@ -14,4 +14,5 @@ export const appointmentTypes: SelectOption[] = [ export const appointmentStatus: SelectOption[] = [ { label: 'Scheduled', value: 'Scheduled' }, { label: 'Confirmed', value: 'Confirmed' }, + { label: 'Checked In', value: 'Checked In' }, ] diff --git a/src/scheduling/appointments/edit/EditAppointment.tsx b/src/scheduling/appointments/edit/EditAppointment.tsx index 6ffed2b90a..d074f970cf 100644 --- a/src/scheduling/appointments/edit/EditAppointment.tsx +++ b/src/scheduling/appointments/edit/EditAppointment.tsx @@ -34,7 +34,9 @@ const EditAppointment = () => { // isError: isErrorUpdate, // error: updateMutateError, // } = useUpdateAppointment(newAppointment) - const { data: patient } = usePatient(currentAppointment ? currentAppointment.patient : id) + const { data: patient } = usePatient( + currentAppointment ? currentAppointment.participant[0].actor : id, + ) const breadcrumbs = [ { i18nKey: 'scheduling.appointments.label', location: '/appointments' }, @@ -68,7 +70,7 @@ const EditAppointment = () => { // } // } - const onFieldChange = (key: string, value: string | boolean) => { + const onFieldChange = (key: string, value: string | boolean | Date | number) => { setAppointment({ ...newAppointment, [key]: value, diff --git a/src/scheduling/appointments/new/NewAppointment.tsx b/src/scheduling/appointments/new/NewAppointment.tsx index 32689db8b0..1e120de9e1 100644 --- a/src/scheduling/appointments/new/NewAppointment.tsx +++ b/src/scheduling/appointments/new/NewAppointment.tsx @@ -1,5 +1,6 @@ // import { Button, Spinner, Toast } from '@hospitalrun/components' -import { Button, Spinner } from '@hospitalrun/components' +import { Button, Spinner, Toast } from '@hospitalrun/components' +import isEmpty from 'lodash/isEmpty' // import addMinutes from 'date-fns/addMinutes' // import roundToNearestMinutes from 'date-fns/roundToNearestMinutes' // import isEmpty from 'lodash/isEmpty' @@ -9,10 +10,12 @@ import { useHistory, useLocation } from 'react-router-dom' import useAddBreadcrumbs from '../../../page-header/breadcrumbs/useAddBreadcrumbs' import { useUpdateTitle } from '../../../page-header/title/TitleContext' import useTranslator from '../../../shared/hooks/useTranslator' +import Appointment from '../../../shared/model/Appointment' // import Appointment from '../../../shared/model/Appointment' import Patient from '../../../shared/model/Patient' import useScheduleAppointment from '../../hooks/useScheduleAppointment' -import AppointmentDetailForm, { Appointment } from '../AppointmentDetailForm' +import AppointmentDetailForm from '../AppointmentDetailForm' +import { createAppointment } from '../service/Appointments' import { AppointmentError } from '../util/validate-appointment' // import { Appointment } from '../ViewAppointments' @@ -42,46 +45,59 @@ const NewAppointment = () => { // const startDateTime = roundToNearestMinutes(new Date(), { nearestTo: 15 }) // const endDateTime = addMinutes(startDateTime, 60) const [saved, setSaved] = useState(false) - const [newAppointmentMutateError, _setError] = useState({} as AppointmentError) - // const [newAppointment, setAppointment] = useState({ - // patient: patient || '', - // startDateTime: startDateTime.toISOString(), - // endDateTime: endDateTime.toISOString(), - // location: '', - // reason: '', - // type: '', - // } as Appointment) + const [newAppointmentMutateError, setError] = useState({} as AppointmentError) const [newAppointment, setAppointment] = useState({} as Appointment) + const [aptId, setAptId] = useState() + const { mutate: newAppointmentMutate, isLoading: isLoadingNewAppointment, isError: isErrorNewAppointment, - validator: _validateNewAppointment, + validator: validateNewAppointment, } = useScheduleAppointment() const onCancelClick = () => { history.push('/appointments') } - // const onSave = () => { - // setSaved(true) - // setError(validateNewAppointment(newAppointment)) + // const func = async () => { + // return await createAppointment(newAppointment) // } + const onSave = async () => { + console.log(newAppointment) + let data = await createAppointment(newAppointment) + console.log('data', await data) + setAptId(await data) + // console.log('@@@@@', await data) + // setAptId(await data) + // console.log('%%%%', aptId) + // newAppointment.id = String(aptId) + // setAppointment({ ...newAppointment }) + // console.log(newAppointment) + setSaved(true) + setError(validateNewAppointment(newAppointment)) + } + + useEffect(() => { + console.log(newAppointment) + }, [newAppointment]) + useEffect(() => { // if save click and no error proceed, else give error message. - // if (saved) { - // if (isEmpty(newAppointmentMutateError) && !isErrorNewAppointment) { - // newAppointmentMutate(newAppointment).then((result) => { - // Toast('success', t('states.success'), t('scheduling.appointment.successfullyCreated')) - // history.push(`/appointments/${result?.id}`) - // }) - // } else if (!isEmpty(newAppointmentMutateError)) { - // newAppointmentMutateError.message = 'scheduling.appointment.errors.createAppointmentError' - // } - // } + if (saved) { + if (isEmpty(newAppointmentMutateError) && !isErrorNewAppointment) { + newAppointmentMutate(newAppointment).then((_result) => { + Toast('success', t('states.success'), t('scheduling.appointment.successfullyCreated')) + console.log(aptId) + history.push(`/appointments/${aptId}`) + }) + } else if (!isEmpty(newAppointmentMutateError)) { + newAppointmentMutateError.message = 'scheduling.appointment.errors.createAppointmentError' + } + } setSaved(false) }, [ saved, @@ -97,46 +113,20 @@ const NewAppointment = () => { return } - const onFieldChange = (key: string, value: string | boolean) => { - setAppointment({ - ...newAppointment, - [key]: value, - }) - } - return ( - //
- //
- // - //
- //
- // - // - //
- //
- // - //
-
{ + setAppointment({ ...appointmentDetail }) + }} />
-