Files
bot/packages/deprecated/bot-engine/src/providers/AnswersProvider.tsx
2023-03-15 08:35:16 +01:00

103 lines
2.7 KiB
TypeScript

import { safeStringify } from '@/features/variables'
import {
AnswerInput,
ResultValuesInput,
Variable,
VariableWithUnknowValue,
VariableWithValue,
} from '@typebot.io/schemas'
import { createContext, ReactNode, useContext, useState } from 'react'
import { isDefined } from '@typebot.io/lib'
const answersContext = createContext<{
resultId?: string
resultValues: ResultValuesInput
addAnswer: (
existingVariables: Variable[]
) => (
answer: AnswerInput & { uploadedFiles: boolean }
) => Promise<void> | undefined
updateVariables: (variables: VariableWithUnknowValue[]) => void
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
}>({})
export const AnswersProvider = ({
children,
resultId,
onNewAnswer,
onVariablesUpdated,
}: {
resultId?: string
onNewAnswer: (
answer: AnswerInput & { uploadedFiles: boolean }
) => Promise<void> | undefined
onVariablesUpdated?: (variables: VariableWithValue[]) => void
children: ReactNode
}) => {
const [resultValues, setResultValues] = useState<ResultValuesInput>({
answers: [],
variables: [],
createdAt: new Date(),
})
const addAnswer =
(existingVariables: Variable[]) =>
(answer: AnswerInput & { uploadedFiles: boolean }) => {
if (answer.variableId)
updateVariables([
{
id: answer.variableId,
value: answer.content,
name:
existingVariables.find(
(existingVariable) => existingVariable.id === answer.variableId
)?.name ?? '',
},
])
setResultValues((resultValues) => ({
...resultValues,
answers: [...resultValues.answers, answer],
}))
return onNewAnswer && onNewAnswer(answer)
}
const updateVariables = (newVariables: VariableWithUnknowValue[]) => {
const serializedNewVariables = newVariables.map((variable) => ({
...variable,
value: safeStringify(variable.value),
}))
setResultValues((resultValues) => {
const updatedVariables = [
...resultValues.variables.filter((v) =>
serializedNewVariables.every(
(variable) => variable.id !== v.id || variable.name !== v.name
)
),
...serializedNewVariables,
].filter((variable) => isDefined(variable.value)) as VariableWithValue[]
if (onVariablesUpdated) onVariablesUpdated(updatedVariables)
return {
...resultValues,
variables: updatedVariables,
}
})
}
return (
<answersContext.Provider
value={{
resultId,
resultValues,
addAnswer,
updateVariables,
}}
>
{children}
</answersContext.Provider>
)
}
export const useAnswers = () => useContext(answersContext)