Skip to main content
Glama
MfaForm.tsx2.56 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import { Alert, Center, Image, Stack, Text, TextInput, Title } from '@mantine/core'; import { normalizeErrorString } from '@medplum/core'; import { IconAlertCircle } from '@tabler/icons-react'; import type { JSX } from 'react'; import { useState } from 'react'; import { Form } from '../Form/Form'; import { SubmitButton } from '../Form/SubmitButton'; import { Logo } from '../Logo/Logo'; export type MfaFormFields = 'token'; export interface MfaFormProps { readonly title: string; readonly buttonText: string; readonly description?: string; readonly qrCodeUrl?: string; readonly onSubmit: (formData: Record<MfaFormFields, string>) => void | Promise<void>; } export function MfaForm(props: MfaFormProps): JSX.Element { const [errorMessage, setErrorMessage] = useState<string>(); return ( <Form onSubmit={(formData: Record<MfaFormFields, string>) => { setErrorMessage(undefined); props.onSubmit(formData)?.catch((err) => setErrorMessage(normalizeErrorString(err))); }} > <Center style={{ flexDirection: 'column' }}> <Logo size={32} /> <Title order={3} py="lg"> {props.title} </Title> {!props.qrCodeUrl && props.description && ( <Text c="dimmed" mb="lg" mt="-lg"> {props.description} </Text> )} </Center> {errorMessage && ( <Alert icon={<IconAlertCircle size={16} />} title="Error" color="red" mb="lg"> {errorMessage} </Alert> )} {props.qrCodeUrl && ( <Center> <Stack mb="xl"> {props.description && ( <Text c="dimmed" mb="md" mt="-lg" ta="center"> {props.description} </Text> )} <Image src={props.qrCodeUrl} alt="Multi Factor Auth QR Code" w="60%" mx="auto" radius="md" p="xs" bg="var(--mantine-color-white)" style={{ border: '1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-4))' }} /> </Stack> </Center> )} <Stack gap="sm"> <TextInput name="token" label="MFA code" autoComplete="one-time-code" required autoFocus /> </Stack> <Stack gap="xs" pt="md"> <SubmitButton fullWidth>{props.buttonText}</SubmitButton> </Stack> </Form> ); }

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