2
0
Files
bot/packages/js/src/components/InputChatBlock.tsx
Baptiste Arnaud be4c8e0760 ♻️ Fix eslint warnings
2023-02-23 07:48:11 +01:00

198 lines
6.0 KiB
TypeScript

import type {
ChatReply,
ChoiceInputBlock,
DateInputOptions,
EmailInputBlock,
FileInputBlock,
NumberInputBlock,
PaymentInputOptions,
PhoneNumberInputBlock,
RatingInputBlock,
RuntimeOptions,
TextInputBlock,
Theme,
UrlInputBlock,
} from 'models'
import { InputBlockType } from 'models/features/blocks/inputs/enums'
import { GuestBubble } from './bubbles/GuestBubble'
import { BotContext, InputSubmitContent } from '@/types'
import { TextInput } from '@/features/blocks/inputs/textInput'
import { NumberInput } from '@/features/blocks/inputs/number'
import { EmailInput } from '@/features/blocks/inputs/email'
import { UrlInput } from '@/features/blocks/inputs/url'
import { PhoneInput } from '@/features/blocks/inputs/phone'
import { DateForm } from '@/features/blocks/inputs/date'
import { ChoiceForm } from '@/features/blocks/inputs/buttons'
import { RatingForm } from '@/features/blocks/inputs/rating'
import { FileUploadForm } from '@/features/blocks/inputs/fileUpload'
import { createSignal, Switch, Match } from 'solid-js'
import { isNotDefined } from 'utils'
import { isMobile } from '@/utils/isMobileSignal'
import { PaymentForm } from '@/features/blocks/inputs/payment'
type Props = {
block: NonNullable<ChatReply['input']>
guestAvatar?: Theme['chat']['guestAvatar']
inputIndex: number
context: BotContext
isInputPrefillEnabled: boolean
onSubmit: (answer: string) => void
onSkip: () => void
}
export const InputChatBlock = (props: Props) => {
const [answer, setAnswer] = createSignal<string>()
const handleSubmit = async ({ label, value }: InputSubmitContent) => {
setAnswer(label ?? value)
props.onSubmit(value ?? label)
}
const handleSkip = (label: string) => {
setAnswer(label)
props.onSkip()
}
return (
<Switch>
<Match when={answer()} keyed>
{(answer) => (
<GuestBubble
message={answer}
showAvatar={props.guestAvatar?.isEnabled ?? false}
avatarSrc={props.guestAvatar?.url && props.guestAvatar.url}
/>
)}
</Match>
<Match when={isNotDefined(answer())}>
<div class="flex justify-end animate-fade-in">
{props.guestAvatar?.isEnabled && (
<div
class={
'flex mr-2 mb-2 mt-1 flex-shrink-0 items-center ' +
(isMobile() ? 'w-6 h-6' : 'w-10 h-10')
}
/>
)}
<Input
context={props.context}
block={props.block}
inputIndex={props.inputIndex}
isInputPrefillEnabled={props.isInputPrefillEnabled}
onSubmit={handleSubmit}
onSkip={handleSkip}
hasGuestAvatar={props.guestAvatar?.isEnabled ?? false}
/>
</div>
</Match>
</Switch>
)
}
const Input = (props: {
context: BotContext
block: NonNullable<ChatReply['input']>
inputIndex: number
hasGuestAvatar: boolean
isInputPrefillEnabled: boolean
onSubmit: (answer: InputSubmitContent) => void
onSkip: (label: string) => void
}) => {
const onSubmit = (answer: InputSubmitContent) => props.onSubmit(answer)
const getPrefilledValue = () =>
props.isInputPrefillEnabled ? props.block.prefilledValue : undefined
const submitPaymentSuccess = () =>
props.onSubmit({
value:
(props.block.options as PaymentInputOptions).labels.success ??
'Success',
})
return (
<Switch>
<Match when={props.block.type === InputBlockType.TEXT}>
<TextInput
block={props.block as TextInputBlock}
defaultValue={getPrefilledValue()}
onSubmit={onSubmit}
hasGuestAvatar={props.hasGuestAvatar}
/>
</Match>
<Match when={props.block.type === InputBlockType.NUMBER}>
<NumberInput
block={props.block as NumberInputBlock}
defaultValue={getPrefilledValue()}
onSubmit={onSubmit}
hasGuestAvatar={props.hasGuestAvatar}
/>
</Match>
<Match when={props.block.type === InputBlockType.EMAIL}>
<EmailInput
block={props.block as EmailInputBlock}
defaultValue={getPrefilledValue()}
onSubmit={onSubmit}
hasGuestAvatar={props.hasGuestAvatar}
/>
</Match>
<Match when={props.block.type === InputBlockType.URL}>
<UrlInput
block={props.block as UrlInputBlock}
defaultValue={getPrefilledValue()}
onSubmit={onSubmit}
hasGuestAvatar={props.hasGuestAvatar}
/>
</Match>
<Match when={props.block.type === InputBlockType.PHONE}>
<PhoneInput
block={props.block as PhoneNumberInputBlock}
defaultValue={getPrefilledValue()}
onSubmit={onSubmit}
hasGuestAvatar={props.hasGuestAvatar}
/>
</Match>
<Match when={props.block.type === InputBlockType.DATE}>
<DateForm
options={props.block.options as DateInputOptions}
onSubmit={onSubmit}
/>
</Match>
<Match when={props.block.type === InputBlockType.CHOICE}>
<ChoiceForm
inputIndex={props.inputIndex}
block={props.block as ChoiceInputBlock}
onSubmit={onSubmit}
/>
</Match>
<Match when={props.block.type === InputBlockType.RATING}>
<RatingForm
block={props.block as RatingInputBlock}
defaultValue={getPrefilledValue()}
onSubmit={onSubmit}
/>
</Match>
<Match when={props.block.type === InputBlockType.FILE}>
<FileUploadForm
context={props.context}
block={props.block as FileInputBlock}
onSubmit={onSubmit}
onSkip={props.onSkip}
/>
</Match>
<Match when={props.block.type === InputBlockType.PAYMENT}>
<PaymentForm
context={props.context}
options={
{
...props.block.options,
...props.block.runtimeOptions,
} as PaymentInputOptions & RuntimeOptions
}
onSuccess={submitPaymentSuccess}
/>
</Match>
</Switch>
)
}