2
0
Files
bot/packages/bot-engine/src/components/ChatGroup/ChatBlock/InputChatBlock.tsx
2022-06-15 18:38:17 +02:00

137 lines
3.8 KiB
TypeScript

import React, { useState } from 'react'
import { useAnswers } from '../../../contexts/AnswersContext'
import { InputBlock, InputBlockType } from 'models'
import { GuestBubble } from './bubbles/GuestBubble'
import { TextForm } from './inputs/TextForm'
import { byId } from 'utils'
import { DateForm } from './inputs/DateForm'
import { ChoiceForm } from './inputs/ChoiceForm'
import { useTypebot } from 'contexts/TypebotContext'
import { parseVariables } from '../../../services/variable'
import { isInputValid } from 'services/inputs'
import { PaymentForm } from './inputs/PaymentForm'
import { RatingForm } from './inputs/RatingForm'
import { FileUploadForm } from './inputs/FileUploadForm'
export type InputSubmitContent = {
label?: string
value: string
itemId?: string
}
export const InputChatBlock = ({
block,
hasAvatar,
hasGuestAvatar,
onTransitionEnd,
}: {
block: InputBlock
hasGuestAvatar: boolean
hasAvatar: boolean
onTransitionEnd: (
answerContent?: InputSubmitContent,
isRetry?: boolean
) => void
}) => {
const { typebot } = useTypebot()
const { addAnswer } = useAnswers()
const [answer, setAnswer] = useState<string>()
const [isEditting, setIsEditting] = useState(false)
const { variableId } = block.options
const defaultValue =
typebot.settings.general.isInputPrefillEnabled ?? true
? variableId && typebot.variables.find(byId(variableId))?.value
: undefined
const handleSubmit = async ({ label, value, itemId }: InputSubmitContent) => {
setAnswer(label ?? value)
const isRetry = !isInputValid(value, block.type)
if (!isRetry && addAnswer)
await addAnswer({
blockId: block.id,
groupId: block.groupId,
content: value,
variableId: variableId ?? null,
})
if (!isEditting) onTransitionEnd({ label, value, itemId }, isRetry)
setIsEditting(false)
}
const handleGuestBubbleClick = () => {
setAnswer(undefined)
setIsEditting(true)
}
if (answer) {
const avatarUrl = typebot.theme.chat.guestAvatar?.url
return (
<GuestBubble
message={answer}
showAvatar={typebot.theme.chat.guestAvatar?.isEnabled ?? false}
avatarSrc={avatarUrl && parseVariables(typebot.variables)(avatarUrl)}
onClick={handleGuestBubbleClick}
/>
)
}
return (
<div className="flex">
{hasAvatar && (
<div className="flex w-6 xs:w-10 h-6 xs:h-10 mr-2 mb-2 mt-1 flex-shrink-0 items-center" />
)}
<Input
block={block}
onSubmit={handleSubmit}
defaultValue={defaultValue?.toString()}
hasGuestAvatar={hasGuestAvatar}
/>
</div>
)
}
const Input = ({
block,
onSubmit,
defaultValue,
hasGuestAvatar,
}: {
block: InputBlock
onSubmit: (value: InputSubmitContent) => void
defaultValue?: string
hasGuestAvatar: boolean
}) => {
switch (block.type) {
case InputBlockType.TEXT:
case InputBlockType.NUMBER:
case InputBlockType.EMAIL:
case InputBlockType.URL:
case InputBlockType.PHONE:
return (
<TextForm
block={block}
onSubmit={onSubmit}
defaultValue={defaultValue}
hasGuestAvatar={hasGuestAvatar}
/>
)
case InputBlockType.DATE:
return <DateForm options={block.options} onSubmit={onSubmit} />
case InputBlockType.CHOICE:
return <ChoiceForm block={block} onSubmit={onSubmit} />
case InputBlockType.PAYMENT:
return (
<PaymentForm
options={block.options}
onSuccess={() =>
onSubmit({ value: block.options.labels.success ?? 'Success' })
}
/>
)
case InputBlockType.RATING:
return <RatingForm block={block} onSubmit={onSubmit} />
case InputBlockType.FILE:
return <FileUploadForm block={block} onSubmit={onSubmit} />
}
}