import { chakra, Modal, ModalBody, ModalContent, ModalOverlay, useDisclosure, } from '@chakra-ui/react' import { TypebotViewer } from 'bot-engine' import { useUser } from 'contexts/UserContext' import { Answer, Typebot } from 'models' import React, { useEffect, useRef, useState } from 'react' import { parseTypebotToPublicTypebot } from 'services/publicTypebot' import { sendRequest } from 'utils' import confetti from 'canvas-confetti' import { useToast } from 'components/shared/hooks/useToast' type Props = { totalTypebots: number } export const OnboardingModal = ({ totalTypebots }: Props) => { const { user, saveUser } = useUser() const { isOpen, onOpen, onClose } = useDisclosure() const [typebot, setTypebot] = useState() const confettiCanvaContainer = useRef(null) const confettiCanon = useRef() const [chosenCategories, setChosenCategories] = useState([]) const [openedOnce, setOpenedOnce] = useState(false) const { showToast } = useToast() useEffect(() => { fetchTemplate() // eslint-disable-next-line react-hooks/exhaustive-deps }, []) useEffect(() => { if (openedOnce) return const isNewUser = user && new Date(user?.createdAt as unknown as string).toDateString() === new Date().toDateString() && totalTypebots === 0 if (isNewUser) { onOpen() setOpenedOnce(true) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [user]) useEffect(() => { initConfettis() return () => { window.removeEventListener('message', handleIncomingMessage) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [confettiCanvaContainer.current]) const initConfettis = () => { if (!confettiCanvaContainer.current || confettiCanon.current) return confettiCanon.current = confetti.create(confettiCanvaContainer.current, { resize: true, useWorker: true, }) window.addEventListener('message', handleIncomingMessage) } const handleIncomingMessage = (message: MessageEvent) => { if (message.data.from === 'typebot') { if (message.data.action === 'shootConfettis' && confettiCanon.current) shootConfettis(confettiCanon.current) } } const fetchTemplate = async () => { const { data, error } = await sendRequest(`/bots/onboarding.json`) if (error) return showToast({ title: error.name, description: error.message }) setTypebot(data as Typebot) } const handleNewAnswer = async (answer: Answer) => { const isName = answer.variableId === 'cl126f4hf000i2e6d8zvzc3t1' const isCompany = answer.variableId === 'cl126jqww000w2e6dq9yv4ifq' const isCategories = answer.variableId === 'cl126mo3t001b2e6dvyi16bkd' const isOtherCategories = answer.variableId === 'cl126q38p001q2e6d0hj23f6b' if (isName) saveUser({ name: answer.content }) if (isCompany) saveUser({ company: answer.content }) if (isCategories) { const onboardingCategories = answer.content.split(', ') saveUser({ onboardingCategories }) setChosenCategories(onboardingCategories) } if (isOtherCategories) saveUser({ onboardingCategories: [...chosenCategories, answer.content], }) } return ( {typebot && ( )} ) } const shootConfettis = (confettiCanon: confetti.CreateTypes) => { const count = 200 const defaults = { origin: { y: 0.7 }, } const fire = ( particleRatio: number, opts: { spread: number startVelocity?: number decay?: number scalar?: number } ) => { confettiCanon( Object.assign({}, defaults, opts, { particleCount: Math.floor(count * particleRatio), }) ) } fire(0.25, { spread: 26, startVelocity: 55, }) fire(0.2, { spread: 60, }) fire(0.35, { spread: 100, decay: 0.91, scalar: 0.8, }) fire(0.1, { spread: 120, startVelocity: 25, decay: 0.92, scalar: 1.2, }) fire(0.1, { spread: 120, startVelocity: 45, }) }