Skip to main content
Glama
EncounterModal.tsx5.65 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import { Box, Button, Card, Grid, Modal, Stack, Text } from '@mantine/core'; import { showNotification } from '@mantine/notifications'; import { normalizeErrorString } from '@medplum/core'; import type { Coding, Encounter, PlanDefinition } from '@medplum/fhirtypes'; import { CodeInput, CodingInput, DateTimeInput, ResourceInput, useMedplum } from '@medplum/react'; import { IconAlertSquareRounded, IconCircleCheck, IconCircleOff } from '@tabler/icons-react'; import { useState } from 'react'; import type { JSX } from 'react'; import { useNavigate } from 'react-router'; import { usePatient } from '../../hooks/usePatient'; import classes from './EncounterModal.module.css'; import { createEncounter } from '../../utils/encounter'; export const EncounterModal = (): JSX.Element => { const navigate = useNavigate(); const medplum = useMedplum(); const patient = usePatient(); const [isOpen, setIsOpen] = useState(true); const [start, setStart] = useState<Date | undefined>(); const [end, setEnd] = useState<Date | undefined>(); const [encounterClass, setEncounterClass] = useState<Coding | undefined>(); const [planDefinitionData, setPlanDefinitionData] = useState<PlanDefinition | undefined>(); const [status, setStatus] = useState<Encounter['status'] | undefined>(); const [isLoading, setIsLoading] = useState(false); const handleCreateEncounter = async (): Promise<void> => { if (!patient || !encounterClass || !start || !end || !status || !planDefinitionData) { showNotification({ color: 'yellow', icon: <IconAlertSquareRounded />, title: 'Error', message: 'Please fill out required fields.', }); return; } setIsLoading(true); try { const encounter = await createEncounter(medplum, start, end, encounterClass, patient, planDefinitionData); showNotification({ icon: <IconCircleCheck />, title: 'Success', message: 'Encounter created' }); navigate(`/Patient/${patient.id}/Encounter/${encounter.id}`)?.catch(console.error); } catch (err) { showNotification({ color: 'red', icon: <IconCircleOff />, title: 'Error', message: normalizeErrorString(err) }); } finally { setIsLoading(false); } }; return ( <Modal opened={isOpen} onClose={() => { navigate(-1)?.catch(console.error); setIsOpen(false); }} size="60%" title="New encounter" styles={{ title: { fontSize: '1.125rem', fontWeight: 600 }, body: { padding: 0, height: '60vh' } }} > <Stack h="100%" justify="space-between" gap={0}> <Box flex={1} miw={0}> <Grid p="md" h="100%"> <Grid.Col span={6} pr="md"> <Stack gap="md"> <ResourceInput resourceType="Patient" name="Patient-id" defaultValue={patient} disabled={true} required={true} /> <DateTimeInput name="start" label="Start Time" required={true} onChange={(value) => { setStart(new Date(value)); }} /> <DateTimeInput name="end" label="End Time" required={true} onChange={(value) => { setEnd(new Date(value)); }} /> <CodingInput name="class" label="Class" binding="http://terminology.hl7.org/ValueSet/v3-ActEncounterCode" required={true} onChange={setEncounterClass} path="Encounter.type" /> <CodeInput name="status" label="Status" binding="http://hl7.org/fhir/ValueSet/encounter-status|4.0.1" maxValues={1} required={true} onChange={(value) => { if (value) { setStatus(value as typeof status); } }} /> </Stack> </Grid.Col> <Grid.Col span={6}> <Card padding="lg" radius="md" className={classes.planDefinition}> <Text size="md" fw={500} mb="xs"> Apply care template </Text> <Text size="sm" color="dimmed" mb="lg"> You can select template for new encounter. Tasks from the template will be automatically added to the encounter. Administrators can create and edit templates in the{' '} <Text component="a" href="#" variant="link"> Medplum app </Text> . </Text> <ResourceInput name="plandefinition" resourceType="PlanDefinition" onChange={(value) => setPlanDefinitionData(value as PlanDefinition)} required={true} /> </Card> </Grid.Col> </Grid> </Box> <Box className={classes.footer} h={70} p="md"> <Button fullWidth={false} onClick={handleCreateEncounter} loading={isLoading} disabled={isLoading}> Create Encounter </Button> </Box> </Stack> </Modal> ); };

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