2
0

refactor: ♻️ Toast component

This commit is contained in:
Baptiste Arnaud
2022-06-02 07:54:48 +02:00
parent 43fb8a7be0
commit 12f2e40152
26 changed files with 148 additions and 177 deletions

View File

@@ -4,7 +4,6 @@ import {
Input, Input,
Stack, Stack,
HStack, HStack,
useToast,
Text, Text,
} from '@chakra-ui/react' } from '@chakra-ui/react'
import React, { ChangeEvent, FormEvent, useEffect } from 'react' import React, { ChangeEvent, FormEvent, useEffect } from 'react'
@@ -21,6 +20,7 @@ import { SocialLoginButtons } from './SocialLoginButtons'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { NextChakraLink } from 'components/nextChakra/NextChakraLink' import { NextChakraLink } from 'components/nextChakra/NextChakraLink'
import { BuiltInProviderType } from 'next-auth/providers' import { BuiltInProviderType } from 'next-auth/providers'
import { useToast } from 'components/shared/hooks/useToast'
type Props = { type Props = {
defaultEmail?: string defaultEmail?: string
@@ -34,9 +34,7 @@ export const SignInForm = ({
const [isLoadingProviders, setIsLoadingProviders] = useState(true) const [isLoadingProviders, setIsLoadingProviders] = useState(true)
const [emailValue, setEmailValue] = useState(defaultEmail ?? '') const [emailValue, setEmailValue] = useState(defaultEmail ?? '')
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
})
const [providers, setProviders] = const [providers, setProviders] =
useState< useState<
Record<LiteralUnion<BuiltInProviderType, string>, ClientSafeProvider> Record<LiteralUnion<BuiltInProviderType, string>, ClientSafeProvider>
@@ -65,7 +63,7 @@ export const SignInForm = ({
email: emailValue, email: emailValue,
redirect: false, redirect: false,
}) })
toast({ showToast({
status: 'success', status: 'success',
title: 'Success!', title: 'Success!',
description: 'Check your inbox to sign in', description: 'Check your inbox to sign in',

View File

@@ -7,7 +7,6 @@ import {
Skeleton, Skeleton,
Stack, Stack,
useEventListener, useEventListener,
useToast,
Wrap, Wrap,
} from '@chakra-ui/react' } from '@chakra-ui/react'
import { useTypebotDnd } from 'contexts/TypebotDndContext' import { useTypebotDnd } from 'contexts/TypebotDndContext'
@@ -27,6 +26,7 @@ import { TypebotButton } from './FolderContent/TypebotButton'
import { TypebotCardOverlay } from './FolderContent/TypebotButtonOverlay' import { TypebotCardOverlay } from './FolderContent/TypebotButtonOverlay'
import { OnboardingModal } from './OnboardingModal' import { OnboardingModal } from './OnboardingModal'
import { useWorkspace } from 'contexts/WorkspaceContext' import { useWorkspace } from 'contexts/WorkspaceContext'
import { useToast } from 'components/shared/hooks/useToast'
type Props = { folder: DashboardFolder | null } type Props = { folder: DashboardFolder | null }
@@ -51,10 +51,7 @@ export const FolderContent = ({ folder }: Props) => {
const [typebotDragCandidate, setTypebotDragCandidate] = const [typebotDragCandidate, setTypebotDragCandidate] =
useState<TypebotInDashboard>() useState<TypebotInDashboard>()
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
const { const {
folders, folders,
@@ -64,7 +61,7 @@ export const FolderContent = ({ folder }: Props) => {
workspaceId: workspace?.id, workspaceId: workspace?.id,
parentId: folder?.id, parentId: folder?.id,
onError: (error) => { onError: (error) => {
toast({ title: "Couldn't fetch folders", description: error.message }) showToast({ title: "Couldn't fetch folders", description: error.message })
}, },
}) })
@@ -76,7 +73,10 @@ export const FolderContent = ({ folder }: Props) => {
workspaceId: workspace?.id, workspaceId: workspace?.id,
folderId: folder?.id, folderId: folder?.id,
onError: (error) => { onError: (error) => {
toast({ title: "Couldn't fetch typebots", description: error.message }) showToast({
title: "Couldn't fetch typebots",
description: error.message,
})
}, },
}) })
@@ -85,7 +85,7 @@ export const FolderContent = ({ folder }: Props) => {
const { error } = await patchTypebot(typebotId, { const { error } = await patchTypebot(typebotId, {
folderId: folderId === 'root' ? null : folderId, folderId: folderId === 'root' ? null : folderId,
}) })
if (error) toast({ description: error.message }) if (error) showToast({ description: error.message })
mutateTypebots({ typebots: typebots.filter((t) => t.id !== typebotId) }) mutateTypebots({ typebots: typebots.filter((t) => t.id !== typebotId) })
} }
@@ -97,7 +97,10 @@ export const FolderContent = ({ folder }: Props) => {
}) })
setIsCreatingFolder(false) setIsCreatingFolder(false)
if (error) if (error)
return toast({ title: 'An error occured', description: error.message }) return showToast({
title: 'An error occured',
description: error.message,
})
if (newFolder) mutateFolders({ folders: [...folders, newFolder] }) if (newFolder) mutateFolders({ folders: [...folders, newFolder] })
} }

View File

@@ -12,7 +12,6 @@ import {
Menu, Menu,
MenuButton, MenuButton,
MenuList, MenuList,
useToast,
SkeletonText, SkeletonText,
SkeletonCircle, SkeletonCircle,
WrapItem, WrapItem,
@@ -23,6 +22,7 @@ import { useTypebotDnd } from 'contexts/TypebotDndContext'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import React, { useMemo } from 'react' import React, { useMemo } from 'react'
import { deleteFolder, updateFolder } from 'services/folders' import { deleteFolder, updateFolder } from 'services/folders'
import { useToast } from 'components/shared/hooks/useToast'
export const FolderButton = ({ export const FolderButton = ({
folder, folder,
@@ -41,15 +41,12 @@ export const FolderButton = ({
[draggedTypebot, folder.id, mouseOverFolderId] [draggedTypebot, folder.id, mouseOverFolderId]
) )
const { isOpen, onOpen, onClose } = useDisclosure() const { isOpen, onOpen, onClose } = useDisclosure()
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
const onDeleteClick = async () => { const onDeleteClick = async () => {
const { error } = await deleteFolder(folder.id) const { error } = await deleteFolder(folder.id)
return error return error
? toast({ ? showToast({
title: "Couldn't delete the folder", title: "Couldn't delete the folder",
description: error.message, description: error.message,
}) })
@@ -60,7 +57,7 @@ export const FolderButton = ({
if (newName === '' || newName === folder.name) return if (newName === '' || newName === folder.name) return
const { error } = await updateFolder(folder.id, { name: newName }) const { error } = await updateFolder(folder.id, { name: newName })
return error return error
? toast({ title: 'An error occured', description: error.message }) ? showToast({ title: 'An error occured', description: error.message })
: onFolderRenamed(newName) : onFolderRenamed(newName)
} }

View File

@@ -7,7 +7,6 @@ import {
Tag, Tag,
Text, Text,
useDisclosure, useDisclosure,
useToast,
VStack, VStack,
WrapItem, WrapItem,
} from '@chakra-ui/react' } from '@chakra-ui/react'
@@ -23,6 +22,7 @@ import { useDebounce } from 'use-debounce'
import { EmojiOrImageIcon } from 'components/shared/EmojiOrImageIcon' import { EmojiOrImageIcon } from 'components/shared/EmojiOrImageIcon'
import { Plan } from 'db' import { Plan } from 'db'
import { useWorkspace } from 'contexts/WorkspaceContext' import { useWorkspace } from 'contexts/WorkspaceContext'
import { useToast } from 'components/shared/hooks/useToast'
type ChatbotCardProps = { type ChatbotCardProps = {
typebot: Pick<Typebot, 'id' | 'publishedTypebotId' | 'name' | 'icon'> typebot: Pick<Typebot, 'id' | 'publishedTypebotId' | 'name' | 'icon'>
@@ -47,10 +47,7 @@ export const TypebotButton = ({
onClose: onDeleteClose, onClose: onDeleteClose,
} = useDisclosure() } = useDisclosure()
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
const handleTypebotClick = () => { const handleTypebotClick = () => {
if (draggedTypebotDebounced) return if (draggedTypebotDebounced) return
@@ -65,7 +62,7 @@ export const TypebotButton = ({
if (isReadOnly) return if (isReadOnly) return
const { error } = await deleteTypebot(typebot.id) const { error } = await deleteTypebot(typebot.id)
if (error) if (error)
return toast({ return showToast({
title: "Couldn't delete typebot", title: "Couldn't delete typebot",
description: error.message, description: error.message,
}) })
@@ -82,7 +79,7 @@ export const TypebotButton = ({
workspace?.plan ?? Plan.FREE workspace?.plan ?? Plan.FREE
) )
if (error) if (error)
return toast({ return showToast({
title: "Couldn't duplicate typebot", title: "Couldn't duplicate typebot",
description: error.message, description: error.message,
}) })

View File

@@ -5,7 +5,6 @@ import {
ModalContent, ModalContent,
ModalOverlay, ModalOverlay,
useDisclosure, useDisclosure,
useToast,
} from '@chakra-ui/react' } from '@chakra-ui/react'
import { TypebotViewer } from 'bot-engine' import { TypebotViewer } from 'bot-engine'
import { useUser } from 'contexts/UserContext' import { useUser } from 'contexts/UserContext'
@@ -14,6 +13,7 @@ import React, { useEffect, useRef, useState } from 'react'
import { parseTypebotToPublicTypebot } from 'services/publicTypebot' import { parseTypebotToPublicTypebot } from 'services/publicTypebot'
import { sendRequest } from 'utils' import { sendRequest } from 'utils'
import confetti from 'canvas-confetti' import confetti from 'canvas-confetti'
import { useToast } from 'components/shared/hooks/useToast'
type Props = { totalTypebots: number } type Props = { totalTypebots: number }
@@ -26,10 +26,7 @@ export const OnboardingModal = ({ totalTypebots }: Props) => {
const [chosenCategories, setChosenCategories] = useState<string[]>([]) const [chosenCategories, setChosenCategories] = useState<string[]>([])
const [openedOnce, setOpenedOnce] = useState(false) const [openedOnce, setOpenedOnce] = useState(false)
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
useEffect(() => { useEffect(() => {
fetchTemplate() fetchTemplate()
@@ -77,7 +74,8 @@ export const OnboardingModal = ({ totalTypebots }: Props) => {
const fetchTemplate = async () => { const fetchTemplate = async () => {
const { data, error } = await sendRequest(`/bots/onboarding.json`) const { data, error } = await sendRequest(`/bots/onboarding.json`)
if (error) return toast({ title: error.name, description: error.message }) if (error)
return showToast({ title: error.name, description: error.message })
setTypebot(data as Typebot) setTypebot(data as Typebot)
} }

View File

@@ -6,11 +6,11 @@ import {
Flex, Flex,
FlexProps, FlexProps,
useEventListener, useEventListener,
useToast,
UseToastOptions, UseToastOptions,
VStack, VStack,
} from '@chakra-ui/react' } from '@chakra-ui/react'
import { TypebotViewer } from 'bot-engine' import { TypebotViewer } from 'bot-engine'
import { useToast } from 'components/shared/hooks/useToast'
import { headerHeight } from 'components/shared/TypebotHeader' import { headerHeight } from 'components/shared/TypebotHeader'
import { useEditor } from 'contexts/EditorContext' import { useEditor } from 'contexts/EditorContext'
import { useGraph } from 'contexts/GraphContext' import { useGraph } from 'contexts/GraphContext'
@@ -33,9 +33,7 @@ export const PreviewDrawer = () => {
[typebot] [typebot]
) )
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
})
const handleMouseDown = () => { const handleMouseDown = () => {
setIsResizing(true) setIsResizing(true)
@@ -60,7 +58,7 @@ export const PreviewDrawer = () => {
} }
const handleNewLog = (log: Omit<Log, 'id' | 'createdAt' | 'resultId'>) => const handleNewLog = (log: Omit<Log, 'id' | 'createdAt' | 'resultId'>) =>
toast(log as UseToastOptions) showToast(log as UseToastOptions)
return ( return (
<Flex <Flex

View File

@@ -5,12 +5,12 @@ import {
IconButton, IconButton,
Stack, Stack,
Tag, Tag,
useToast,
Wrap, Wrap,
Text, Text,
} from '@chakra-ui/react' } from '@chakra-ui/react'
import { TrashIcon } from 'assets/icons' import { TrashIcon } from 'assets/icons'
import { UpgradeButton } from 'components/shared/buttons/UpgradeButton' import { UpgradeButton } from 'components/shared/buttons/UpgradeButton'
import { useToast } from 'components/shared/hooks/useToast'
import { useTypebot } from 'contexts/TypebotContext/TypebotContext' import { useTypebot } from 'contexts/TypebotContext/TypebotContext'
import { useWorkspace } from 'contexts/WorkspaceContext' import { useWorkspace } from 'contexts/WorkspaceContext'
import React from 'react' import React from 'react'
@@ -24,15 +24,12 @@ import { integrationsList } from './integrations/EmbedButton'
export const ShareContent = () => { export const ShareContent = () => {
const { workspace } = useWorkspace() const { workspace } = useWorkspace()
const { typebot, updateOnBothTypebots } = useTypebot() const { typebot, updateOnBothTypebots } = useTypebot()
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
const handlePublicIdChange = (publicId: string) => { const handlePublicIdChange = (publicId: string) => {
if (publicId === typebot?.publicId) return if (publicId === typebot?.publicId) return
if (publicId.length < 4) if (publicId.length < 4)
return toast({ description: 'ID must be longer than 4 characters' }) return showToast({ description: 'ID must be longer than 4 characters' })
updateOnBothTypebots({ publicId }) updateOnBothTypebots({ publicId })
} }

View File

@@ -12,10 +12,10 @@ import {
Alert, Alert,
ModalFooter, ModalFooter,
Button, Button,
useToast,
Text, Text,
Tooltip, Tooltip,
} from '@chakra-ui/react' } from '@chakra-ui/react'
import { useToast } from 'components/shared/hooks/useToast'
import { useEffect, useRef, useState } from 'react' import { useEffect, useRef, useState } from 'react'
import { createCustomDomain } from 'services/user' import { createCustomDomain } from 'services/user'
import { isEmpty } from 'utils' import { isEmpty } from 'utils'
@@ -46,11 +46,7 @@ export const CustomDomainModal = ({
subdomain: splitHostname(domain)?.subdomain ?? '', subdomain: splitHostname(domain)?.subdomain ?? '',
}) })
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
description: 'An error occured',
})
useEffect(() => { useEffect(() => {
if (inputValue === '' || !isOpen) return if (inputValue === '' || !isOpen) return
@@ -72,7 +68,8 @@ export const CustomDomainModal = ({
name: inputValue, name: inputValue,
}) })
setIsLoading(false) setIsLoading(false)
if (error) return toast({ title: error.name, description: error.message }) if (error)
return showToast({ title: error.name, description: error.message })
onNewDomain(inputValue) onNewDomain(inputValue)
onClose() onClose()
} }

View File

@@ -9,13 +9,13 @@ import {
Stack, Stack,
Text, Text,
useDisclosure, useDisclosure,
useToast,
} from '@chakra-ui/react' } from '@chakra-ui/react'
import { ChevronLeftIcon, PlusIcon, TrashIcon } from 'assets/icons' import { ChevronLeftIcon, PlusIcon, TrashIcon } from 'assets/icons'
import React, { useState } from 'react' import React, { useState } from 'react'
import { CustomDomainModal } from './CustomDomainModal' import { CustomDomainModal } from './CustomDomainModal'
import { deleteCustomDomain, useCustomDomains } from 'services/user' import { deleteCustomDomain, useCustomDomains } from 'services/user'
import { useWorkspace } from 'contexts/WorkspaceContext' import { useWorkspace } from 'contexts/WorkspaceContext'
import { useToast } from 'components/shared/hooks/useToast'
type Props = Omit<MenuButtonProps, 'type'> & { type Props = Omit<MenuButtonProps, 'type'> & {
currentCustomDomain?: string currentCustomDomain?: string
@@ -30,14 +30,11 @@ export const CustomDomainsDropdown = ({
const [isDeleting, setIsDeleting] = useState('') const [isDeleting, setIsDeleting] = useState('')
const { isOpen, onOpen, onClose } = useDisclosure() const { isOpen, onOpen, onClose } = useDisclosure()
const { workspace } = useWorkspace() const { workspace } = useWorkspace()
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
const { customDomains, mutate } = useCustomDomains({ const { customDomains, mutate } = useCustomDomains({
workspaceId: workspace?.id, workspaceId: workspace?.id,
onError: (error) => onError: (error) =>
toast({ title: error.name, description: error.message }), showToast({ title: error.name, description: error.message }),
}) })
const handleMenuItemClick = (customDomain: string) => () => const handleMenuItemClick = (customDomain: string) => () =>
@@ -50,7 +47,8 @@ export const CustomDomainsDropdown = ({
setIsDeleting(domainName) setIsDeleting(domainName)
const { error } = await deleteCustomDomain(workspace.id, domainName) const { error } = await deleteCustomDomain(workspace.id, domainName)
setIsDeleting('') setIsDeleting('')
if (error) return toast({ title: error.name, description: error.message }) if (error)
return showToast({ title: error.name, description: error.message })
mutate({ mutate({
customDomains: (customDomains ?? []).filter( customDomains: (customDomains ?? []).filter(
(cd) => cd.name !== domainName (cd) => cd.name !== domainName

View File

@@ -8,7 +8,6 @@ import {
MenuList, MenuList,
Stack, Stack,
Text, Text,
useToast,
} from '@chakra-ui/react' } from '@chakra-ui/react'
import { ChevronLeftIcon, PlusIcon, TrashIcon } from 'assets/icons' import { ChevronLeftIcon, PlusIcon, TrashIcon } from 'assets/icons'
import React, { useEffect, useMemo, useState } from 'react' import React, { useEffect, useMemo, useState } from 'react'
@@ -16,6 +15,7 @@ import { useRouter } from 'next/router'
import { CredentialsType } from 'models' import { CredentialsType } from 'models'
import { deleteCredentials, useCredentials } from 'services/user' import { deleteCredentials, useCredentials } from 'services/user'
import { useWorkspace } from 'contexts/WorkspaceContext' import { useWorkspace } from 'contexts/WorkspaceContext'
import { useToast } from './hooks/useToast'
type Props = Omit<MenuButtonProps, 'type'> & { type Props = Omit<MenuButtonProps, 'type'> & {
type: CredentialsType type: CredentialsType
@@ -37,10 +37,7 @@ export const CredentialsDropdown = ({
}: Props) => { }: Props) => {
const router = useRouter() const router = useRouter()
const { workspace } = useWorkspace() const { workspace } = useWorkspace()
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
const { credentials, mutate } = useCredentials({ const { credentials, mutate } = useCredentials({
workspaceId: workspace?.id, workspaceId: workspace?.id,
}) })
@@ -88,7 +85,8 @@ export const CredentialsDropdown = ({
setIsDeleting(credentialsId) setIsDeleting(credentialsId)
const { error } = await deleteCredentials(workspace.id, credentialsId) const { error } = await deleteCredentials(workspace.id, credentialsId)
setIsDeleting(undefined) setIsDeleting(undefined)
if (error) return toast({ title: error.name, description: error.message }) if (error)
return showToast({ title: error.name, description: error.message })
onCredentialsSelect(undefined) onCredentialsSelect(undefined)
mutate({ credentials: credentials.filter((c) => c.id !== credentialsId) }) mutate({ credentials: credentials.filter((c) => c.id !== credentialsId) })
} }

View File

@@ -7,7 +7,6 @@ import {
ModalBody, ModalBody,
ModalFooter, ModalFooter,
Button, Button,
useToast,
FormControl, FormControl,
FormLabel, FormLabel,
Stack, Stack,
@@ -24,6 +23,7 @@ import { MoreInfoTooltip } from 'components/shared/MoreInfoTooltip'
import { ExternalLinkIcon } from 'assets/icons' import { ExternalLinkIcon } from 'assets/icons'
import { createCredentials } from 'services/credentials' import { createCredentials } from 'services/credentials'
import { omit } from 'utils' import { omit } from 'utils'
import { useToast } from 'components/shared/hooks/useToast'
type Props = { type Props = {
isOpen: boolean isOpen: boolean
@@ -39,10 +39,7 @@ export const StripeConfigModal = ({
const { user } = useUser() const { user } = useUser()
const { workspace } = useWorkspace() const { workspace } = useWorkspace()
const [isCreating, setIsCreating] = useState(false) const [isCreating, setIsCreating] = useState(false)
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
const [stripeConfig, setStripeConfig] = useState< const [stripeConfig, setStripeConfig] = useState<
StripeCredentialsData & { name: string } StripeCredentialsData & { name: string }
>({ >({
@@ -91,9 +88,10 @@ export const StripeConfigModal = ({
workspaceId: workspace.id, workspaceId: workspace.id,
}) })
setIsCreating(false) setIsCreating(false)
if (error) return toast({ title: error.name, description: error.message }) if (error)
return showToast({ title: error.name, description: error.message })
if (!data?.credentials) if (!data?.credentials)
return toast({ description: "Credentials wasn't created" }) return showToast({ description: "Credentials wasn't created" })
onNewCredentials(data.credentials.id) onNewCredentials(data.credentials.id)
onClose() onClose()
} }

View File

@@ -7,7 +7,6 @@ import {
ModalBody, ModalBody,
ModalFooter, ModalFooter,
Button, Button,
useToast,
} from '@chakra-ui/react' } from '@chakra-ui/react'
import { useUser } from 'contexts/UserContext' import { useUser } from 'contexts/UserContext'
import { CredentialsType, SmtpCredentialsData } from 'models' import { CredentialsType, SmtpCredentialsData } from 'models'
@@ -17,6 +16,7 @@ import { testSmtpConfig } from 'services/integrations'
import { isNotDefined } from 'utils' import { isNotDefined } from 'utils'
import { SmtpConfigForm } from './SmtpConfigForm' import { SmtpConfigForm } from './SmtpConfigForm'
import { useWorkspace } from 'contexts/WorkspaceContext' import { useWorkspace } from 'contexts/WorkspaceContext'
import { useToast } from 'components/shared/hooks/useToast'
type Props = { type Props = {
isOpen: boolean isOpen: boolean
@@ -32,10 +32,7 @@ export const SmtpConfigModal = ({
const { user } = useUser() const { user } = useUser()
const { workspace } = useWorkspace() const { workspace } = useWorkspace()
const [isCreating, setIsCreating] = useState(false) const [isCreating, setIsCreating] = useState(false)
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
const [smtpConfig, setSmtpConfig] = useState<SmtpCredentialsData>({ const [smtpConfig, setSmtpConfig] = useState<SmtpCredentialsData>({
from: {}, from: {},
port: 25, port: 25,
@@ -50,7 +47,7 @@ export const SmtpConfigModal = ({
) )
if (testSmtpError) { if (testSmtpError) {
setIsCreating(false) setIsCreating(false)
return toast({ return showToast({
title: 'Invalid configuration', title: 'Invalid configuration',
description: "We couldn't send the test email with your configuration", description: "We couldn't send the test email with your configuration",
}) })
@@ -62,9 +59,10 @@ export const SmtpConfigModal = ({
workspaceId: workspace.id, workspaceId: workspace.id,
}) })
setIsCreating(false) setIsCreating(false)
if (error) return toast({ title: error.name, description: error.message }) if (error)
return showToast({ title: error.name, description: error.message })
if (!data?.credentials) if (!data?.credentials)
return toast({ description: "Credentials wasn't created" }) return showToast({ description: "Credentials wasn't created" })
onNewCredentials(data.credentials.id) onNewCredentials(data.credentials.id)
onClose() onClose()
} }

View File

@@ -1,6 +1,7 @@
import { HStack, IconButton, Input, useToast } from '@chakra-ui/react' import { HStack, IconButton, Input } from '@chakra-ui/react'
import { ExternalLinkIcon } from 'assets/icons' import { ExternalLinkIcon } from 'assets/icons'
import { NextChakraLink } from 'components/nextChakra/NextChakraLink' import { NextChakraLink } from 'components/nextChakra/NextChakraLink'
import { useToast } from 'components/shared/hooks/useToast'
import { SearchableDropdown } from 'components/shared/SearchableDropdown' import { SearchableDropdown } from 'components/shared/SearchableDropdown'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { useMemo } from 'react' import { useMemo } from 'react'
@@ -19,14 +20,11 @@ export const TypebotsDropdown = ({
currentWorkspaceId, currentWorkspaceId,
}: Props) => { }: Props) => {
const { query } = useRouter() const { query } = useRouter()
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
const { typebots, isLoading } = useTypebots({ const { typebots, isLoading } = useTypebots({
workspaceId: currentWorkspaceId, workspaceId: currentWorkspaceId,
allFolders: true, allFolders: true,
onError: (e) => toast({ title: e.name, description: e.message }), onError: (e) => showToast({ title: e.name, description: e.message }),
}) })
const currentTypebot = useMemo( const currentTypebot = useMemo(
() => typebots?.find(byId(typebotId)), () => typebots?.find(byId(typebotId)),

View File

@@ -9,7 +9,6 @@ import {
HStack, HStack,
Spinner, Spinner,
Stack, Stack,
useToast,
Text, Text,
Alert, Alert,
AlertIcon, AlertIcon,
@@ -43,6 +42,7 @@ import { DataVariableInputs } from './ResponseMappingInputs'
import { byId } from 'utils' import { byId } from 'utils'
import { SwitchWithLabel } from 'components/shared/SwitchWithLabel' import { SwitchWithLabel } from 'components/shared/SwitchWithLabel'
import { ExternalLinkIcon } from 'assets/icons' import { ExternalLinkIcon } from 'assets/icons'
import { useToast } from 'components/shared/hooks/useToast'
type Provider = { type Provider = {
name: 'Make.com' | 'Pabbly Connect' name: 'Make.com' | 'Pabbly Connect'
@@ -64,10 +64,7 @@ export const WebhookSettings = ({
const [testResponse, setTestResponse] = useState<string>() const [testResponse, setTestResponse] = useState<string>()
const [responseKeys, setResponseKeys] = useState<string[]>([]) const [responseKeys, setResponseKeys] = useState<string[]>([])
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
const [localWebhook, setLocalWebhook] = useState( const [localWebhook, setLocalWebhook] = useState(
webhooks.find(byId(webhookId)) webhooks.find(byId(webhookId))
) )
@@ -140,7 +137,8 @@ export const WebhookSettings = ({
), ),
{ blockId, stepId } { blockId, stepId }
) )
if (error) return toast({ title: error.name, description: error.message }) if (error)
return showToast({ title: error.name, description: error.message })
setTestResponse(JSON.stringify(data, undefined, 2)) setTestResponse(JSON.stringify(data, undefined, 2))
setResponseKeys(getDeepKeys(data)) setResponseKeys(getDeepKeys(data))
setIsTestResponseLoading(false) setIsTestResponseLoading(false)

View File

@@ -3,7 +3,6 @@ import {
HStack, HStack,
Input, Input,
Button, Button,
useToast,
Menu, Menu,
MenuButton, MenuButton,
MenuItem, MenuItem,
@@ -16,6 +15,7 @@ import {
} from '@chakra-ui/react' } from '@chakra-ui/react'
import { ChevronLeftIcon } from 'assets/icons' import { ChevronLeftIcon } from 'assets/icons'
import { EmojiOrImageIcon } from 'components/shared/EmojiOrImageIcon' import { EmojiOrImageIcon } from 'components/shared/EmojiOrImageIcon'
import { useToast } from 'components/shared/hooks/useToast'
import { useTypebot } from 'contexts/TypebotContext' import { useTypebot } from 'contexts/TypebotContext'
import { useWorkspace } from 'contexts/WorkspaceContext' import { useWorkspace } from 'contexts/WorkspaceContext'
import { CollaborationType, WorkspaceRole } from 'db' import { CollaborationType, WorkspaceRole } from 'db'
@@ -45,10 +45,7 @@ export const CollaborationList = () => {
const hasFullAccess = const hasFullAccess =
(currentRole && currentRole !== WorkspaceRole.GUEST) || false (currentRole && currentRole !== WorkspaceRole.GUEST) || false
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
const { const {
collaborators, collaborators,
isLoading: isCollaboratorsLoading, isLoading: isCollaboratorsLoading,
@@ -56,7 +53,7 @@ export const CollaborationList = () => {
} = useCollaborators({ } = useCollaborators({
typebotId: typebot?.id, typebotId: typebot?.id,
onError: (e) => onError: (e) =>
toast({ showToast({
title: "Couldn't fetch collaborators", title: "Couldn't fetch collaborators",
description: e.message, description: e.message,
}), }),
@@ -68,7 +65,10 @@ export const CollaborationList = () => {
} = useInvitations({ } = useInvitations({
typebotId: typebot?.id, typebotId: typebot?.id,
onError: (e) => onError: (e) =>
toast({ title: "Couldn't fetch invitations", description: e.message }), showToast({
title: "Couldn't fetch invitations",
description: e.message,
}),
}) })
const handleChangeInvitationCollabType = const handleChangeInvitationCollabType =
@@ -79,7 +79,8 @@ export const CollaborationList = () => {
typebotId: typebot.id, typebotId: typebot.id,
type, type,
}) })
if (error) return toast({ title: error.name, description: error.message }) if (error)
return showToast({ title: error.name, description: error.message })
mutateInvitations({ mutateInvitations({
invitations: (invitations ?? []).map((i) => invitations: (invitations ?? []).map((i) =>
i.email === email ? { ...i, type } : i i.email === email ? { ...i, type } : i
@@ -89,7 +90,8 @@ export const CollaborationList = () => {
const handleDeleteInvitation = (email: string) => async () => { const handleDeleteInvitation = (email: string) => async () => {
if (!typebot || !hasFullAccess) return if (!typebot || !hasFullAccess) return
const { error } = await deleteInvitation(typebot?.id, email) const { error } = await deleteInvitation(typebot?.id, email)
if (error) return toast({ title: error.name, description: error.message }) if (error)
return showToast({ title: error.name, description: error.message })
mutateInvitations({ mutateInvitations({
invitations: (invitations ?? []).filter((i) => i.email !== email), invitations: (invitations ?? []).filter((i) => i.email !== email),
}) })
@@ -103,7 +105,8 @@ export const CollaborationList = () => {
type, type,
typebotId: typebot.id, typebotId: typebot.id,
}) })
if (error) return toast({ title: error.name, description: error.message }) if (error)
return showToast({ title: error.name, description: error.message })
mutateCollaborators({ mutateCollaborators({
collaborators: (collaborators ?? []).map((c) => collaborators: (collaborators ?? []).map((c) =>
c.userId === userId ? { ...c, type } : c c.userId === userId ? { ...c, type } : c
@@ -113,7 +116,8 @@ export const CollaborationList = () => {
const handleDeleteCollaboration = (userId: string) => async () => { const handleDeleteCollaboration = (userId: string) => async () => {
if (!typebot || !hasFullAccess) return if (!typebot || !hasFullAccess) return
const { error } = await deleteCollaborator(typebot?.id, userId) const { error } = await deleteCollaborator(typebot?.id, userId)
if (error) return toast({ title: error.name, description: error.message }) if (error)
return showToast({ title: error.name, description: error.message })
mutateCollaborators({ mutateCollaborators({
collaborators: (collaborators ?? []).filter((c) => c.userId !== userId), collaborators: (collaborators ?? []).filter((c) => c.userId !== userId),
}) })
@@ -130,8 +134,9 @@ export const CollaborationList = () => {
setIsSendingInvitation(false) setIsSendingInvitation(false)
mutateInvitations({ invitations: invitations ?? [] }) mutateInvitations({ invitations: invitations ?? [] })
mutateCollaborators({ collaborators: collaborators ?? [] }) mutateCollaborators({ collaborators: collaborators ?? [] })
if (error) return toast({ title: error.name, description: error.message }) if (error)
toast({ status: 'success', title: 'Invitation sent! 📧' }) return showToast({ title: error.name, description: error.message })
showToast({ status: 'success', title: 'Invitation sent! 📧' })
setInvitationEmail('') setInvitationEmail('')
} }

View File

@@ -0,0 +1,20 @@
import { useToast as useChakraToast, UseToastOptions } from '@chakra-ui/toast'
export const useToast = () => {
const toast = useChakraToast()
const showToast = ({
title,
description,
status = 'error',
}: UseToastOptions) => {
toast({
position: 'bottom-right',
description,
title,
status,
})
}
return { showToast }
}

View File

@@ -16,7 +16,6 @@ import {
ListProps, ListProps,
Button, Button,
HStack, HStack,
useToast,
} from '@chakra-ui/react' } from '@chakra-ui/react'
import { pay } from 'services/stripe' import { pay } from 'services/stripe'
import { useUser } from 'contexts/UserContext' import { useUser } from 'contexts/UserContext'
@@ -25,6 +24,7 @@ import { useWorkspace } from 'contexts/WorkspaceContext'
import { TypebotLogo } from 'assets/logos' import { TypebotLogo } from 'assets/logos'
import { CheckIcon } from 'assets/icons' import { CheckIcon } from 'assets/icons'
import { toTitleCase } from 'utils' import { toTitleCase } from 'utils'
import { useToast } from 'components/shared/hooks/useToast'
export enum LimitReached { export enum LimitReached {
BRAND = 'Remove branding', BRAND = 'Remove branding',
@@ -48,7 +48,7 @@ export const UpgradeModal = ({
const { workspace, refreshWorkspace } = useWorkspace() const { workspace, refreshWorkspace } = useWorkspace()
const [payLoading, setPayLoading] = useState(false) const [payLoading, setPayLoading] = useState(false)
const [currency, setCurrency] = useState<'usd' | 'eur'>('usd') const [currency, setCurrency] = useState<'usd' | 'eur'>('usd')
const toast = useToast() const { showToast } = useToast()
useEffect(() => { useEffect(() => {
setCurrency( setCurrency(
@@ -69,7 +69,7 @@ export const UpgradeModal = ({
setPayLoading(false) setPayLoading(false)
if (response?.newPlan) { if (response?.newPlan) {
refreshWorkspace({ plan: response.newPlan }) refreshWorkspace({ plan: response.newPlan })
toast({ showToast({
status: 'success', status: 'success',
title: 'Upgrade success!', title: 'Upgrade success!',
description: `Workspace successfully upgraded to ${toTitleCase( description: `Workspace successfully upgraded to ${toTitleCase(

View File

@@ -1,12 +1,6 @@
import { import { VStack, Heading, Stack, Button, useDisclosure } from '@chakra-ui/react'
VStack,
Heading,
Stack,
Button,
useDisclosure,
useToast,
} from '@chakra-ui/react'
import { ToolIcon, TemplateIcon, DownloadIcon } from 'assets/icons' import { ToolIcon, TemplateIcon, DownloadIcon } from 'assets/icons'
import { useToast } from 'components/shared/hooks/useToast'
import { useUser } from 'contexts/UserContext' import { useUser } from 'contexts/UserContext'
import { useWorkspace } from 'contexts/WorkspaceContext' import { useWorkspace } from 'contexts/WorkspaceContext'
import { Typebot } from 'models' import { Typebot } from 'models'
@@ -24,11 +18,7 @@ export const CreateNewTypebotButtons = () => {
const [isLoading, setIsLoading] = useState(false) const [isLoading, setIsLoading] = useState(false)
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
title: 'An error occured',
})
const handleCreateSubmit = async (typebot?: Typebot) => { const handleCreateSubmit = async (typebot?: Typebot) => {
if (!user || !workspace) return if (!user || !workspace) return
@@ -54,7 +44,7 @@ export const CreateNewTypebotButtons = () => {
folderId, folderId,
workspaceId: workspace.id, workspaceId: workspace.id,
}) })
if (error) toast({ description: error.message }) if (error) showToast({ description: error.message })
if (data) if (data)
router.push({ router.push({
pathname: `/typebots/${data.id}/edit`, pathname: `/typebots/${data.id}/edit`,

View File

@@ -1,4 +1,5 @@
import { Button, ButtonProps, chakra, useToast } from '@chakra-ui/react' import { Button, ButtonProps, chakra } from '@chakra-ui/react'
import { useToast } from 'components/shared/hooks/useToast'
import { Typebot } from 'models' import { Typebot } from 'models'
import React, { ChangeEvent } from 'react' import React, { ChangeEvent } from 'react'
import { readFile } from 'services/utils' import { readFile } from 'services/utils'
@@ -11,10 +12,7 @@ export const ImportTypebotFromFileButton = ({
onNewTypebot, onNewTypebot,
...props ...props
}: Props) => { }: Props) => {
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
const handleInputChange = async (e: ChangeEvent<HTMLInputElement>) => { const handleInputChange = async (e: ChangeEvent<HTMLInputElement>) => {
if (!e.target?.files) return if (!e.target?.files) return
@@ -24,7 +22,7 @@ export const ImportTypebotFromFileButton = ({
onNewTypebot(JSON.parse(fileContent)) onNewTypebot(JSON.parse(fileContent))
} catch (err) { } catch (err) {
console.error(err) console.error(err)
toast({ description: 'Failed to parse the file' }) showToast({ description: 'Failed to parse the file' })
} }
} }

View File

@@ -10,10 +10,10 @@ import {
ModalOverlay, ModalOverlay,
Stack, Stack,
Tooltip, Tooltip,
useToast,
} from '@chakra-ui/react' } from '@chakra-ui/react'
import { ExternalLinkIcon } from 'assets/icons' import { ExternalLinkIcon } from 'assets/icons'
import { TypebotViewer } from 'bot-engine' import { TypebotViewer } from 'bot-engine'
import { useToast } from 'components/shared/hooks/useToast'
import { Typebot } from 'models' import { Typebot } from 'models'
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { parseTypebotToPublicTypebot } from 'services/publicTypebot' import { parseTypebotToPublicTypebot } from 'services/publicTypebot'
@@ -33,10 +33,7 @@ export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => {
) )
const [isLoading, setIsLoading] = useState(false) const [isLoading, setIsLoading] = useState(false)
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
useEffect(() => { useEffect(() => {
fetchTemplate(templates[0]) fetchTemplate(templates[0])
@@ -46,7 +43,8 @@ export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => {
const fetchTemplate = async (template: TemplateProps) => { const fetchTemplate = async (template: TemplateProps) => {
setSelectedTemplate(template) setSelectedTemplate(template)
const { data, error } = await sendRequest(`/templates/${template.fileName}`) const { data, error } = await sendRequest(`/templates/${template.fileName}`)
if (error) return toast({ title: error.name, description: error.message }) if (error)
return showToast({ title: error.name, description: error.message })
setTypebot(data as Typebot) setTypebot(data as Typebot)
} }

View File

@@ -1,4 +1,3 @@
import { useToast } from '@chakra-ui/react'
import { import {
LogicStepType, LogicStepType,
PublicTypebot, PublicTypebot,
@@ -43,6 +42,7 @@ import { dequal } from 'dequal'
import { saveWebhook } from 'services/webhook' import { saveWebhook } from 'services/webhook'
import { stringify } from 'qs' import { stringify } from 'qs'
import cuid from 'cuid' import cuid from 'cuid'
import { useToast } from 'components/shared/hooks/useToast'
const autoSaveTimeout = 10000 const autoSaveTimeout = 10000
type UpdateTypebotPayload = Partial<{ type UpdateTypebotPayload = Partial<{
@@ -101,16 +101,13 @@ export const TypebotContext = ({
typebotId: string typebotId: string
}) => { }) => {
const router = useRouter() const router = useRouter()
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
const { typebot, publishedTypebot, webhooks, isReadOnly, isLoading, mutate } = const { typebot, publishedTypebot, webhooks, isReadOnly, isLoading, mutate } =
useFetchedTypebot({ useFetchedTypebot({
typebotId, typebotId,
onError: (error) => onError: (error) =>
toast({ showToast({
title: 'Error while fetching typebot', title: 'Error while fetching typebot',
description: error.message, description: error.message,
}), }),
@@ -145,7 +142,7 @@ export const TypebotContext = ({
typebotId, typebotId,
typebotIds: linkedTypebotIds, typebotIds: linkedTypebotIds,
onError: (error) => onError: (error) =>
toast({ showToast({
title: 'Error while fetching linkedTypebots', title: 'Error while fetching linkedTypebots',
description: error.message, description: error.message,
}), }),
@@ -181,7 +178,7 @@ export const TypebotContext = ({
const { error } = await updateTypebot(typebotToSave.id, typebotToSave) const { error } = await updateTypebot(typebotToSave.id, typebotToSave)
setIsSavingLoading(false) setIsSavingLoading(false)
if (error) { if (error) {
toast({ title: error.name, description: error.message }) showToast({ title: error.name, description: error.message })
return return
} }
if (!options?.disableMutation) if (!options?.disableMutation)
@@ -200,7 +197,8 @@ export const TypebotContext = ({
newPublishedTypebot newPublishedTypebot
) )
setIsPublishing(false) setIsPublishing(false)
if (error) return toast({ title: error.name, description: error.message }) if (error)
return showToast({ title: error.name, description: error.message })
mutate({ mutate({
typebot: currentTypebotRef.current as Typebot, typebot: currentTypebotRef.current as Typebot,
publishedTypebot: newPublishedTypebot, publishedTypebot: newPublishedTypebot,
@@ -252,7 +250,7 @@ export const TypebotContext = ({
useEffect(() => { useEffect(() => {
if (isLoading) return if (isLoading) return
if (!typebot) { if (!typebot) {
toast({ status: 'info', description: "Couldn't find typebot" }) showToast({ status: 'info', description: "Couldn't find typebot" })
router.replace('/typebots') router.replace('/typebots')
return return
} }
@@ -314,7 +312,8 @@ export const TypebotContext = ({
id: publishedTypebotId, id: publishedTypebotId,
}) })
setIsPublishing(false) setIsPublishing(false)
if (error) return toast({ title: error.name, description: error.message }) if (error)
return showToast({ title: error.name, description: error.message })
mutate({ mutate({
typebot: localTypebot, typebot: localTypebot,
publishedTypebot: data, publishedTypebot: data,

View File

@@ -10,10 +10,10 @@ import {
} from 'react' } from 'react'
import { isDefined, isNotDefined } from 'utils' import { isDefined, isNotDefined } from 'utils'
import { updateUser as updateUserInDb } from 'services/user/user' import { updateUser as updateUserInDb } from 'services/user/user'
import { useToast } from '@chakra-ui/react'
import { dequal } from 'dequal' import { dequal } from 'dequal'
import { User } from 'db' import { User } from 'db'
import { setUser as setSentryUser } from '@sentry/nextjs' import { setUser as setSentryUser } from '@sentry/nextjs'
import { useToast } from 'components/shared/hooks/useToast'
const userContext = createContext<{ const userContext = createContext<{
user?: User user?: User
@@ -32,10 +32,7 @@ export const UserContext = ({ children }: { children: ReactNode }) => {
const router = useRouter() const router = useRouter()
const { data: session, status } = useSession() const { data: session, status } = useSession()
const [user, setUser] = useState<User | undefined>() const [user, setUser] = useState<User | undefined>()
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
const [currentWorkspaceId, setCurrentWorkspaceId] = useState<string>() const [currentWorkspaceId, setCurrentWorkspaceId] = useState<string>()
const [isSaving, setIsSaving] = useState(false) const [isSaving, setIsSaving] = useState(false)
@@ -88,7 +85,7 @@ export const UserContext = ({ children }: { children: ReactNode }) => {
setIsSaving(true) setIsSaving(true)
if (newUser) updateUser(newUser) if (newUser) updateUser(newUser)
const { error } = await updateUserInDb(user.id, { ...user, ...newUser }) const { error } = await updateUserInDb(user.id, { ...user, ...newUser })
if (error) toast({ title: error.name, description: error.message }) if (error) showToast({ title: error.name, description: error.message })
await refreshUser() await refreshUser()
setIsSaving(false) setIsSaving(false)
} }

View File

@@ -1,6 +1,7 @@
import { Flex, useDisclosure, useToast } from '@chakra-ui/react' import { Flex, useDisclosure } from '@chakra-ui/react'
import { StatsCards } from 'components/analytics/StatsCards' import { StatsCards } from 'components/analytics/StatsCards'
import { Graph } from 'components/shared/Graph' import { Graph } from 'components/shared/Graph'
import { useToast } from 'components/shared/hooks/useToast'
import { UpgradeModal } from 'components/shared/modals/UpgradeModal' import { UpgradeModal } from 'components/shared/modals/UpgradeModal'
import { GraphProvider } from 'contexts/GraphContext' import { GraphProvider } from 'contexts/GraphContext'
import { useTypebot } from 'contexts/TypebotContext/TypebotContext' import { useTypebot } from 'contexts/TypebotContext/TypebotContext'
@@ -11,14 +12,10 @@ import { useAnswersCount } from 'services/analytics'
export const AnalyticsContent = ({ stats }: { stats?: Stats }) => { export const AnalyticsContent = ({ stats }: { stats?: Stats }) => {
const { isOpen, onOpen, onClose } = useDisclosure() const { isOpen, onOpen, onClose } = useDisclosure()
const { typebot, publishedTypebot } = useTypebot() const { typebot, publishedTypebot } = useTypebot()
const { showToast } = useToast()
const toast = useToast({
position: 'top-right',
status: 'error',
})
const { answersCounts } = useAnswersCount({ const { answersCounts } = useAnswersCount({
typebotId: publishedTypebot && typebot?.id, typebotId: publishedTypebot && typebot?.id,
onError: (err) => toast({ title: err.name, description: err.message }), onError: (err) => showToast({ title: err.name, description: err.message }),
}) })
return ( return (
<Flex <Flex

View File

@@ -1,5 +1,6 @@
import { Button, Flex, HStack, Tag, useToast, Text } from '@chakra-ui/react' import { Button, Flex, HStack, Tag, Text } from '@chakra-ui/react'
import { NextChakraLink } from 'components/nextChakra/NextChakraLink' import { NextChakraLink } from 'components/nextChakra/NextChakraLink'
import { useToast } from 'components/shared/hooks/useToast'
import { useTypebot } from 'contexts/TypebotContext/TypebotContext' import { useTypebot } from 'contexts/TypebotContext/TypebotContext'
import { useWorkspace } from 'contexts/WorkspaceContext' import { useWorkspace } from 'contexts/WorkspaceContext'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
@@ -17,14 +18,11 @@ export const ResultsContent = () => {
() => router.pathname.endsWith('analytics'), () => router.pathname.endsWith('analytics'),
[router.pathname] [router.pathname]
) )
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
const { stats, mutate } = useStats({ const { stats, mutate } = useStats({
typebotId: publishedTypebot?.typebotId, typebotId: publishedTypebot?.typebotId,
onError: (err) => toast({ title: err.name, description: err.message }), onError: (err) => showToast({ title: err.name, description: err.message }),
}) })
const handleDeletedResults = (total: number) => { const handleDeletedResults = (total: number) => {

View File

@@ -1,4 +1,4 @@
import { Stack, useToast, Flex } from '@chakra-ui/react' import { Stack, Flex } from '@chakra-ui/react'
import { ResultsActionButtons } from 'components/results/ResultsActionButtons' import { ResultsActionButtons } from 'components/results/ResultsActionButtons'
import { SubmissionsTable } from 'components/results/SubmissionsTable' import { SubmissionsTable } from 'components/results/SubmissionsTable'
import React, { useCallback, useMemo, useState } from 'react' import React, { useCallback, useMemo, useState } from 'react'
@@ -15,6 +15,7 @@ import { LogsModal } from './LogsModal'
import { useTypebot } from 'contexts/TypebotContext' import { useTypebot } from 'contexts/TypebotContext'
import { isDefined, parseResultHeader } from 'utils' import { isDefined, parseResultHeader } from 'utils'
import { Plan } from 'db' import { Plan } from 'db'
import { useToast } from 'components/shared/hooks/useToast'
type Props = { type Props = {
typebotId: string typebotId: string
@@ -34,10 +35,7 @@ export const SubmissionsContent = ({
const [isExportLoading, setIsExportLoading] = useState(false) const [isExportLoading, setIsExportLoading] = useState(false)
const [inspectingLogsResultId, setInspectingLogsResultId] = useState<string>() const [inspectingLogsResultId, setInspectingLogsResultId] = useState<string>()
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
const blocksAndVariables = { const blocksAndVariables = {
blocks: [ blocks: [
@@ -54,7 +52,7 @@ export const SubmissionsContent = ({
const { data, mutate, setSize, hasMore } = useResults({ const { data, mutate, setSize, hasMore } = useResults({
typebotId, typebotId,
onError: (err) => toast({ title: err.name, description: err.message }), onError: (err) => showToast({ title: err.name, description: err.message }),
}) })
const results = useMemo(() => data?.flatMap((d) => d.results), [data]) const results = useMemo(() => data?.flatMap((d) => d.results), [data])
@@ -73,7 +71,7 @@ export const SubmissionsContent = ({
totalSelected === totalResults totalSelected === totalResults
? await deleteAllResults(typebotId) ? await deleteAllResults(typebotId)
: await deleteResults(typebotId, selectedIds) : await deleteResults(typebotId, selectedIds)
if (error) toast({ description: error.message, title: error.name }) if (error) showToast({ description: error.message, title: error.name })
else { else {
mutate( mutate(
totalSelected === totalResults totalSelected === totalResults

View File

@@ -5,21 +5,19 @@ import { Seo } from 'components/Seo'
import { FolderContent } from 'components/dashboard/FolderContent' import { FolderContent } from 'components/dashboard/FolderContent'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { useFolderContent } from 'services/folders' import { useFolderContent } from 'services/folders'
import { Spinner, useToast } from '@chakra-ui/react' import { Spinner } from '@chakra-ui/react'
import { TypebotDndContext } from 'contexts/TypebotDndContext' import { TypebotDndContext } from 'contexts/TypebotDndContext'
import { useToast } from 'components/shared/hooks/useToast'
const FolderPage = () => { const FolderPage = () => {
const router = useRouter() const router = useRouter()
const toast = useToast({ const { showToast } = useToast()
position: 'top-right',
status: 'error',
})
const { folder } = useFolderContent({ const { folder } = useFolderContent({
folderId: router.query.id?.toString(), folderId: router.query.id?.toString(),
onError: (error) => { onError: (error) => {
toast({ showToast({
title: "Couldn't fetch folder content", title: "Couldn't fetch folder content",
description: error.message, description: error.message,
}) })