Skip to main content
Glama
CreateEncounter.tsx4.01 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import { Modal } from '@mantine/core'; import { showNotification } from '@mantine/notifications'; import { createReference, getQuestionnaireAnswers, normalizeErrorString } from '@medplum/core'; import type { Appointment, Coding, Encounter, Patient, Practitioner, Questionnaire, Reference, } from '@medplum/fhirtypes'; import { QuestionnaireForm, useMedplum } from '@medplum/react'; import { IconCircleCheck, IconCircleOff } from '@tabler/icons-react'; import type { JSX } from 'react'; import { useNavigate } from 'react-router'; interface CreateEncounterProps { appointment: Appointment; patient: Patient; readonly opened: boolean; readonly handlers: { readonly open: () => void; readonly close: () => void; readonly toggle: () => void; }; } export function CreateEncounter(props: CreateEncounterProps): JSX.Element { const { appointment, patient, opened, handlers } = props; const medplum = useMedplum(); const navigate = useNavigate(); async function handleCreateEncounter(formData: any): Promise<void> { const answers = getQuestionnaireAnswers(formData); try { // Update the appointment status to 'fulfilled' await medplum.updateResource({ ...appointment, status: 'fulfilled', }); // Create the Encounter resource const patientReference = createReference(patient); const participant = appointment.participant?.filter((p) => p.actor?.reference !== patientReference.reference); const duration = new Date(appointment.end as string).getTime() - new Date(appointment.start as string).getTime(); let encounter: Encounter = { resourceType: 'Encounter', status: 'finished', subject: patientReference, appointment: [createReference(appointment)], class: { system: 'http://terminology.hl7.org/CodeSystem/v3-ActCode', code: 'VR', display: 'virtual', }, type: [{ coding: [answers['type'].valueCoding as Coding] }], serviceType: appointment.serviceType?.[0], period: { start: appointment.start, end: appointment.end, }, length: { value: Math.floor(duration / 60000), unit: 'minutes', }, participant: participant.map((p) => ({ individual: p.actor as Reference<Practitioner>, type: [{ coding: [{ system: 'http://terminology.hl7.org/CodeSystem/v3-ParticipationType', code: 'ATND' }] }], })), }; encounter = await medplum.createResource(encounter); // Navigate to the encounter details page navigate(`/Encounter/${encounter.id}`)?.catch(console.error); showNotification({ icon: <IconCircleCheck />, title: 'Success', message: 'Encounter created', }); handlers.close(); } catch (err) { showNotification({ icon: <IconCircleOff />, title: 'Error', message: normalizeErrorString(err), }); } } return ( <Modal opened={opened} onClose={handlers.close}> <QuestionnaireForm questionnaire={createEncounterQuestionnaire} onSubmit={handleCreateEncounter} /> </Modal> ); } const createEncounterQuestionnaire: Questionnaire = { resourceType: 'Questionnaire', id: 'new-encounter', title: 'Create Encounter', status: 'active', item: [ { linkId: 'info-note', type: 'display', text: "By submitting the form, the appointment status will be set to 'fulfilled' and " + 'an Encounter resource will be created to capture details about the visit. ' + 'To further explore the Encounter lifecycle, please visit the Medplum Charting Demo.', }, { linkId: 'type', type: 'choice', text: 'Type', answerValueSet: 'http://hl7.org/fhir/ValueSet/encounter-type', required: true, }, ], };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/medplum/medplum'

If you have feedback or need assistance with the MCP directory API, please join our Discord server