🌐 Add pt_BR and more translations (#767)
Original PR: https://github.com/baptisteArno/typebot.io/pull/694 --------- Co-authored-by: Daniel Oliveira <daniel.oliveira@kununu.com> Co-authored-by: Daniel Oliveira <daniel@headdev.com.br>
This commit is contained in:
@ -22,7 +22,7 @@ const nextConfig = {
|
|||||||
],
|
],
|
||||||
i18n: {
|
i18n: {
|
||||||
defaultLocale: 'en',
|
defaultLocale: 'en',
|
||||||
locales: ['en', 'fr', 'pt', 'de'],
|
locales: ['en', 'fr', 'pt', 'pt_BR', 'de'],
|
||||||
},
|
},
|
||||||
experimental: {
|
experimental: {
|
||||||
outputFileTracingRoot: join(__dirname, '../../'),
|
outputFileTracingRoot: join(__dirname, '../../'),
|
||||||
|
@ -19,10 +19,11 @@ import { ChevronDownIcon } from '@/components/icons'
|
|||||||
import { MoreInfoTooltip } from '@/components/MoreInfoTooltip'
|
import { MoreInfoTooltip } from '@/components/MoreInfoTooltip'
|
||||||
|
|
||||||
const localeHumanReadable = {
|
const localeHumanReadable = {
|
||||||
en: 'English',
|
en: 'English',
|
||||||
fr: 'Français',
|
fr: 'Français',
|
||||||
de: 'Deutsch',
|
de: 'Deutsch',
|
||||||
pt: 'Português',
|
pt: 'Português',
|
||||||
|
pt_BR: 'Português (BR)'
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
export const UserPreferencesForm = () => {
|
export const UserPreferencesForm = () => {
|
||||||
|
@ -30,7 +30,8 @@ export const CurrentSubscriptionSummary = ({ workspace }: Props) => {
|
|||||||
<PlanTag plan={workspace.plan} />
|
<PlanTag plan={workspace.plan} />
|
||||||
{data?.subscription?.cancelDate && (
|
{data?.subscription?.cancelDate && (
|
||||||
<Text fontSize="sm">
|
<Text fontSize="sm">
|
||||||
(Will be cancelled on {data.subscription.cancelDate.toDateString()})
|
({scopedT('cancelDate')}{' '}
|
||||||
|
{data.subscription.cancelDate.toDateString()})
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</HStack>
|
</HStack>
|
||||||
|
@ -88,7 +88,7 @@ export const UsageProgressBars = ({ workspace }: Props) => {
|
|||||||
<Text>
|
<Text>
|
||||||
/{' '}
|
/{' '}
|
||||||
{workspaceChatsLimit === -1
|
{workspaceChatsLimit === -1
|
||||||
? 'Unlimited'
|
? scopedT('unlimited')
|
||||||
: parseNumberWithCommas(workspaceChatsLimit)}
|
: parseNumberWithCommas(workspaceChatsLimit)}
|
||||||
</Text>
|
</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
@ -141,7 +141,7 @@ export const UsageProgressBars = ({ workspace }: Props) => {
|
|||||||
<Text>
|
<Text>
|
||||||
/{' '}
|
/{' '}
|
||||||
{workspaceStorageLimit === -1
|
{workspaceStorageLimit === -1
|
||||||
? 'Unlimited'
|
? scopedT('unlimited')
|
||||||
: `${workspaceStorageLimit} GB`}
|
: `${workspaceStorageLimit} GB`}
|
||||||
</Text>
|
</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
@ -4,6 +4,7 @@ import { TextInput } from '@/components/inputs'
|
|||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { UploadButton } from '@/components/ImageUploadContent/UploadButton'
|
import { UploadButton } from '@/components/ImageUploadContent/UploadButton'
|
||||||
import { SwitchWithLabel } from '@/components/inputs/SwitchWithLabel'
|
import { SwitchWithLabel } from '@/components/inputs/SwitchWithLabel'
|
||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
fileUploadPath: string
|
fileUploadPath: string
|
||||||
@ -16,6 +17,7 @@ export const AudioBubbleForm = ({
|
|||||||
content,
|
content,
|
||||||
onContentChange,
|
onContentChange,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
|
const scopedT = useScopedI18n('editor.blocks.bubbles.audio.settings')
|
||||||
const [currentTab, setCurrentTab] = useState<'link' | 'upload'>('link')
|
const [currentTab, setCurrentTab] = useState<'link' | 'upload'>('link')
|
||||||
|
|
||||||
const updateUrl = (url: string) => onContentChange({ ...content, url })
|
const updateUrl = (url: string) => onContentChange({ ...content, url })
|
||||||
@ -31,14 +33,14 @@ export const AudioBubbleForm = ({
|
|||||||
onClick={() => setCurrentTab('upload')}
|
onClick={() => setCurrentTab('upload')}
|
||||||
size="sm"
|
size="sm"
|
||||||
>
|
>
|
||||||
Upload
|
{scopedT('upload.label')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant={currentTab === 'link' ? 'solid' : 'ghost'}
|
variant={currentTab === 'link' ? 'solid' : 'ghost'}
|
||||||
onClick={() => setCurrentTab('link')}
|
onClick={() => setCurrentTab('link')}
|
||||||
size="sm"
|
size="sm"
|
||||||
>
|
>
|
||||||
Embed link
|
{scopedT('embedLink.label')}
|
||||||
</Button>
|
</Button>
|
||||||
</HStack>
|
</HStack>
|
||||||
<Stack p="2" spacing={4}>
|
<Stack p="2" spacing={4}>
|
||||||
@ -51,25 +53,25 @@ export const AudioBubbleForm = ({
|
|||||||
onFileUploaded={updateUrl}
|
onFileUploaded={updateUrl}
|
||||||
colorScheme="blue"
|
colorScheme="blue"
|
||||||
>
|
>
|
||||||
Choose a file
|
{scopedT('chooseFile.label')}
|
||||||
</UploadButton>
|
</UploadButton>
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
{currentTab === 'link' && (
|
{currentTab === 'link' && (
|
||||||
<>
|
<>
|
||||||
<TextInput
|
<TextInput
|
||||||
placeholder="Paste the audio file link..."
|
placeholder={scopedT('worksWith.placeholder')}
|
||||||
defaultValue={content.url ?? ''}
|
defaultValue={content.url ?? ''}
|
||||||
onChange={updateUrl}
|
onChange={updateUrl}
|
||||||
/>
|
/>
|
||||||
<Text fontSize="sm" color="gray.400" textAlign="center">
|
<Text fontSize="sm" color="gray.400" textAlign="center">
|
||||||
Works with .MP3s and .WAVs
|
{scopedT('worksWith.text')}
|
||||||
</Text>
|
</Text>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
<SwitchWithLabel
|
<SwitchWithLabel
|
||||||
label={'Enable autoplay'}
|
label={scopedT('autoplay.label')}
|
||||||
initialValue={content.isAutoplayEnabled ?? true}
|
initialValue={content.isAutoplayEnabled ?? true}
|
||||||
onCheckChange={updateAutoPlay}
|
onCheckChange={updateAutoPlay}
|
||||||
/>
|
/>
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
import { Text } from '@chakra-ui/react'
|
import { Text } from '@chakra-ui/react'
|
||||||
import { AudioBubbleContent } from '@typebot.io/schemas'
|
import { AudioBubbleContent } from '@typebot.io/schemas'
|
||||||
import { isDefined } from '@typebot.io/lib'
|
import { isDefined } from '@typebot.io/lib'
|
||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
url: AudioBubbleContent['url']
|
url: AudioBubbleContent['url']
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AudioBubbleNode = ({ url }: Props) =>
|
export const AudioBubbleNode = ({ url }: Props) => {
|
||||||
isDefined(url) ? (
|
const scopedT = useScopedI18n('editor.blocks.bubbles.audio.node')
|
||||||
|
return isDefined(url) ? (
|
||||||
<audio src={url} controls />
|
<audio src={url} controls />
|
||||||
) : (
|
) : (
|
||||||
<Text color={'gray.500'}>Click to edit...</Text>
|
<Text color={'gray.500'}>{scopedT('clickToEdit.text')}</Text>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
import { Text } from '@chakra-ui/react'
|
import { Text } from '@chakra-ui/react'
|
||||||
import { EmbedBubbleBlock } from '@typebot.io/schemas'
|
import { EmbedBubbleBlock } from '@typebot.io/schemas'
|
||||||
|
|
||||||
export const EmbedBubbleContent = ({ block }: { block: EmbedBubbleBlock }) => {
|
type Props = {
|
||||||
if (!block.content?.url) return <Text color="gray.500">Click to edit...</Text>
|
block: EmbedBubbleBlock
|
||||||
return <Text>Show embed</Text>
|
}
|
||||||
|
|
||||||
|
export const EmbedBubbleContent = ({ block }: Props) => {
|
||||||
|
const scopedT = useScopedI18n('editor.blocks.bubbles.embed.node')
|
||||||
|
if (!block.content?.url)
|
||||||
|
return <Text color="gray.500">{scopedT('clickToEdit.text')}</Text>
|
||||||
|
return <Text>{scopedT('show.text')}</Text>
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import { TextInput, NumberInput } from '@/components/inputs'
|
|||||||
import { HStack, Stack, Text } from '@chakra-ui/react'
|
import { HStack, Stack, Text } from '@chakra-ui/react'
|
||||||
import { EmbedBubbleContent } from '@typebot.io/schemas'
|
import { EmbedBubbleContent } from '@typebot.io/schemas'
|
||||||
import { sanitizeUrl } from '@typebot.io/lib'
|
import { sanitizeUrl } from '@typebot.io/lib'
|
||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
content: EmbedBubbleContent
|
content: EmbedBubbleContent
|
||||||
@ -9,6 +10,7 @@ type Props = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const EmbedUploadContent = ({ content, onSubmit }: Props) => {
|
export const EmbedUploadContent = ({ content, onSubmit }: Props) => {
|
||||||
|
const scopedT = useScopedI18n('editor.blocks.bubbles.embed.settings')
|
||||||
const handleUrlChange = (url: string) => {
|
const handleUrlChange = (url: string) => {
|
||||||
const iframeUrl = sanitizeUrl(
|
const iframeUrl = sanitizeUrl(
|
||||||
url.trim().startsWith('<iframe') ? extractUrlFromIframe(url) : url
|
url.trim().startsWith('<iframe') ? extractUrlFromIframe(url) : url
|
||||||
@ -23,12 +25,12 @@ export const EmbedUploadContent = ({ content, onSubmit }: Props) => {
|
|||||||
<Stack p="2" spacing={6}>
|
<Stack p="2" spacing={6}>
|
||||||
<Stack>
|
<Stack>
|
||||||
<TextInput
|
<TextInput
|
||||||
placeholder="Paste the link or code..."
|
placeholder={scopedT('worksWith.placeholder')}
|
||||||
defaultValue={content?.url ?? ''}
|
defaultValue={content?.url ?? ''}
|
||||||
onChange={handleUrlChange}
|
onChange={handleUrlChange}
|
||||||
/>
|
/>
|
||||||
<Text fontSize="sm" color="gray.400" textAlign="center">
|
<Text fontSize="sm" color="gray.400" textAlign="center">
|
||||||
Works with PDFs, iframes, websites...
|
{scopedT('worksWith.text')}
|
||||||
</Text>
|
</Text>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
@ -38,7 +40,7 @@ export const EmbedUploadContent = ({ content, onSubmit }: Props) => {
|
|||||||
defaultValue={content?.height}
|
defaultValue={content?.height}
|
||||||
onValueChange={handleHeightChange}
|
onValueChange={handleHeightChange}
|
||||||
/>
|
/>
|
||||||
<Text>px</Text>
|
<Text>{scopedT('numberInput.unit')}</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
import { Box, Text, Image } from '@chakra-ui/react'
|
import { Box, Text, Image } from '@chakra-ui/react'
|
||||||
import { ImageBubbleBlock } from '@typebot.io/schemas'
|
import { ImageBubbleBlock } from '@typebot.io/schemas'
|
||||||
|
|
||||||
export const ImageBubbleContent = ({ block }: { block: ImageBubbleBlock }) => {
|
type Props = {
|
||||||
|
block: ImageBubbleBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ImageBubbleContent = ({ block }: Props) => {
|
||||||
|
const scopedT = useScopedI18n('editor.blocks.bubbles.image.node')
|
||||||
const containsVariables =
|
const containsVariables =
|
||||||
block.content?.url?.includes('{{') && block.content.url.includes('}}')
|
block.content?.url?.includes('{{') && block.content.url.includes('}}')
|
||||||
return !block.content?.url ? (
|
return !block.content?.url ? (
|
||||||
<Text color={'gray.500'}>Click to edit...</Text>
|
<Text color={'gray.500'}>{scopedT('clickToEdit.text')}</Text>
|
||||||
) : (
|
) : (
|
||||||
<Box w="full">
|
<Box w="full">
|
||||||
<Image
|
<Image
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { ImageUploadContent } from '@/components/ImageUploadContent'
|
import { ImageUploadContent } from '@/components/ImageUploadContent'
|
||||||
import { TextInput } from '@/components/inputs'
|
import { TextInput } from '@/components/inputs'
|
||||||
import { SwitchWithLabel } from '@/components/inputs/SwitchWithLabel'
|
import { SwitchWithLabel } from '@/components/inputs/SwitchWithLabel'
|
||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
import { Stack } from '@chakra-ui/react'
|
import { Stack } from '@chakra-ui/react'
|
||||||
import { isDefined, isNotEmpty } from '@typebot.io/lib'
|
import { isDefined, isNotEmpty } from '@typebot.io/lib'
|
||||||
import { ImageBubbleBlock } from '@typebot.io/schemas'
|
import { ImageBubbleBlock } from '@typebot.io/schemas'
|
||||||
@ -17,6 +18,9 @@ export const ImageBubbleSettings = ({
|
|||||||
block,
|
block,
|
||||||
onContentChange,
|
onContentChange,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
|
const scopedT = useScopedI18n(
|
||||||
|
'editor.blocks.bubbles.image.switchWithLabel.onClick'
|
||||||
|
)
|
||||||
const [showClickLinkInput, setShowClickLinkInput] = useState(
|
const [showClickLinkInput, setShowClickLinkInput] = useState(
|
||||||
isNotEmpty(block.content.clickLink?.url)
|
isNotEmpty(block.content.clickLink?.url)
|
||||||
)
|
)
|
||||||
@ -55,7 +59,7 @@ export const ImageBubbleSettings = ({
|
|||||||
/>
|
/>
|
||||||
<Stack>
|
<Stack>
|
||||||
<SwitchWithLabel
|
<SwitchWithLabel
|
||||||
label={'On click link'}
|
label={scopedT('label')}
|
||||||
initialValue={showClickLinkInput}
|
initialValue={showClickLinkInput}
|
||||||
onCheckChange={toggleClickLink}
|
onCheckChange={toggleClickLink}
|
||||||
/>
|
/>
|
||||||
@ -68,7 +72,7 @@ export const ImageBubbleSettings = ({
|
|||||||
defaultValue={block.content.clickLink?.url}
|
defaultValue={block.content.clickLink?.url}
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
placeholder="Link alt text (description)"
|
placeholder={scopedT('placeholder')}
|
||||||
onChange={updateClickLinkAltText}
|
onChange={updateClickLinkAltText}
|
||||||
defaultValue={block.content.clickLink?.alt}
|
defaultValue={block.content.clickLink?.alt}
|
||||||
/>
|
/>
|
||||||
|
@ -18,6 +18,7 @@ import { colors } from '@/lib/theme'
|
|||||||
import { useOutsideClick } from '@/hooks/useOutsideClick'
|
import { useOutsideClick } from '@/hooks/useOutsideClick'
|
||||||
import { selectEditor, TElement } from '@udecode/plate-common'
|
import { selectEditor, TElement } from '@udecode/plate-common'
|
||||||
import { TextEditorToolBar } from './TextEditorToolBar'
|
import { TextEditorToolBar } from './TextEditorToolBar'
|
||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
|
|
||||||
type TextBubbleEditorContentProps = {
|
type TextBubbleEditorContentProps = {
|
||||||
id: string
|
id: string
|
||||||
@ -30,6 +31,7 @@ const TextBubbleEditorContent = ({
|
|||||||
textEditorValue,
|
textEditorValue,
|
||||||
onClose,
|
onClose,
|
||||||
}: TextBubbleEditorContentProps) => {
|
}: TextBubbleEditorContentProps) => {
|
||||||
|
const scopedT = useScopedI18n('editor.blocks.bubbles')
|
||||||
const editor = usePlateEditorRef()
|
const editor = usePlateEditorRef()
|
||||||
const varDropdownRef = useRef<HTMLDivElement | null>(null)
|
const varDropdownRef = useRef<HTMLDivElement | null>(null)
|
||||||
const rememberedSelection = useRef<BaseSelection | null>(null)
|
const rememberedSelection = useRef<BaseSelection | null>(null)
|
||||||
@ -108,7 +110,7 @@ const TextBubbleEditorContent = ({
|
|||||||
backgroundColor: useColorModeValue('white', 'gray.800'),
|
backgroundColor: useColorModeValue('white', 'gray.800'),
|
||||||
borderRadius: 'md',
|
borderRadius: 'md',
|
||||||
transitionProperty: 'background-color',
|
transitionProperty: 'background-color',
|
||||||
transitionDuration: 'normal'
|
transitionDuration: 'normal',
|
||||||
},
|
},
|
||||||
'[class^="FloatingVerticalDivider___"]': {
|
'[class^="FloatingVerticalDivider___"]': {
|
||||||
'--tw-bg-opacity': useColorModeValue('1', '.4') + '!important',
|
'--tw-bg-opacity': useColorModeValue('1', '.4') + '!important',
|
||||||
@ -135,7 +137,7 @@ const TextBubbleEditorContent = ({
|
|||||||
})
|
})
|
||||||
setIsFirstFocus(false)
|
setIsFirstFocus(false)
|
||||||
},
|
},
|
||||||
'aria-label': 'Text editor',
|
'aria-label': `${scopedT('textEditor.plate.label')}`,
|
||||||
onBlur: () => {
|
onBlur: () => {
|
||||||
rememberedSelection.current = editor?.selection
|
rememberedSelection.current = editor?.selection
|
||||||
},
|
},
|
||||||
@ -154,7 +156,7 @@ const TextBubbleEditorContent = ({
|
|||||||
<VariableSearchInput
|
<VariableSearchInput
|
||||||
initialVariableId={undefined}
|
initialVariableId={undefined}
|
||||||
onSelectVariable={handleVariableSelected}
|
onSelectVariable={handleVariableSelected}
|
||||||
placeholder="Search for a variable"
|
placeholder={scopedT('textEditor.searchVariable.placeholder')}
|
||||||
autoFocus
|
autoFocus
|
||||||
/>
|
/>
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
import { Box, Text } from '@chakra-ui/react'
|
import { Box, Text } from '@chakra-ui/react'
|
||||||
import { VideoBubbleBlock, VideoBubbleContentType } from '@typebot.io/schemas'
|
import { VideoBubbleBlock, VideoBubbleContentType } from '@typebot.io/schemas'
|
||||||
|
|
||||||
export const VideoBubbleContent = ({ block }: { block: VideoBubbleBlock }) => {
|
type Props = {
|
||||||
|
block: VideoBubbleBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
export const VideoBubbleContent = ({ block }: Props) => {
|
||||||
|
const scopedT = useScopedI18n('editor.blocks.bubbles.video.node')
|
||||||
if (!block.content?.url || !block.content.type)
|
if (!block.content?.url || !block.content.type)
|
||||||
return <Text color="gray.500">Click to edit...</Text>
|
return <Text color="gray.500">{scopedT('clickToEdit.text')}</Text>
|
||||||
switch (block.content.type) {
|
switch (block.content.type) {
|
||||||
case VideoBubbleContentType.URL:
|
case VideoBubbleContentType.URL:
|
||||||
return (
|
return (
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Stack, Text } from '@chakra-ui/react'
|
import { Stack, Text } from '@chakra-ui/react'
|
||||||
import { VideoBubbleContent, VideoBubbleContentType } from '@typebot.io/schemas'
|
import { VideoBubbleContent, VideoBubbleContentType } from '@typebot.io/schemas'
|
||||||
import { TextInput } from '@/components/inputs'
|
import { TextInput } from '@/components/inputs'
|
||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
|
|
||||||
const vimeoRegex = /vimeo\.com\/(\d+)/
|
const vimeoRegex = /vimeo\.com\/(\d+)/
|
||||||
const youtubeRegex = /youtube\.com\/(watch\?v=|shorts\/)(\w+)|youtu\.be\/(\w+)/
|
const youtubeRegex = /youtube\.com\/(watch\?v=|shorts\/)(\w+)|youtu\.be\/(\w+)/
|
||||||
@ -11,6 +12,7 @@ type Props = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const VideoUploadContent = ({ content, onSubmit }: Props) => {
|
export const VideoUploadContent = ({ content, onSubmit }: Props) => {
|
||||||
|
const scopedT = useScopedI18n('editor.blocks.bubbles.video.settings')
|
||||||
const handleUrlChange = (url: string) => {
|
const handleUrlChange = (url: string) => {
|
||||||
const info = parseVideoUrl(url)
|
const info = parseVideoUrl(url)
|
||||||
return onSubmit({
|
return onSubmit({
|
||||||
@ -22,12 +24,12 @@ export const VideoUploadContent = ({ content, onSubmit }: Props) => {
|
|||||||
return (
|
return (
|
||||||
<Stack p="2">
|
<Stack p="2">
|
||||||
<TextInput
|
<TextInput
|
||||||
placeholder="Paste the video link..."
|
placeholder={scopedT('worksWith.placeholder')}
|
||||||
defaultValue={content?.url ?? ''}
|
defaultValue={content?.url ?? ''}
|
||||||
onChange={handleUrlChange}
|
onChange={handleUrlChange}
|
||||||
/>
|
/>
|
||||||
<Text fontSize="sm" color="gray.400" textAlign="center">
|
<Text fontSize="sm" color="gray.400" textAlign="center">
|
||||||
Works with Youtube, Vimeo and others
|
{scopedT('worksWith.text')}
|
||||||
</Text>
|
</Text>
|
||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
|
@ -14,6 +14,7 @@ import { Plan } from '@typebot.io/prisma'
|
|||||||
import { useWorkspace } from '@/features/workspace/WorkspaceProvider'
|
import { useWorkspace } from '@/features/workspace/WorkspaceProvider'
|
||||||
import { BlockLabel } from './BlockLabel'
|
import { BlockLabel } from './BlockLabel'
|
||||||
import { LockTag } from '@/features/billing/components/LockTag'
|
import { LockTag } from '@/features/billing/components/LockTag'
|
||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
type: DraggableBlockType
|
type: DraggableBlockType
|
||||||
@ -26,6 +27,7 @@ type Props = {
|
|||||||
export const BlockCard = (
|
export const BlockCard = (
|
||||||
props: Pick<Props, 'type' | 'onMouseDown'>
|
props: Pick<Props, 'type' | 'onMouseDown'>
|
||||||
): JSX.Element => {
|
): JSX.Element => {
|
||||||
|
const scopedT = useScopedI18n('editor.blockCard')
|
||||||
const { workspace } = useWorkspace()
|
const { workspace } = useWorkspace()
|
||||||
|
|
||||||
switch (props.type) {
|
switch (props.type) {
|
||||||
@ -33,7 +35,7 @@ export const BlockCard = (
|
|||||||
return (
|
return (
|
||||||
<BlockCardLayout
|
<BlockCardLayout
|
||||||
{...props}
|
{...props}
|
||||||
tooltip="Embed a pdf, an iframe, a website..."
|
tooltip={scopedT('bubbleBlock.tooltip.label')}
|
||||||
>
|
>
|
||||||
<BlockIcon type={props.type} />
|
<BlockIcon type={props.type} />
|
||||||
<BlockLabel type={props.type} />
|
<BlockLabel type={props.type} />
|
||||||
@ -41,7 +43,10 @@ export const BlockCard = (
|
|||||||
)
|
)
|
||||||
case InputBlockType.FILE:
|
case InputBlockType.FILE:
|
||||||
return (
|
return (
|
||||||
<BlockCardLayout {...props} tooltip="Upload Files">
|
<BlockCardLayout
|
||||||
|
{...props}
|
||||||
|
tooltip={scopedT('inputBlock.tooltip.files.label')}
|
||||||
|
>
|
||||||
<BlockIcon type={props.type} />
|
<BlockIcon type={props.type} />
|
||||||
<HStack>
|
<HStack>
|
||||||
<BlockLabel type={props.type} />
|
<BlockLabel type={props.type} />
|
||||||
@ -51,14 +56,20 @@ export const BlockCard = (
|
|||||||
)
|
)
|
||||||
case LogicBlockType.SCRIPT:
|
case LogicBlockType.SCRIPT:
|
||||||
return (
|
return (
|
||||||
<BlockCardLayout {...props} tooltip="Execute Javascript code">
|
<BlockCardLayout
|
||||||
|
{...props}
|
||||||
|
tooltip={scopedT('logicBlock.tooltip.code.label')}
|
||||||
|
>
|
||||||
<BlockIcon type={props.type} />
|
<BlockIcon type={props.type} />
|
||||||
<BlockLabel type={props.type} />
|
<BlockLabel type={props.type} />
|
||||||
</BlockCardLayout>
|
</BlockCardLayout>
|
||||||
)
|
)
|
||||||
case LogicBlockType.TYPEBOT_LINK:
|
case LogicBlockType.TYPEBOT_LINK:
|
||||||
return (
|
return (
|
||||||
<BlockCardLayout {...props} tooltip="Link and jump to another typebot">
|
<BlockCardLayout
|
||||||
|
{...props}
|
||||||
|
tooltip={scopedT('logicBlock.tooltip.typebotLink.label')}
|
||||||
|
>
|
||||||
<BlockIcon type={props.type} />
|
<BlockIcon type={props.type} />
|
||||||
<BlockLabel type={props.type} />
|
<BlockLabel type={props.type} />
|
||||||
</BlockCardLayout>
|
</BlockCardLayout>
|
||||||
@ -67,7 +78,7 @@ export const BlockCard = (
|
|||||||
return (
|
return (
|
||||||
<BlockCardLayout
|
<BlockCardLayout
|
||||||
{...props}
|
{...props}
|
||||||
tooltip="Fast forward the flow to another group"
|
tooltip={scopedT('logicBlock.tooltip.jump.label')}
|
||||||
>
|
>
|
||||||
<BlockIcon type={props.type} />
|
<BlockIcon type={props.type} />
|
||||||
<BlockLabel type={props.type} />
|
<BlockLabel type={props.type} />
|
||||||
@ -75,14 +86,20 @@ export const BlockCard = (
|
|||||||
)
|
)
|
||||||
case IntegrationBlockType.GOOGLE_SHEETS:
|
case IntegrationBlockType.GOOGLE_SHEETS:
|
||||||
return (
|
return (
|
||||||
<BlockCardLayout {...props} tooltip="Google Sheets">
|
<BlockCardLayout
|
||||||
|
{...props}
|
||||||
|
tooltip={scopedT('integrationBlock.tooltip.googleSheets.label')}
|
||||||
|
>
|
||||||
<BlockIcon type={props.type} />
|
<BlockIcon type={props.type} />
|
||||||
<BlockLabel type={props.type} />
|
<BlockLabel type={props.type} />
|
||||||
</BlockCardLayout>
|
</BlockCardLayout>
|
||||||
)
|
)
|
||||||
case IntegrationBlockType.GOOGLE_ANALYTICS:
|
case IntegrationBlockType.GOOGLE_ANALYTICS:
|
||||||
return (
|
return (
|
||||||
<BlockCardLayout {...props} tooltip="Google Analytics">
|
<BlockCardLayout
|
||||||
|
{...props}
|
||||||
|
tooltip={scopedT('integrationBlock.tooltip.googleAnalytics.label')}
|
||||||
|
>
|
||||||
<BlockIcon type={props.type} />
|
<BlockIcon type={props.type} />
|
||||||
<BlockLabel type={props.type} />
|
<BlockLabel type={props.type} />
|
||||||
</BlockCardLayout>
|
</BlockCardLayout>
|
||||||
|
@ -7,79 +7,82 @@ import {
|
|||||||
BlockType,
|
BlockType,
|
||||||
} from '@typebot.io/schemas'
|
} from '@typebot.io/schemas'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
|
|
||||||
type Props = { type: BlockType }
|
type Props = { type: BlockType }
|
||||||
|
|
||||||
export const BlockLabel = ({ type }: Props): JSX.Element => {
|
export const BlockLabel = ({ type }: Props): JSX.Element => {
|
||||||
|
const scopedT = useScopedI18n('editor.sidebarBlock')
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'start':
|
case 'start':
|
||||||
return <Text fontSize="sm">Start</Text>
|
return <Text fontSize="sm">{scopedT('start.label')}</Text>
|
||||||
case BubbleBlockType.TEXT:
|
case BubbleBlockType.TEXT:
|
||||||
case InputBlockType.TEXT:
|
case InputBlockType.TEXT:
|
||||||
return <Text fontSize="sm">Text</Text>
|
return <Text fontSize="sm">{scopedT('text.label')}</Text>
|
||||||
case BubbleBlockType.IMAGE:
|
case BubbleBlockType.IMAGE:
|
||||||
return <Text fontSize="sm">Image</Text>
|
return <Text fontSize="sm">{scopedT('image.label')}</Text>
|
||||||
case BubbleBlockType.VIDEO:
|
case BubbleBlockType.VIDEO:
|
||||||
return <Text fontSize="sm">Video</Text>
|
return <Text fontSize="sm">{scopedT('video.label')}</Text>
|
||||||
case BubbleBlockType.EMBED:
|
case BubbleBlockType.EMBED:
|
||||||
return <Text fontSize="sm">Embed</Text>
|
return <Text fontSize="sm">{scopedT('embed.label')}</Text>
|
||||||
case BubbleBlockType.AUDIO:
|
case BubbleBlockType.AUDIO:
|
||||||
return <Text fontSize="sm">Audio</Text>
|
return <Text fontSize="sm">{scopedT('audio.label')}</Text>
|
||||||
case InputBlockType.NUMBER:
|
case InputBlockType.NUMBER:
|
||||||
return <Text fontSize="sm">Number</Text>
|
return <Text fontSize="sm">{scopedT('number.label')}</Text>
|
||||||
case InputBlockType.EMAIL:
|
case InputBlockType.EMAIL:
|
||||||
return <Text fontSize="sm">Email</Text>
|
return <Text fontSize="sm">{scopedT('email.label')}</Text>
|
||||||
case InputBlockType.URL:
|
case InputBlockType.URL:
|
||||||
return <Text fontSize="sm">Website</Text>
|
return <Text fontSize="sm">{scopedT('website.label')}</Text>
|
||||||
case InputBlockType.DATE:
|
case InputBlockType.DATE:
|
||||||
return <Text fontSize="sm">Date</Text>
|
return <Text fontSize="sm">{scopedT('date.label')}</Text>
|
||||||
case InputBlockType.PHONE:
|
case InputBlockType.PHONE:
|
||||||
return <Text fontSize="sm">Phone</Text>
|
return <Text fontSize="sm">{scopedT('phone.label')}</Text>
|
||||||
case InputBlockType.CHOICE:
|
case InputBlockType.CHOICE:
|
||||||
return <Text fontSize="sm">Button</Text>
|
return <Text fontSize="sm">{scopedT('button.label')}</Text>
|
||||||
case InputBlockType.PICTURE_CHOICE:
|
case InputBlockType.PICTURE_CHOICE:
|
||||||
return <Text fontSize="sm">Pic choice</Text>
|
return <Text fontSize="sm">{scopedT('picChoice.label')}</Text>
|
||||||
case InputBlockType.PAYMENT:
|
case InputBlockType.PAYMENT:
|
||||||
return <Text fontSize="sm">Payment</Text>
|
return <Text fontSize="sm">{scopedT('payment.label')}</Text>
|
||||||
case InputBlockType.RATING:
|
case InputBlockType.RATING:
|
||||||
return <Text fontSize="sm">Rating</Text>
|
return <Text fontSize="sm">{scopedT('rating.label')}</Text>
|
||||||
case InputBlockType.FILE:
|
case InputBlockType.FILE:
|
||||||
return <Text fontSize="sm">File</Text>
|
return <Text fontSize="sm">{scopedT('file.label')}</Text>
|
||||||
case LogicBlockType.SET_VARIABLE:
|
case LogicBlockType.SET_VARIABLE:
|
||||||
return <Text fontSize="sm">Set variable</Text>
|
return <Text fontSize="sm">{scopedT('setVariable.label')}</Text>
|
||||||
case LogicBlockType.CONDITION:
|
case LogicBlockType.CONDITION:
|
||||||
return <Text fontSize="sm">Condition</Text>
|
return <Text fontSize="sm">{scopedT('condition.label')}</Text>
|
||||||
case LogicBlockType.REDIRECT:
|
case LogicBlockType.REDIRECT:
|
||||||
return <Text fontSize="sm">Redirect</Text>
|
return <Text fontSize="sm">{scopedT('redirect.label')}</Text>
|
||||||
case LogicBlockType.SCRIPT:
|
case LogicBlockType.SCRIPT:
|
||||||
return <Text fontSize="sm">Script</Text>
|
return <Text fontSize="sm">{scopedT('script.label')}</Text>
|
||||||
case LogicBlockType.TYPEBOT_LINK:
|
case LogicBlockType.TYPEBOT_LINK:
|
||||||
return <Text fontSize="sm">Typebot</Text>
|
return <Text fontSize="sm">{scopedT('typebot.label')}</Text>
|
||||||
case LogicBlockType.WAIT:
|
case LogicBlockType.WAIT:
|
||||||
return <Text fontSize="sm">Wait</Text>
|
return <Text fontSize="sm">{scopedT('wait.label')}</Text>
|
||||||
case LogicBlockType.JUMP:
|
case LogicBlockType.JUMP:
|
||||||
return <Text fontSize="sm">Jump</Text>
|
return <Text fontSize="sm">{scopedT('jump.label')}</Text>
|
||||||
case LogicBlockType.AB_TEST:
|
case LogicBlockType.AB_TEST:
|
||||||
return <Text fontSize="sm">AB Test</Text>
|
return <Text fontSize="sm">{scopedT('abTest.label')}</Text>
|
||||||
case IntegrationBlockType.GOOGLE_SHEETS:
|
case IntegrationBlockType.GOOGLE_SHEETS:
|
||||||
return <Text fontSize="sm">Sheets</Text>
|
return <Text fontSize="sm">{scopedT('sheets.label')}</Text>
|
||||||
case IntegrationBlockType.GOOGLE_ANALYTICS:
|
case IntegrationBlockType.GOOGLE_ANALYTICS:
|
||||||
return <Text fontSize="sm">Analytics</Text>
|
return <Text fontSize="sm">{scopedT('analytics.label')}</Text>
|
||||||
case IntegrationBlockType.WEBHOOK:
|
case IntegrationBlockType.WEBHOOK:
|
||||||
return <Text fontSize="sm">Webhook</Text>
|
return <Text fontSize="sm">{scopedT('webhook.label')}</Text>
|
||||||
case IntegrationBlockType.ZAPIER:
|
case IntegrationBlockType.ZAPIER:
|
||||||
return <Text fontSize="sm">Zapier</Text>
|
return <Text fontSize="sm">{scopedT('zapier.label')}</Text>
|
||||||
case IntegrationBlockType.MAKE_COM:
|
case IntegrationBlockType.MAKE_COM:
|
||||||
return <Text fontSize="sm">Make.com</Text>
|
return <Text fontSize="sm">{scopedT('makecom.label')}</Text>
|
||||||
case IntegrationBlockType.PABBLY_CONNECT:
|
case IntegrationBlockType.PABBLY_CONNECT:
|
||||||
return <Text fontSize="sm">Pabbly</Text>
|
return <Text fontSize="sm">{scopedT('pabbly.label')}</Text>
|
||||||
case IntegrationBlockType.EMAIL:
|
case IntegrationBlockType.EMAIL:
|
||||||
return <Text fontSize="sm">Email</Text>
|
return <Text fontSize="sm">{scopedT('email.label')}</Text>
|
||||||
case IntegrationBlockType.CHATWOOT:
|
case IntegrationBlockType.CHATWOOT:
|
||||||
return <Text fontSize="sm">Chatwoot</Text>
|
return <Text fontSize="sm">{scopedT('chatwoot.label')}</Text>
|
||||||
case IntegrationBlockType.OPEN_AI:
|
case IntegrationBlockType.OPEN_AI:
|
||||||
return <Text fontSize="sm">OpenAI</Text>
|
return <Text fontSize="sm">{scopedT('openai.label')}</Text>
|
||||||
case IntegrationBlockType.PIXEL:
|
case IntegrationBlockType.PIXEL:
|
||||||
return <Text fontSize="sm">Pixel</Text>
|
return <Text fontSize="sm">{scopedT('pixel.label')}</Text>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,10 @@ import { BlockCard } from './BlockCard'
|
|||||||
import { LockedIcon, UnlockedIcon } from '@/components/icons'
|
import { LockedIcon, UnlockedIcon } from '@/components/icons'
|
||||||
import { BlockCardOverlay } from './BlockCardOverlay'
|
import { BlockCardOverlay } from './BlockCardOverlay'
|
||||||
import { headerHeight } from '../constants'
|
import { headerHeight } from '../constants'
|
||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
|
|
||||||
export const BlocksSideBar = () => {
|
export const BlocksSideBar = () => {
|
||||||
|
const scopedT = useScopedI18n('editor.sidebarBlocks')
|
||||||
const { setDraggedBlockType, draggedBlockType } = useBlockDnd()
|
const { setDraggedBlockType, draggedBlockType } = useBlockDnd()
|
||||||
const [position, setPosition] = useState({
|
const [position, setPosition] = useState({
|
||||||
x: 0,
|
x: 0,
|
||||||
@ -102,10 +104,20 @@ export const BlocksSideBar = () => {
|
|||||||
className="hide-scrollbar"
|
className="hide-scrollbar"
|
||||||
>
|
>
|
||||||
<Flex justifyContent="flex-end">
|
<Flex justifyContent="flex-end">
|
||||||
<Tooltip label={isLocked ? 'Unlock sidebar' : 'Lock sidebar'}>
|
<Tooltip
|
||||||
|
label={
|
||||||
|
isLocked
|
||||||
|
? scopedT('sidebar.unlock.label')
|
||||||
|
: scopedT('sidebar.lock.label')
|
||||||
|
}
|
||||||
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={isLocked ? <LockedIcon /> : <UnlockedIcon />}
|
icon={isLocked ? <LockedIcon /> : <UnlockedIcon />}
|
||||||
aria-label={isLocked ? 'Unlock' : 'Lock'}
|
aria-label={
|
||||||
|
isLocked
|
||||||
|
? scopedT('sidebar.icon.unlock.label')
|
||||||
|
: scopedT('sidebar.icon.lock.label')
|
||||||
|
}
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={handleLockClick}
|
onClick={handleLockClick}
|
||||||
/>
|
/>
|
||||||
@ -114,7 +126,7 @@ export const BlocksSideBar = () => {
|
|||||||
|
|
||||||
<Stack>
|
<Stack>
|
||||||
<Text fontSize="sm" fontWeight="semibold">
|
<Text fontSize="sm" fontWeight="semibold">
|
||||||
Bubbles
|
{scopedT('blockType.bubbles.heading')}
|
||||||
</Text>
|
</Text>
|
||||||
<SimpleGrid columns={2} spacing="3">
|
<SimpleGrid columns={2} spacing="3">
|
||||||
{Object.values(BubbleBlockType).map((type) => (
|
{Object.values(BubbleBlockType).map((type) => (
|
||||||
@ -125,7 +137,7 @@ export const BlocksSideBar = () => {
|
|||||||
|
|
||||||
<Stack>
|
<Stack>
|
||||||
<Text fontSize="sm" fontWeight="semibold">
|
<Text fontSize="sm" fontWeight="semibold">
|
||||||
Inputs
|
{scopedT('blockType.inputs.heading')}
|
||||||
</Text>
|
</Text>
|
||||||
<SimpleGrid columns={2} spacing="3">
|
<SimpleGrid columns={2} spacing="3">
|
||||||
{Object.values(InputBlockType).map((type) => (
|
{Object.values(InputBlockType).map((type) => (
|
||||||
@ -136,7 +148,7 @@ export const BlocksSideBar = () => {
|
|||||||
|
|
||||||
<Stack>
|
<Stack>
|
||||||
<Text fontSize="sm" fontWeight="semibold">
|
<Text fontSize="sm" fontWeight="semibold">
|
||||||
Logic
|
{scopedT('blockType.logic.heading')}
|
||||||
</Text>
|
</Text>
|
||||||
<SimpleGrid columns={2} spacing="3">
|
<SimpleGrid columns={2} spacing="3">
|
||||||
{Object.values(LogicBlockType).map((type) => (
|
{Object.values(LogicBlockType).map((type) => (
|
||||||
@ -147,7 +159,7 @@ export const BlocksSideBar = () => {
|
|||||||
|
|
||||||
<Stack>
|
<Stack>
|
||||||
<Text fontSize="sm" fontWeight="semibold">
|
<Text fontSize="sm" fontWeight="semibold">
|
||||||
Integrations
|
{scopedT('blockType.integrations.heading')}
|
||||||
</Text>
|
</Text>
|
||||||
<SimpleGrid columns={2} spacing="3">
|
<SimpleGrid columns={2} spacing="3">
|
||||||
{Object.values(IntegrationBlockType).map((type) => (
|
{Object.values(IntegrationBlockType).map((type) => (
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
useColorModeValue,
|
useColorModeValue,
|
||||||
} from '@chakra-ui/react'
|
} from '@chakra-ui/react'
|
||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
|
|
||||||
type EditableProps = {
|
type EditableProps = {
|
||||||
defaultName: string
|
defaultName: string
|
||||||
@ -15,6 +16,7 @@ export const EditableTypebotName = ({
|
|||||||
defaultName,
|
defaultName,
|
||||||
onNewName,
|
onNewName,
|
||||||
}: EditableProps) => {
|
}: EditableProps) => {
|
||||||
|
const scopedT = useScopedI18n('editor.editableTypebotName')
|
||||||
const emptyNameBg = useColorModeValue('gray.100', 'gray.700')
|
const emptyNameBg = useColorModeValue('gray.100', 'gray.700')
|
||||||
const [currentName, setCurrentName] = useState(defaultName)
|
const [currentName, setCurrentName] = useState(defaultName)
|
||||||
|
|
||||||
@ -25,7 +27,7 @@ export const EditableTypebotName = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip label="Rename">
|
<Tooltip label={scopedT('tooltip.rename.label')}>
|
||||||
<Editable
|
<Editable
|
||||||
value={currentName}
|
value={currentName}
|
||||||
onChange={setCurrentName}
|
onChange={setCurrentName}
|
||||||
|
@ -21,8 +21,10 @@ import {
|
|||||||
} from '@chakra-ui/react'
|
} from '@chakra-ui/react'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
|
|
||||||
export const GettingStartedModal = () => {
|
export const GettingStartedModal = () => {
|
||||||
|
const scopedT = useScopedI18n('editor.gettingStartedModal')
|
||||||
const { query } = useRouter()
|
const { query } = useRouter()
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure()
|
const { isOpen, onOpen, onClose } = useDisclosure()
|
||||||
|
|
||||||
@ -38,7 +40,7 @@ export const GettingStartedModal = () => {
|
|||||||
<ModalCloseButton />
|
<ModalCloseButton />
|
||||||
<ModalBody as={Stack} spacing="8" py="10">
|
<ModalBody as={Stack} spacing="8" py="10">
|
||||||
<Stack spacing={4}>
|
<Stack spacing={4}>
|
||||||
<Heading fontSize="xl">Editor basics</Heading>
|
<Heading fontSize="xl">{scopedT('editorBasics.heading')}</Heading>
|
||||||
<List spacing={4}>
|
<List spacing={4}>
|
||||||
<HStack as={ListItem}>
|
<HStack as={ListItem}>
|
||||||
<Flex
|
<Flex
|
||||||
@ -54,10 +56,7 @@ export const GettingStartedModal = () => {
|
|||||||
>
|
>
|
||||||
1
|
1
|
||||||
</Flex>
|
</Flex>
|
||||||
<Text>
|
<Text>{scopedT('editorBasics.list.one.label')}</Text>
|
||||||
The left side bar contains blocks that you can drag and drop
|
|
||||||
to the board.
|
|
||||||
</Text>
|
|
||||||
</HStack>
|
</HStack>
|
||||||
<HStack as={ListItem}>
|
<HStack as={ListItem}>
|
||||||
<Flex
|
<Flex
|
||||||
@ -73,10 +72,7 @@ export const GettingStartedModal = () => {
|
|||||||
>
|
>
|
||||||
2
|
2
|
||||||
</Flex>
|
</Flex>
|
||||||
<Text>
|
<Text>{scopedT('editorBasics.list.two.label')}</Text>
|
||||||
You can group blocks together by dropping them below or above
|
|
||||||
each other
|
|
||||||
</Text>
|
|
||||||
</HStack>
|
</HStack>
|
||||||
<HStack as={ListItem}>
|
<HStack as={ListItem}>
|
||||||
<Flex
|
<Flex
|
||||||
@ -92,7 +88,7 @@ export const GettingStartedModal = () => {
|
|||||||
>
|
>
|
||||||
3
|
3
|
||||||
</Flex>
|
</Flex>
|
||||||
<Text>Connect the groups together</Text>
|
<Text>{scopedT('editorBasics.list.three.label')}</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
<HStack as={ListItem}>
|
<HStack as={ListItem}>
|
||||||
<Flex
|
<Flex
|
||||||
@ -108,20 +104,16 @@ export const GettingStartedModal = () => {
|
|||||||
>
|
>
|
||||||
4
|
4
|
||||||
</Flex>
|
</Flex>
|
||||||
<Text>
|
<Text>{scopedT('editorBasics.list.four.label')}</Text>
|
||||||
Preview your bot by clicking the preview button on the top
|
|
||||||
right
|
|
||||||
</Text>
|
|
||||||
</HStack>
|
</HStack>
|
||||||
</List>
|
</List>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<Text>
|
<Text>{scopedT('editorBasics.list.label')}</Text>
|
||||||
Feel free to use the bottom-right bubble to reach out if you have
|
|
||||||
any question. I usually answer within the next 24 hours. 😃
|
|
||||||
</Text>
|
|
||||||
<Stack spacing={4}>
|
<Stack spacing={4}>
|
||||||
<Heading fontSize="xl">See it in action ({`<`} 5 minutes)</Heading>
|
<Heading fontSize="xl">
|
||||||
|
{scopedT('seeAction.label')} ({`<`} {scopedT('seeAction.time')})
|
||||||
|
</Heading>
|
||||||
<iframe
|
<iframe
|
||||||
width="100%"
|
width="100%"
|
||||||
height="315"
|
height="315"
|
||||||
@ -135,7 +127,7 @@ export const GettingStartedModal = () => {
|
|||||||
<AccordionItem>
|
<AccordionItem>
|
||||||
<AccordionButton>
|
<AccordionButton>
|
||||||
<Box flex="1" textAlign="left">
|
<Box flex="1" textAlign="left">
|
||||||
Other videos
|
{scopedT('seeAction.item.label')}
|
||||||
</Box>
|
</Box>
|
||||||
<AccordionIcon />
|
<AccordionIcon />
|
||||||
</AccordionButton>
|
</AccordionButton>
|
||||||
|
@ -30,8 +30,10 @@ import { RightPanel, useEditor } from '../providers/EditorProvider'
|
|||||||
import { useTypebot } from '../providers/TypebotProvider'
|
import { useTypebot } from '../providers/TypebotProvider'
|
||||||
import { SupportBubble } from '@/components/SupportBubble'
|
import { SupportBubble } from '@/components/SupportBubble'
|
||||||
import { isCloudProdInstance } from '@/helpers/isCloudProdInstance'
|
import { isCloudProdInstance } from '@/helpers/isCloudProdInstance'
|
||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
|
|
||||||
export const TypebotHeader = () => {
|
export const TypebotHeader = () => {
|
||||||
|
const scopedT = useScopedI18n('editor.headers')
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const {
|
const {
|
||||||
typebot,
|
typebot,
|
||||||
@ -103,7 +105,7 @@ export const TypebotHeader = () => {
|
|||||||
variant={router.pathname.includes('/edit') ? 'outline' : 'ghost'}
|
variant={router.pathname.includes('/edit') ? 'outline' : 'ghost'}
|
||||||
size="sm"
|
size="sm"
|
||||||
>
|
>
|
||||||
Flow
|
{scopedT('flowButton.label')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
as={Link}
|
as={Link}
|
||||||
@ -112,7 +114,7 @@ export const TypebotHeader = () => {
|
|||||||
variant={router.pathname.endsWith('theme') ? 'outline' : 'ghost'}
|
variant={router.pathname.endsWith('theme') ? 'outline' : 'ghost'}
|
||||||
size="sm"
|
size="sm"
|
||||||
>
|
>
|
||||||
Theme
|
{scopedT('themeButton.label')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
as={Link}
|
as={Link}
|
||||||
@ -121,7 +123,7 @@ export const TypebotHeader = () => {
|
|||||||
variant={router.pathname.endsWith('settings') ? 'outline' : 'ghost'}
|
variant={router.pathname.endsWith('settings') ? 'outline' : 'ghost'}
|
||||||
size="sm"
|
size="sm"
|
||||||
>
|
>
|
||||||
Settings
|
{scopedT('settingsButton.label')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
as={Link}
|
as={Link}
|
||||||
@ -130,7 +132,7 @@ export const TypebotHeader = () => {
|
|||||||
variant={router.pathname.endsWith('share') ? 'outline' : 'ghost'}
|
variant={router.pathname.endsWith('share') ? 'outline' : 'ghost'}
|
||||||
size="sm"
|
size="sm"
|
||||||
>
|
>
|
||||||
Share
|
{scopedT('shareButton.label')}
|
||||||
</Button>
|
</Button>
|
||||||
{isDefined(publishedTypebot) && (
|
{isDefined(publishedTypebot) && (
|
||||||
<Button
|
<Button
|
||||||
@ -140,7 +142,7 @@ export const TypebotHeader = () => {
|
|||||||
variant={router.pathname.includes('results') ? 'outline' : 'ghost'}
|
variant={router.pathname.includes('results') ? 'outline' : 'ghost'}
|
||||||
size="sm"
|
size="sm"
|
||||||
>
|
>
|
||||||
Results
|
{scopedT('resultsButton.label')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</HStack>
|
</HStack>
|
||||||
@ -219,14 +221,14 @@ export const TypebotHeader = () => {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</HStack>
|
</HStack>
|
||||||
<Button leftIcon={<BuoyIcon />} onClick={handleHelpClick} size="sm">
|
<Button leftIcon={<BuoyIcon />} onClick={handleHelpClick} size="sm">
|
||||||
Help
|
{scopedT('helpButton.label')}
|
||||||
</Button>
|
</Button>
|
||||||
</HStack>
|
</HStack>
|
||||||
{isSavingLoading && (
|
{isSavingLoading && (
|
||||||
<HStack>
|
<HStack>
|
||||||
<Spinner speed="0.7s" size="sm" color="gray.400" />
|
<Spinner speed="0.7s" size="sm" color="gray.400" />
|
||||||
<Text fontSize="sm" color="gray.400">
|
<Text fontSize="sm" color="gray.400">
|
||||||
Saving...
|
{scopedT('savingSpinner.label')}
|
||||||
</Text>
|
</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
)}
|
)}
|
||||||
@ -241,7 +243,7 @@ export const TypebotHeader = () => {
|
|||||||
isLoading={isNotDefined(typebot)}
|
isLoading={isNotDefined(typebot)}
|
||||||
size="sm"
|
size="sm"
|
||||||
>
|
>
|
||||||
Preview
|
{scopedT('previewButton.label')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<PublishButton size="sm" />
|
<PublishButton size="sm" />
|
||||||
|
@ -23,6 +23,7 @@ import { areTypebotsEqual } from '@/features/publish/helpers/areTypebotsEqual'
|
|||||||
import { isPublished as isPublishedHelper } from '@/features/publish/helpers/isPublished'
|
import { isPublished as isPublishedHelper } from '@/features/publish/helpers/isPublished'
|
||||||
import { convertPublicTypebotToTypebot } from '@/features/publish/helpers/convertPublicTypebotToTypebot'
|
import { convertPublicTypebotToTypebot } from '@/features/publish/helpers/convertPublicTypebotToTypebot'
|
||||||
import { trpc } from '@/lib/trpc'
|
import { trpc } from '@/lib/trpc'
|
||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
|
|
||||||
const autoSaveTimeout = 10000
|
const autoSaveTimeout = 10000
|
||||||
|
|
||||||
@ -79,6 +80,7 @@ export const TypebotProvider = ({
|
|||||||
children: ReactNode
|
children: ReactNode
|
||||||
typebotId?: string
|
typebotId?: string
|
||||||
}) => {
|
}) => {
|
||||||
|
const scopedT = useScopedI18n('editor.provider')
|
||||||
const { push } = useRouter()
|
const { push } = useRouter()
|
||||||
const { showToast } = useToast()
|
const { showToast } = useToast()
|
||||||
|
|
||||||
@ -92,12 +94,15 @@ export const TypebotProvider = ({
|
|||||||
enabled: isDefined(typebotId),
|
enabled: isDefined(typebotId),
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
if (error.data?.httpStatus === 404) {
|
if (error.data?.httpStatus === 404) {
|
||||||
showToast({ status: 'info', description: "Couldn't find typebot" })
|
showToast({
|
||||||
|
status: 'info',
|
||||||
|
description: scopedT('messages.getTypebotError.description'),
|
||||||
|
})
|
||||||
push('/typebots')
|
push('/typebots')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
showToast({
|
showToast({
|
||||||
title: 'Error while fetching typebot. Refresh the page.',
|
title: scopedT('messages.getTypebotError.title'),
|
||||||
description: error.message,
|
description: error.message,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -112,7 +117,7 @@ export const TypebotProvider = ({
|
|||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
if (error.data?.httpStatus === 404) return
|
if (error.data?.httpStatus === 404) return
|
||||||
showToast({
|
showToast({
|
||||||
title: 'Error while fetching published typebot',
|
title: scopedT('messages.publishedTypebotError.title'),
|
||||||
description: error.message,
|
description: error.message,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -123,7 +128,7 @@ export const TypebotProvider = ({
|
|||||||
trpc.typebot.updateTypebot.useMutation({
|
trpc.typebot.updateTypebot.useMutation({
|
||||||
onError: (error) =>
|
onError: (error) =>
|
||||||
showToast({
|
showToast({
|
||||||
title: 'Error while updating typebot',
|
title: scopedT('messages.updateTypebotError.title'),
|
||||||
description: error.message,
|
description: error.message,
|
||||||
}),
|
}),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
@ -253,7 +258,10 @@ export const TypebotProvider = ({
|
|||||||
isPublished,
|
isPublished,
|
||||||
updateTypebot: updateLocalTypebot,
|
updateTypebot: updateLocalTypebot,
|
||||||
restorePublishedTypebot,
|
restorePublishedTypebot,
|
||||||
...groupsActions(setLocalTypebot as SetTypebot),
|
...groupsActions(
|
||||||
|
setLocalTypebot as SetTypebot,
|
||||||
|
scopedT('groups.copy.title')
|
||||||
|
),
|
||||||
...blocksAction(setLocalTypebot as SetTypebot),
|
...blocksAction(setLocalTypebot as SetTypebot),
|
||||||
...variablesAction(setLocalTypebot as SetTypebot),
|
...variablesAction(setLocalTypebot as SetTypebot),
|
||||||
...edgesAction(setLocalTypebot as SetTypebot),
|
...edgesAction(setLocalTypebot as SetTypebot),
|
||||||
|
@ -28,7 +28,10 @@ export type GroupsActions = {
|
|||||||
deleteGroup: (groupIndex: number) => void
|
deleteGroup: (groupIndex: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const groupsActions = (setTypebot: SetTypebot): GroupsActions => ({
|
const groupsActions = (
|
||||||
|
setTypebot: SetTypebot,
|
||||||
|
groupCopyLabel: string
|
||||||
|
): GroupsActions => ({
|
||||||
createGroup: ({
|
createGroup: ({
|
||||||
id,
|
id,
|
||||||
block,
|
block,
|
||||||
@ -63,11 +66,12 @@ const groupsActions = (setTypebot: SetTypebot): GroupsActions => ({
|
|||||||
produce(typebot, (typebot) => {
|
produce(typebot, (typebot) => {
|
||||||
const group = typebot.groups[groupIndex]
|
const group = typebot.groups[groupIndex]
|
||||||
const id = createId()
|
const id = createId()
|
||||||
|
|
||||||
const newGroup: Group = {
|
const newGroup: Group = {
|
||||||
...group,
|
...group,
|
||||||
title: isEmpty(group.title)
|
title: isEmpty(group.title)
|
||||||
? ''
|
? ''
|
||||||
: `${parseGroupTitle(group.title)} copy`,
|
: `${parseGroupTitle(group.title)} ${groupCopyLabel}`,
|
||||||
id,
|
id,
|
||||||
blocks: group.blocks.map((block) => duplicateBlockDraft(id)(block)),
|
blocks: group.blocks.map((block) => duplicateBlockDraft(id)(block)),
|
||||||
graphCoordinates: {
|
graphCoordinates: {
|
||||||
|
@ -42,12 +42,14 @@ import { ChatwootNodeBody } from '@/features/blocks/integrations/chatwoot/compon
|
|||||||
import { AbTestNodeBody } from '@/features/blocks/logic/abTest/components/AbTestNodeBody'
|
import { AbTestNodeBody } from '@/features/blocks/logic/abTest/components/AbTestNodeBody'
|
||||||
import { PictureChoiceNode } from '@/features/blocks/inputs/pictureChoice/components/PictureChoiceNode'
|
import { PictureChoiceNode } from '@/features/blocks/inputs/pictureChoice/components/PictureChoiceNode'
|
||||||
import { PixelNodeBody } from '@/features/blocks/integrations/pixel/components/PixelNodeBody'
|
import { PixelNodeBody } from '@/features/blocks/integrations/pixel/components/PixelNodeBody'
|
||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
block: Block | StartBlock
|
block: Block | StartBlock
|
||||||
indices: BlockIndices
|
indices: BlockIndices
|
||||||
}
|
}
|
||||||
export const BlockNodeContent = ({ block, indices }: Props): JSX.Element => {
|
export const BlockNodeContent = ({ block, indices }: Props): JSX.Element => {
|
||||||
|
const scopedT = useScopedI18n('editor.blocks.start')
|
||||||
switch (block.type) {
|
switch (block.type) {
|
||||||
case BubbleBlockType.TEXT: {
|
case BubbleBlockType.TEXT: {
|
||||||
return <TextBubbleContent block={block} />
|
return <TextBubbleContent block={block} />
|
||||||
@ -199,7 +201,7 @@ export const BlockNodeContent = ({ block, indices }: Props): JSX.Element => {
|
|||||||
return <PixelNodeBody options={block.options} />
|
return <PixelNodeBody options={block.options} />
|
||||||
}
|
}
|
||||||
case 'start': {
|
case 'start': {
|
||||||
return <Text>Start</Text>
|
return <Text>{scopedT('text')}</Text>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,10 @@ import { useWorkspace } from '@/features/workspace/WorkspaceProvider'
|
|||||||
import { useUser } from '@/features/account/hooks/useUser'
|
import { useUser } from '@/features/account/hooks/useUser'
|
||||||
import { useToast } from '@/hooks/useToast'
|
import { useToast } from '@/hooks/useToast'
|
||||||
import { trpc } from '@/lib/trpc'
|
import { trpc } from '@/lib/trpc'
|
||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
|
|
||||||
export const CreateNewTypebotButtons = () => {
|
export const CreateNewTypebotButtons = () => {
|
||||||
|
const scopedT = useScopedI18n('templates.buttons')
|
||||||
const { workspace } = useWorkspace()
|
const { workspace } = useWorkspace()
|
||||||
const { user } = useUser()
|
const { user } = useUser()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@ -70,7 +72,7 @@ export const CreateNewTypebotButtons = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<VStack maxW="600px" w="full" flex="1" pt="20" spacing={10}>
|
<VStack maxW="600px" w="full" flex="1" pt="20" spacing={10}>
|
||||||
<Heading>Create a new typebot</Heading>
|
<Heading>{scopedT('heading')}</Heading>
|
||||||
<Stack w="full" spacing={6}>
|
<Stack w="full" spacing={6}>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
@ -87,7 +89,7 @@ export const CreateNewTypebotButtons = () => {
|
|||||||
onClick={() => handleCreateSubmit()}
|
onClick={() => handleCreateSubmit()}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
>
|
>
|
||||||
Start from scratch
|
{scopedT('fromScratchButton.label')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
@ -104,7 +106,7 @@ export const CreateNewTypebotButtons = () => {
|
|||||||
onClick={onOpen}
|
onClick={onOpen}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
>
|
>
|
||||||
Start from a template
|
{scopedT('fromTemplateButton.label')}
|
||||||
</Button>
|
</Button>
|
||||||
<ImportTypebotFromFileButton
|
<ImportTypebotFromFileButton
|
||||||
variant="outline"
|
variant="outline"
|
||||||
@ -121,7 +123,7 @@ export const CreateNewTypebotButtons = () => {
|
|||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
onNewTypebot={handleCreateSubmit}
|
onNewTypebot={handleCreateSubmit}
|
||||||
>
|
>
|
||||||
Import a file
|
{scopedT('importFileButton.label')}
|
||||||
</ImportTypebotFromFileButton>
|
</ImportTypebotFromFileButton>
|
||||||
</Stack>
|
</Stack>
|
||||||
<TemplatesModal
|
<TemplatesModal
|
||||||
|
@ -4,6 +4,7 @@ import { Typebot, typebotCreateSchema } from '@typebot.io/schemas'
|
|||||||
import { preprocessTypebot } from '@typebot.io/schemas/features/typebot/helpers/preprocessTypebot'
|
import { preprocessTypebot } from '@typebot.io/schemas/features/typebot/helpers/preprocessTypebot'
|
||||||
import React, { ChangeEvent } from 'react'
|
import React, { ChangeEvent } from 'react'
|
||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
onNewTypebot: (typebot: Typebot) => void
|
onNewTypebot: (typebot: Typebot) => void
|
||||||
@ -13,6 +14,7 @@ export const ImportTypebotFromFileButton = ({
|
|||||||
onNewTypebot,
|
onNewTypebot,
|
||||||
...props
|
...props
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
|
const scopedT = useScopedI18n('templates.importFromFileButon')
|
||||||
const { showToast } = useToast()
|
const { showToast } = useToast()
|
||||||
|
|
||||||
const handleInputChange = async (e: ChangeEvent<HTMLInputElement>) => {
|
const handleInputChange = async (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
@ -27,7 +29,7 @@ export const ImportTypebotFromFileButton = ({
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
showToast({
|
showToast({
|
||||||
description: "Failed to parse the file. Are you sure it's a typebot?",
|
description: scopedT('toastError.description'),
|
||||||
details: {
|
details: {
|
||||||
content: JSON.stringify(err, null, 2),
|
content: JSON.stringify(err, null, 2),
|
||||||
lang: 'json',
|
lang: 'json',
|
||||||
|
@ -19,6 +19,7 @@ import { templates } from '../data'
|
|||||||
import { TemplateProps } from '../types'
|
import { TemplateProps } from '../types'
|
||||||
import { useToast } from '@/hooks/useToast'
|
import { useToast } from '@/hooks/useToast'
|
||||||
import { sendRequest } from '@typebot.io/lib'
|
import { sendRequest } from '@typebot.io/lib'
|
||||||
|
import { useScopedI18n } from '@/locales'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean
|
isOpen: boolean
|
||||||
@ -27,6 +28,7 @@ type Props = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => {
|
export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => {
|
||||||
|
const scopedT = useScopedI18n('templates.modal')
|
||||||
const templateCardBackgroundColor = useColorModeValue('white', 'gray.800')
|
const templateCardBackgroundColor = useColorModeValue('white', 'gray.800')
|
||||||
const [typebot, setTypebot] = useState<Typebot>()
|
const [typebot, setTypebot] = useState<Typebot>()
|
||||||
const [selectedTemplate, setSelectedTemplate] = useState<TemplateProps>(
|
const [selectedTemplate, setSelectedTemplate] = useState<TemplateProps>(
|
||||||
@ -88,7 +90,7 @@ export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => {
|
|||||||
pl="1"
|
pl="1"
|
||||||
color="gray.500"
|
color="gray.500"
|
||||||
>
|
>
|
||||||
Marketing
|
{scopedT('menuHeading.marketing')}
|
||||||
</Text>
|
</Text>
|
||||||
{templates
|
{templates
|
||||||
.filter((template) => template.category === 'marketing')
|
.filter((template) => template.category === 'marketing')
|
||||||
@ -110,7 +112,7 @@ export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => {
|
|||||||
<Text>{template.name}</Text>
|
<Text>{template.name}</Text>
|
||||||
{template.isNew && (
|
{template.isNew && (
|
||||||
<Tag colorScheme="orange" size="sm" flexShrink={0}>
|
<Tag colorScheme="orange" size="sm" flexShrink={0}>
|
||||||
New
|
{scopedT('menuHeading.new.tag')}
|
||||||
</Tag>
|
</Tag>
|
||||||
)}
|
)}
|
||||||
</HStack>
|
</HStack>
|
||||||
@ -124,7 +126,7 @@ export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => {
|
|||||||
pl="1"
|
pl="1"
|
||||||
color="gray.500"
|
color="gray.500"
|
||||||
>
|
>
|
||||||
Product
|
{scopedT('menuHeading.product')}
|
||||||
</Text>
|
</Text>
|
||||||
{templates
|
{templates
|
||||||
.filter((template) => template.category === 'product')
|
.filter((template) => template.category === 'product')
|
||||||
@ -146,7 +148,7 @@ export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => {
|
|||||||
<Text>{template.name}</Text>
|
<Text>{template.name}</Text>
|
||||||
{template.isNew && (
|
{template.isNew && (
|
||||||
<Tag colorScheme="orange" size="sm" flexShrink={0}>
|
<Tag colorScheme="orange" size="sm" flexShrink={0}>
|
||||||
New
|
{scopedT('menuHeading.new.tag')}
|
||||||
</Tag>
|
</Tag>
|
||||||
)}
|
)}
|
||||||
</HStack>
|
</HStack>
|
||||||
@ -160,7 +162,7 @@ export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => {
|
|||||||
pl="1"
|
pl="1"
|
||||||
color="gray.500"
|
color="gray.500"
|
||||||
>
|
>
|
||||||
Other
|
{scopedT('menuHeading.other')}
|
||||||
</Text>
|
</Text>
|
||||||
{templates
|
{templates
|
||||||
.filter((template) => template.category === undefined)
|
.filter((template) => template.category === undefined)
|
||||||
@ -182,7 +184,7 @@ export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => {
|
|||||||
<Text>{template.name}</Text>
|
<Text>{template.name}</Text>
|
||||||
{template.isNew && (
|
{template.isNew && (
|
||||||
<Tag colorScheme="orange" size="sm" flexShrink={0}>
|
<Tag colorScheme="orange" size="sm" flexShrink={0}>
|
||||||
New
|
{scopedT('menuHeading.new.tag')}
|
||||||
</Tag>
|
</Tag>
|
||||||
)}
|
)}
|
||||||
</HStack>
|
</HStack>
|
||||||
@ -229,7 +231,7 @@ export const TemplatesModal = ({ isOpen, onClose, onTypebotChoose }: Props) => {
|
|||||||
onClick={onUseThisTemplateClick}
|
onClick={onUseThisTemplateClick}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
>
|
>
|
||||||
Use this template
|
{scopedT('useTemplateButton.label')}
|
||||||
</Button>
|
</Button>
|
||||||
</HStack>
|
</HStack>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
@ -122,6 +122,7 @@ export default defineLocale({
|
|||||||
'Um {type} hinzuzufügen, musst du deinen Tarif aktualisieren',
|
'Um {type} hinzuzufügen, musst du deinen Tarif aktualisieren',
|
||||||
'billing.currentSubscription.heading': 'Abonnement',
|
'billing.currentSubscription.heading': 'Abonnement',
|
||||||
'billing.currentSubscription.subheading': 'Aktuelles Workspace-Abonnement:',
|
'billing.currentSubscription.subheading': 'Aktuelles Workspace-Abonnement:',
|
||||||
|
'billing.currentSubscription.cancelDate': 'Wird storniert am',
|
||||||
'billing.invoices.heading': 'Rechnungen',
|
'billing.invoices.heading': 'Rechnungen',
|
||||||
'billing.invoices.empty': 'Keine Rechnungen für diesen Workspace gefunden.',
|
'billing.invoices.empty': 'Keine Rechnungen für diesen Workspace gefunden.',
|
||||||
'billing.invoices.paidAt': 'Bezahlt am',
|
'billing.invoices.paidAt': 'Bezahlt am',
|
||||||
@ -154,6 +155,7 @@ export default defineLocale({
|
|||||||
'billing.pricingCard.pro.customDomains': 'Eigene Domains',
|
'billing.pricingCard.pro.customDomains': 'Eigene Domains',
|
||||||
'billing.pricingCard.pro.analytics': 'Detaillierte Analysen',
|
'billing.pricingCard.pro.analytics': 'Detaillierte Analysen',
|
||||||
'billing.usage.heading': 'Nutzung',
|
'billing.usage.heading': 'Nutzung',
|
||||||
|
'billing.usage.unlimited': 'Unbegrenzt',
|
||||||
'billing.usage.chats.heading': 'Chats',
|
'billing.usage.chats.heading': 'Chats',
|
||||||
'billing.usage.chats.alert.soonReach':
|
'billing.usage.chats.alert.soonReach':
|
||||||
'Deine Typebots sind beliebt! Du wirst bald das Chat-Limit deines Tarifs erreichen. 🚀',
|
'Deine Typebots sind beliebt! Du wirst bald das Chat-Limit deines Tarifs erreichen. 🚀',
|
||||||
@ -190,4 +192,135 @@ export default defineLocale({
|
|||||||
'workspace.settings.modal.menu.version.label': 'Version: {version}',
|
'workspace.settings.modal.menu.version.label': 'Version: {version}',
|
||||||
'workspace.dropdown.newButton.label': 'Neuer Workspace',
|
'workspace.dropdown.newButton.label': 'Neuer Workspace',
|
||||||
'workspace.dropdown.logoutButton.label': 'Abmelden',
|
'workspace.dropdown.logoutButton.label': 'Abmelden',
|
||||||
|
|
||||||
|
'templates.buttons.heading': 'Erstelle einen neuen Typebot',
|
||||||
|
'templates.buttons.fromScratchButton.label': 'Von Grund auf starten',
|
||||||
|
'templates.buttons.fromTemplateButton.label': 'Von einer Vorlage starten',
|
||||||
|
'templates.buttons.importFileButton.label': 'Datei importieren',
|
||||||
|
'templates.modal.menuHeading.marketing': 'Marketing',
|
||||||
|
'templates.modal.menuHeading.product': 'Produkt',
|
||||||
|
'templates.modal.menuHeading.other': 'Andere',
|
||||||
|
'templates.modal.menuHeading.new.tag': 'Neu',
|
||||||
|
'templates.modal.useTemplateButton.label': 'Diese Vorlage verwenden',
|
||||||
|
'templates.importFromFileButon.toastError.description':
|
||||||
|
'Konnte die Datei nicht verarbeiten. Bist du sicher, dass es sich um einen Typebot handelt?',
|
||||||
|
'editor.headers.flowButton.label': 'Ablauf',
|
||||||
|
'editor.headers.themeButton.label': 'Design',
|
||||||
|
'editor.headers.settingsButton.label': 'Einstellungen',
|
||||||
|
'editor.headers.shareButton.label': 'Teilen',
|
||||||
|
'editor.headers.resultsButton.label': 'Ergebnisse',
|
||||||
|
'editor.headers.helpButton.label': 'Hilfe',
|
||||||
|
'editor.headers.savingSpinner.label': 'Speichern...',
|
||||||
|
'editor.headers.previewButton.label': 'Vorschau',
|
||||||
|
'editor.sidebarBlocks.sidebar.lock.label': 'Seitenleiste sperren',
|
||||||
|
'editor.sidebarBlocks.sidebar.unlock.label': 'Seitenleiste entsperren',
|
||||||
|
'editor.sidebarBlocks.sidebar.icon.lock.label': 'Sperren',
|
||||||
|
'editor.sidebarBlocks.sidebar.icon.unlock.label': 'Entsperren',
|
||||||
|
'editor.sidebarBlocks.blockType.bubbles.heading': 'Blasen',
|
||||||
|
'editor.sidebarBlocks.blockType.inputs.heading': 'Eingaben',
|
||||||
|
'editor.sidebarBlocks.blockType.logic.heading': 'Logik',
|
||||||
|
'editor.sidebarBlocks.blockType.integrations.heading': 'Integrationen',
|
||||||
|
'editor.sidebarBlock.start.label': 'Start',
|
||||||
|
'editor.sidebarBlock.text.label': 'Text',
|
||||||
|
'editor.sidebarBlock.image.label': 'Bild',
|
||||||
|
'editor.sidebarBlock.video.label': 'Video',
|
||||||
|
'editor.sidebarBlock.embed.label': 'Einbetten',
|
||||||
|
'editor.sidebarBlock.audio.label': 'Audio',
|
||||||
|
'editor.sidebarBlock.number.label': 'Nummer',
|
||||||
|
'editor.sidebarBlock.email.label': 'E-Mail',
|
||||||
|
'editor.sidebarBlock.website.label': 'Website',
|
||||||
|
'editor.sidebarBlock.date.label': 'Datum',
|
||||||
|
'editor.sidebarBlock.phone.label': 'Telefon',
|
||||||
|
'editor.sidebarBlock.button.label': 'Buttons',
|
||||||
|
'editor.sidebarBlock.picChoice.label': 'Bildauswahl',
|
||||||
|
'editor.sidebarBlock.payment.label': 'Zahlung',
|
||||||
|
'editor.sidebarBlock.rating.label': 'Bewertung',
|
||||||
|
'editor.sidebarBlock.file.label': 'Datei',
|
||||||
|
'editor.sidebarBlock.setVariable.label': 'Variable setzen',
|
||||||
|
'editor.sidebarBlock.condition.label': 'Bedingung',
|
||||||
|
'editor.sidebarBlock.redirect.label': 'Weiterleitung',
|
||||||
|
'editor.sidebarBlock.script.label': 'Skript',
|
||||||
|
'editor.sidebarBlock.typebot.label': 'Typebot',
|
||||||
|
'editor.sidebarBlock.wait.label': 'Warten',
|
||||||
|
'editor.sidebarBlock.jump.label': 'Springen',
|
||||||
|
'editor.sidebarBlock.abTest.label': 'AB-Test',
|
||||||
|
'editor.sidebarBlock.sheets.label': 'Tabellen',
|
||||||
|
'editor.sidebarBlock.analytics.label': 'Analytics',
|
||||||
|
'editor.sidebarBlock.webhook.label': 'Webhook',
|
||||||
|
'editor.sidebarBlock.zapier.label': 'Zapier',
|
||||||
|
'editor.sidebarBlock.makecom.label': 'Make.com',
|
||||||
|
'editor.sidebarBlock.pabbly.label': 'Pabbly',
|
||||||
|
'editor.sidebarBlock.chatwoot.label': 'Chatwoot',
|
||||||
|
'editor.sidebarBlock.openai.label': 'OpenAI',
|
||||||
|
'editor.sidebarBlock.pixel.label': 'Pixel',
|
||||||
|
'editor.blockCard.bubbleBlock.tooltip.label':
|
||||||
|
'Ein PDF, ein iframe, eine Website einbetten...',
|
||||||
|
'editor.blockCard.inputBlock.tooltip.files.label': 'Dateien hochladen',
|
||||||
|
'editor.blockCard.logicBlock.tooltip.code.label': 'JavaScript-Code ausführen',
|
||||||
|
'editor.blockCard.logicBlock.tooltip.typebotLink.label':
|
||||||
|
'Verlinkung zu einem anderen Typebot',
|
||||||
|
'editor.blockCard.logicBlock.tooltip.jump.label':
|
||||||
|
'Ablauf zu einer anderen Gruppe beschleunigen',
|
||||||
|
'editor.blockCard.integrationBlock.tooltip.googleSheets.label':
|
||||||
|
'Google Tabellen',
|
||||||
|
'editor.blockCard.integrationBlock.tooltip.googleAnalytics.label':
|
||||||
|
'Google Analytics',
|
||||||
|
'editor.editableTypebotName.tooltip.rename.label': 'Umbenennen',
|
||||||
|
'editor.gettingStartedModal.editorBasics.heading': 'Grundlagen des Editors',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.one.label':
|
||||||
|
'Die Seitenleiste enthält Blöcke, die du auf das Board ziehen und ablegen kannst.',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.two.label':
|
||||||
|
'Du kannst Blöcke gruppieren, indem du sie unter oder über einander ablegst.',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.three.label':
|
||||||
|
'Verbinde die Gruppen miteinander.',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.four.label':
|
||||||
|
'Klicke auf die Vorschau-Schaltfläche oben rechts, um deinen Bot anzusehen.',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.label':
|
||||||
|
'Wenn du Fragen hast, verwende gerne die Sprechblase unten rechts, um sie mir zu stellen. Ich beantworte normalerweise innerhalb der nächsten 24 Stunden. 😃',
|
||||||
|
'editor.gettingStartedModal.seeAction.label': 'In Aktion sehen',
|
||||||
|
'editor.gettingStartedModal.seeAction.time': '5 Minuten',
|
||||||
|
'editor.gettingStartedModal.seeAction.item.label': 'Weitere Videos',
|
||||||
|
'editor.provider.messages.getTypebotError.title':
|
||||||
|
'Fehler beim Abrufen des Typebots. Aktualisiere die Seite.',
|
||||||
|
'editor.provider.messages.getTypebotError.description':
|
||||||
|
'Typebot konnte nicht gefunden werden.',
|
||||||
|
'editor.provider.messages.publishedTypebotError.title':
|
||||||
|
'Fehler beim Abrufen des veröffentlichten Typebots',
|
||||||
|
'editor.provider.messages.updateTypebotError.title':
|
||||||
|
'Fehler beim Aktualisieren des Typebots',
|
||||||
|
'editor.provider.groups.copy.title': 'kopieren',
|
||||||
|
'editor.blocks.start.text': 'Start',
|
||||||
|
'editor.blocks.bubbles.audio.settings.upload.label': 'Hochladen',
|
||||||
|
'editor.blocks.bubbles.audio.settings.embedLink.label': 'Link einbetten',
|
||||||
|
'editor.blocks.bubbles.audio.settings.chooseFile.label': 'Datei auswählen',
|
||||||
|
'editor.blocks.bubbles.audio.settings.worksWith.text':
|
||||||
|
'Funktioniert mit .MP3- und .WAV-Dateien',
|
||||||
|
'editor.blocks.bubbles.audio.settings.worksWith.placeholder':
|
||||||
|
'Füge den Audio-Dateilink ein...',
|
||||||
|
'editor.blocks.bubbles.audio.settings.autoplay.label': 'Autoplay aktivieren',
|
||||||
|
'editor.blocks.bubbles.audio.node.clickToEdit.text':
|
||||||
|
'Zum Bearbeiten klicken...',
|
||||||
|
'editor.blocks.bubbles.embed.node.clickToEdit.text':
|
||||||
|
'Zum Bearbeiten klicken...',
|
||||||
|
'editor.blocks.bubbles.embed.node.show.text': 'Einbetten anzeigen',
|
||||||
|
'editor.blocks.bubbles.embed.settings.worksWith.placeholder':
|
||||||
|
'Füge den Link oder Code ein...',
|
||||||
|
'editor.blocks.bubbles.embed.settings.worksWith.text':
|
||||||
|
'Funktioniert mit PDFs, iframes, Websites...',
|
||||||
|
'editor.blocks.bubbles.embed.settings.numberInput.unit': 'px',
|
||||||
|
'editor.blocks.bubbles.image.node.clickToEdit.text':
|
||||||
|
'Zum Bearbeiten klicken...',
|
||||||
|
'editor.blocks.bubbles.image.switchWithLabel.onClick.label':
|
||||||
|
'Beim Klicken Link',
|
||||||
|
'editor.blocks.bubbles.image.switchWithLabel.onClick.placeholder':
|
||||||
|
'Link Alternativtext (Beschreibung)',
|
||||||
|
'editor.blocks.bubbles.video.node.clickToEdit.text':
|
||||||
|
'Zum Bearbeiten klicken...',
|
||||||
|
'editor.blocks.bubbles.video.settings.worksWith.text':
|
||||||
|
'Funktioniert mit YouTube, Vimeo und anderen',
|
||||||
|
'editor.blocks.bubbles.video.settings.worksWith.placeholder':
|
||||||
|
'Füge den Videolink ein...',
|
||||||
|
'editor.blocks.bubbles.textEditor.plate.label': 'Texteditor',
|
||||||
|
'editor.blocks.bubbles.textEditor.searchVariable.placeholder':
|
||||||
|
'Nach einer Variable suchen',
|
||||||
})
|
})
|
||||||
|
@ -115,6 +115,7 @@ export default {
|
|||||||
'You need to upgrade your plan in order to {type}',
|
'You need to upgrade your plan in order to {type}',
|
||||||
'billing.currentSubscription.heading': 'Subscription',
|
'billing.currentSubscription.heading': 'Subscription',
|
||||||
'billing.currentSubscription.subheading': 'Current workspace subscription:',
|
'billing.currentSubscription.subheading': 'Current workspace subscription:',
|
||||||
|
'billing.currentSubscription.cancelDate': 'Will be cancelled on',
|
||||||
'billing.invoices.heading': 'Invoices',
|
'billing.invoices.heading': 'Invoices',
|
||||||
'billing.invoices.empty': 'No invoices found for this workspace.',
|
'billing.invoices.empty': 'No invoices found for this workspace.',
|
||||||
'billing.invoices.paidAt': 'Paid at',
|
'billing.invoices.paidAt': 'Paid at',
|
||||||
@ -147,6 +148,7 @@ export default {
|
|||||||
'billing.pricingCard.pro.customDomains': 'Custom domains',
|
'billing.pricingCard.pro.customDomains': 'Custom domains',
|
||||||
'billing.pricingCard.pro.analytics': 'In-depth analytics',
|
'billing.pricingCard.pro.analytics': 'In-depth analytics',
|
||||||
'billing.usage.heading': 'Usage',
|
'billing.usage.heading': 'Usage',
|
||||||
|
'billing.usage.unlimited': 'Unlimited',
|
||||||
'billing.usage.chats.heading': 'Chats',
|
'billing.usage.chats.heading': 'Chats',
|
||||||
'billing.usage.chats.alert.soonReach':
|
'billing.usage.chats.alert.soonReach':
|
||||||
"Your typebots are popular! You will soon reach your plan's chats limit. 🚀",
|
"Your typebots are popular! You will soon reach your plan's chats limit. 🚀",
|
||||||
@ -183,4 +185,129 @@ export default {
|
|||||||
'workspace.settings.modal.menu.version.label': 'Version: {version}',
|
'workspace.settings.modal.menu.version.label': 'Version: {version}',
|
||||||
'workspace.dropdown.newButton.label': 'New workspace',
|
'workspace.dropdown.newButton.label': 'New workspace',
|
||||||
'workspace.dropdown.logoutButton.label': 'Log out',
|
'workspace.dropdown.logoutButton.label': 'Log out',
|
||||||
|
'templates.buttons.heading': 'Create a new typebot',
|
||||||
|
'templates.buttons.fromScratchButton.label': 'Start from scratch',
|
||||||
|
'templates.buttons.fromTemplateButton.label': 'Start from a template',
|
||||||
|
'templates.buttons.importFileButton.label': 'Import a file',
|
||||||
|
'templates.modal.menuHeading.marketing': 'Marketing',
|
||||||
|
'templates.modal.menuHeading.product': 'Product',
|
||||||
|
'templates.modal.menuHeading.other': 'Other',
|
||||||
|
'templates.modal.menuHeading.new.tag': 'New',
|
||||||
|
'templates.modal.useTemplateButton.label': 'Use this template',
|
||||||
|
'templates.importFromFileButon.toastError.description':
|
||||||
|
"Failed to parse the file. Are you sure it's a typebot?",
|
||||||
|
'editor.headers.flowButton.label': 'Flow',
|
||||||
|
'editor.headers.themeButton.label': 'Theme',
|
||||||
|
'editor.headers.settingsButton.label': 'Settings',
|
||||||
|
'editor.headers.shareButton.label': 'Share',
|
||||||
|
'editor.headers.resultsButton.label': 'Results',
|
||||||
|
'editor.headers.helpButton.label': 'Help',
|
||||||
|
'editor.headers.savingSpinner.label': 'Saving...',
|
||||||
|
'editor.headers.previewButton.label': 'Preview',
|
||||||
|
'editor.sidebarBlocks.sidebar.lock.label': 'Lock sidebar',
|
||||||
|
'editor.sidebarBlocks.sidebar.unlock.label': 'Unlock sidebar',
|
||||||
|
'editor.sidebarBlocks.sidebar.icon.lock.label': 'Lock',
|
||||||
|
'editor.sidebarBlocks.sidebar.icon.unlock.label': 'Unlock',
|
||||||
|
'editor.sidebarBlocks.blockType.bubbles.heading': 'Bubbles',
|
||||||
|
'editor.sidebarBlocks.blockType.inputs.heading': 'Inputs',
|
||||||
|
'editor.sidebarBlocks.blockType.logic.heading': 'Logic',
|
||||||
|
'editor.sidebarBlocks.blockType.integrations.heading': 'Integrations',
|
||||||
|
'editor.sidebarBlock.start.label': 'Start',
|
||||||
|
'editor.sidebarBlock.text.label': 'Text',
|
||||||
|
'editor.sidebarBlock.image.label': 'Image',
|
||||||
|
'editor.sidebarBlock.video.label': 'Video',
|
||||||
|
'editor.sidebarBlock.embed.label': 'Embed',
|
||||||
|
'editor.sidebarBlock.audio.label': 'Audio',
|
||||||
|
'editor.sidebarBlock.number.label': 'Number',
|
||||||
|
'editor.sidebarBlock.email.label': 'Email',
|
||||||
|
'editor.sidebarBlock.website.label': 'Website',
|
||||||
|
'editor.sidebarBlock.date.label': 'Date',
|
||||||
|
'editor.sidebarBlock.phone.label': 'Phone',
|
||||||
|
'editor.sidebarBlock.button.label': 'Buttons',
|
||||||
|
'editor.sidebarBlock.picChoice.label': 'Pic choice',
|
||||||
|
'editor.sidebarBlock.payment.label': 'Payment',
|
||||||
|
'editor.sidebarBlock.rating.label': 'Rating',
|
||||||
|
'editor.sidebarBlock.file.label': 'File',
|
||||||
|
'editor.sidebarBlock.setVariable.label': 'Set variable',
|
||||||
|
'editor.sidebarBlock.condition.label': 'Condition',
|
||||||
|
'editor.sidebarBlock.redirect.label': 'Redirect',
|
||||||
|
'editor.sidebarBlock.script.label': 'Script',
|
||||||
|
'editor.sidebarBlock.typebot.label': 'Typebot',
|
||||||
|
'editor.sidebarBlock.wait.label': 'Wait',
|
||||||
|
'editor.sidebarBlock.jump.label': 'Jump',
|
||||||
|
'editor.sidebarBlock.abTest.label': 'AB Test',
|
||||||
|
'editor.sidebarBlock.sheets.label': 'Sheets',
|
||||||
|
'editor.sidebarBlock.analytics.label': 'Analytics',
|
||||||
|
'editor.sidebarBlock.webhook.label': 'Webhook',
|
||||||
|
'editor.sidebarBlock.zapier.label': 'Zapier',
|
||||||
|
'editor.sidebarBlock.makecom.label': 'Make.com',
|
||||||
|
'editor.sidebarBlock.pabbly.label': 'Pabbly',
|
||||||
|
'editor.sidebarBlock.chatwoot.label': 'Chatwoot',
|
||||||
|
'editor.sidebarBlock.openai.label': 'OpenAI',
|
||||||
|
'editor.sidebarBlock.pixel.label': 'Pixel',
|
||||||
|
'editor.blockCard.bubbleBlock.tooltip.label':
|
||||||
|
'Embed a pdf, an iframe, a website...',
|
||||||
|
'editor.blockCard.inputBlock.tooltip.files.label': 'Upload Files',
|
||||||
|
'editor.blockCard.logicBlock.tooltip.code.label': 'Execute Javascript code',
|
||||||
|
'editor.blockCard.logicBlock.tooltip.typebotLink.label':
|
||||||
|
'Link and jump to another typebot',
|
||||||
|
'editor.blockCard.logicBlock.tooltip.jump.label':
|
||||||
|
'Fast forward the flow to another group',
|
||||||
|
'editor.blockCard.integrationBlock.tooltip.googleSheets.label':
|
||||||
|
'Google Sheets',
|
||||||
|
'editor.blockCard.integrationBlock.tooltip.googleAnalytics.label':
|
||||||
|
'Google Analytics',
|
||||||
|
'editor.editableTypebotName.tooltip.rename.label': 'Rename',
|
||||||
|
'editor.gettingStartedModal.editorBasics.heading': 'Editor Basics',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.one.label':
|
||||||
|
'The left side bar contains blocks that you can drag and drop to the board.',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.two.label':
|
||||||
|
'You can group blocks together by dropping them below or above each other',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.three.label':
|
||||||
|
'Connect the groups together',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.four.label':
|
||||||
|
'Preview your bot by clicking the preview button on the top right',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.label':
|
||||||
|
'Feel free to use the bottom-right bubble to reach out if you have any question. I usually answer within the next 24 hours. 😃',
|
||||||
|
'editor.gettingStartedModal.seeAction.label': 'See it in action',
|
||||||
|
'editor.gettingStartedModal.seeAction.time': '5 minutes',
|
||||||
|
'editor.gettingStartedModal.seeAction.item.label': 'Other videos',
|
||||||
|
'editor.provider.messages.getTypebotError.title':
|
||||||
|
'Error while fetching typebot. Refresh the page.',
|
||||||
|
'editor.provider.messages.getTypebotError.description':
|
||||||
|
"Couldn't find typebot",
|
||||||
|
'editor.provider.messages.publishedTypebotError.title':
|
||||||
|
'Error while fetching published typebot',
|
||||||
|
'editor.provider.messages.updateTypebotError.title':
|
||||||
|
'Error while updating typebot',
|
||||||
|
'editor.provider.groups.copy.title': 'copy',
|
||||||
|
'editor.blocks.start.text': 'Start',
|
||||||
|
'editor.blocks.bubbles.audio.settings.upload.label': 'Upload',
|
||||||
|
'editor.blocks.bubbles.audio.settings.embedLink.label': 'Embed link',
|
||||||
|
'editor.blocks.bubbles.audio.settings.chooseFile.label': 'Choose a file',
|
||||||
|
'editor.blocks.bubbles.audio.settings.worksWith.text':
|
||||||
|
'Works with .MP3s and .WAVs',
|
||||||
|
'editor.blocks.bubbles.audio.settings.worksWith.placeholder':
|
||||||
|
'Paste the audio file link...',
|
||||||
|
'editor.blocks.bubbles.audio.settings.autoplay.label': 'Enable autoplay',
|
||||||
|
'editor.blocks.bubbles.audio.node.clickToEdit.text': 'Click to edit...',
|
||||||
|
'editor.blocks.bubbles.embed.node.clickToEdit.text': 'Click to edit...',
|
||||||
|
'editor.blocks.bubbles.embed.node.show.text': 'Show embed',
|
||||||
|
'editor.blocks.bubbles.embed.settings.worksWith.placeholder':
|
||||||
|
'Paste the link or code...',
|
||||||
|
'editor.blocks.bubbles.embed.settings.worksWith.text':
|
||||||
|
'Works with PDFs, iframes, websites...',
|
||||||
|
'editor.blocks.bubbles.embed.settings.numberInput.unit': 'px',
|
||||||
|
'editor.blocks.bubbles.image.node.clickToEdit.text': 'Click to edit...',
|
||||||
|
'editor.blocks.bubbles.image.switchWithLabel.onClick.label': 'On click link',
|
||||||
|
'editor.blocks.bubbles.image.switchWithLabel.onClick.placeholder':
|
||||||
|
'Link alt text (description)',
|
||||||
|
'editor.blocks.bubbles.video.node.clickToEdit.text': 'Click to edit...',
|
||||||
|
'editor.blocks.bubbles.video.settings.worksWith.text':
|
||||||
|
'Works with Youtube, Vimeo and others',
|
||||||
|
'editor.blocks.bubbles.video.settings.worksWith.placeholder':
|
||||||
|
'Paste the video link...',
|
||||||
|
'editor.blocks.bubbles.textEditor.plate.label': 'Text editor',
|
||||||
|
'editor.blocks.bubbles.textEditor.searchVariable.placeholder':
|
||||||
|
'Search for a variable',
|
||||||
} as const
|
} as const
|
||||||
|
@ -119,6 +119,7 @@ export default defineLocale({
|
|||||||
'Tu dois mettre à niveau ton abonnement pour {type}',
|
'Tu dois mettre à niveau ton abonnement pour {type}',
|
||||||
'billing.currentSubscription.heading': 'Abonnement',
|
'billing.currentSubscription.heading': 'Abonnement',
|
||||||
'billing.currentSubscription.subheading': 'Abonnement actuel du workspace :',
|
'billing.currentSubscription.subheading': 'Abonnement actuel du workspace :',
|
||||||
|
'billing.currentSubscription.cancelDate': 'Sera annulé le',
|
||||||
'billing.invoices.heading': 'Factures',
|
'billing.invoices.heading': 'Factures',
|
||||||
'billing.invoices.empty': 'Aucune facture trouvée pour ce workspace.',
|
'billing.invoices.empty': 'Aucune facture trouvée pour ce workspace.',
|
||||||
'billing.invoices.paidAt': 'Payé le',
|
'billing.invoices.paidAt': 'Payé le',
|
||||||
@ -153,6 +154,7 @@ export default defineLocale({
|
|||||||
'billing.pricingCard.pro.customDomains': 'Domaines personnalisés',
|
'billing.pricingCard.pro.customDomains': 'Domaines personnalisés',
|
||||||
'billing.pricingCard.pro.analytics': 'Analyses approfondies',
|
'billing.pricingCard.pro.analytics': 'Analyses approfondies',
|
||||||
'billing.usage.heading': 'Utilisation',
|
'billing.usage.heading': 'Utilisation',
|
||||||
|
'billing.usage.unlimited': 'Illimité',
|
||||||
'billing.usage.chats.heading': 'Chats',
|
'billing.usage.chats.heading': 'Chats',
|
||||||
'billing.usage.chats.alert.soonReach':
|
'billing.usage.chats.alert.soonReach':
|
||||||
'Tes typebots sont populaires ! Tu atteindras bientôt la limite de chats de votre abonnement. 🚀',
|
'Tes typebots sont populaires ! Tu atteindras bientôt la limite de chats de votre abonnement. 🚀',
|
||||||
@ -190,4 +192,138 @@ export default defineLocale({
|
|||||||
'workspace.settings.modal.menu.version.label': 'Version : {version}',
|
'workspace.settings.modal.menu.version.label': 'Version : {version}',
|
||||||
'workspace.dropdown.newButton.label': 'Nouveau workspace',
|
'workspace.dropdown.newButton.label': 'Nouveau workspace',
|
||||||
'workspace.dropdown.logoutButton.label': 'Déconnexion',
|
'workspace.dropdown.logoutButton.label': 'Déconnexion',
|
||||||
|
'templates.buttons.heading': 'Créer un nouveau typebot',
|
||||||
|
'templates.buttons.fromScratchButton.label': 'Commencer à partir de zéro',
|
||||||
|
'templates.buttons.fromTemplateButton.label':
|
||||||
|
"Commencer à partir d'un modèle",
|
||||||
|
'templates.buttons.importFileButton.label': 'Importer un fichier',
|
||||||
|
'templates.modal.menuHeading.marketing': 'Marketing',
|
||||||
|
'templates.modal.menuHeading.product': 'Produit',
|
||||||
|
'templates.modal.menuHeading.other': 'Autre',
|
||||||
|
'templates.modal.menuHeading.new.tag': 'Nouveau',
|
||||||
|
'templates.modal.useTemplateButton.label': 'Utiliser ce modèle',
|
||||||
|
'templates.importFromFileButon.toastError.description':
|
||||||
|
"Échec de l'analyse du fichier. Es-tu sûr que c'est un typebot ?",
|
||||||
|
'editor.headers.flowButton.label': 'Flow',
|
||||||
|
'editor.headers.themeButton.label': 'Thème',
|
||||||
|
'editor.headers.settingsButton.label': 'Paramètres',
|
||||||
|
'editor.headers.shareButton.label': 'Partager',
|
||||||
|
'editor.headers.resultsButton.label': 'Résultats',
|
||||||
|
'editor.headers.helpButton.label': 'Aide',
|
||||||
|
'editor.headers.savingSpinner.label': 'Enregistrement...',
|
||||||
|
'editor.headers.previewButton.label': 'Tester',
|
||||||
|
'editor.sidebarBlocks.sidebar.lock.label': 'Fermer la barre latérale',
|
||||||
|
'editor.sidebarBlocks.sidebar.unlock.label': 'Ouvrir la barre latérale',
|
||||||
|
'editor.sidebarBlocks.sidebar.icon.lock.label': 'Fermée',
|
||||||
|
'editor.sidebarBlocks.sidebar.icon.unlock.label': 'Ouverte',
|
||||||
|
'editor.sidebarBlocks.blockType.bubbles.heading': 'Bulles',
|
||||||
|
'editor.sidebarBlocks.blockType.inputs.heading': 'Inputs',
|
||||||
|
'editor.sidebarBlocks.blockType.logic.heading': 'Logique',
|
||||||
|
'editor.sidebarBlocks.blockType.integrations.heading': 'Intégrations',
|
||||||
|
'editor.sidebarBlock.start.label': 'Démarrer',
|
||||||
|
'editor.sidebarBlock.text.label': 'Texte',
|
||||||
|
'editor.sidebarBlock.image.label': 'Image',
|
||||||
|
'editor.sidebarBlock.video.label': 'Vidéo',
|
||||||
|
'editor.sidebarBlock.embed.label': 'Iframe',
|
||||||
|
'editor.sidebarBlock.audio.label': 'Audio',
|
||||||
|
'editor.sidebarBlock.number.label': 'Nombre',
|
||||||
|
'editor.sidebarBlock.email.label': 'Email',
|
||||||
|
'editor.sidebarBlock.website.label': 'Site web',
|
||||||
|
'editor.sidebarBlock.date.label': 'Date',
|
||||||
|
'editor.sidebarBlock.phone.label': 'Téléphone',
|
||||||
|
'editor.sidebarBlock.button.label': 'Boutons',
|
||||||
|
'editor.sidebarBlock.picChoice.label': 'Choix image',
|
||||||
|
'editor.sidebarBlock.payment.label': 'Paiement',
|
||||||
|
'editor.sidebarBlock.rating.label': 'Évaluation',
|
||||||
|
'editor.sidebarBlock.file.label': 'Fichier',
|
||||||
|
'editor.sidebarBlock.setVariable.label': 'Définir variable',
|
||||||
|
'editor.sidebarBlock.condition.label': 'Condition',
|
||||||
|
'editor.sidebarBlock.redirect.label': 'Rediriger',
|
||||||
|
'editor.sidebarBlock.script.label': 'Script',
|
||||||
|
'editor.sidebarBlock.typebot.label': 'Typebot',
|
||||||
|
'editor.sidebarBlock.wait.label': 'Attendre',
|
||||||
|
'editor.sidebarBlock.jump.label': 'Sauter',
|
||||||
|
'editor.sidebarBlock.abTest.label': 'AB Test',
|
||||||
|
'editor.sidebarBlock.sheets.label': 'Sheets',
|
||||||
|
'editor.sidebarBlock.analytics.label': 'Analytics',
|
||||||
|
'editor.sidebarBlock.webhook.label': 'Webhook',
|
||||||
|
'editor.sidebarBlock.zapier.label': 'Zapier',
|
||||||
|
'editor.sidebarBlock.makecom.label': 'Make.com',
|
||||||
|
'editor.sidebarBlock.pabbly.label': 'Pabbly',
|
||||||
|
'editor.sidebarBlock.chatwoot.label': 'Chatwoot',
|
||||||
|
'editor.sidebarBlock.openai.label': 'OpenAI',
|
||||||
|
'editor.sidebarBlock.pixel.label': 'Pixel',
|
||||||
|
'editor.blockCard.bubbleBlock.tooltip.label':
|
||||||
|
'Intégrer un pdf, un iframe, un site web...',
|
||||||
|
'editor.blockCard.inputBlock.tooltip.files.label': 'Télécharger des fichiers',
|
||||||
|
'editor.blockCard.logicBlock.tooltip.code.label':
|
||||||
|
'Exécuter du code Javascript',
|
||||||
|
'editor.blockCard.logicBlock.tooltip.typebotLink.label':
|
||||||
|
'Lier et exécuter un autre typebot',
|
||||||
|
'editor.blockCard.logicBlock.tooltip.jump.label':
|
||||||
|
'Passer rapidement au groupe suivant',
|
||||||
|
'editor.blockCard.integrationBlock.tooltip.googleSheets.label':
|
||||||
|
'Google Sheets',
|
||||||
|
'editor.blockCard.integrationBlock.tooltip.googleAnalytics.label':
|
||||||
|
'Google Analytics',
|
||||||
|
'editor.editableTypebotName.tooltip.rename.label': 'Renommer',
|
||||||
|
'editor.gettingStartedModal.editorBasics.heading':
|
||||||
|
"Principes de base de l'éditeur",
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.one.label':
|
||||||
|
'La barre latérale de gauche contient des blocs que vous pouvez glisser-déposer sur le graph.',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.two.label':
|
||||||
|
'Vous pouvez regrouper les blocs en les déposant les uns au-dessus ou en-dessous des autres.',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.three.label':
|
||||||
|
'Connectez les groupes ensemble.',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.four.label':
|
||||||
|
'Prévisualisez votre bot en cliquant sur le bouton "Tester" en haut à droite.',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.label':
|
||||||
|
"N'hésitez pas à utiliser la bulle en bas à droite pour me poser des questions. Je réponds généralement dans les 24 heures. 😃",
|
||||||
|
'editor.gettingStartedModal.seeAction.label': 'Voir en action',
|
||||||
|
'editor.gettingStartedModal.seeAction.time': '5 minutes',
|
||||||
|
'editor.gettingStartedModal.seeAction.item.label': 'Autres vidéos',
|
||||||
|
'editor.provider.messages.getTypebotError.title':
|
||||||
|
'Erreur lors de la récupération du typebot. Rafraîchissez la page.',
|
||||||
|
'editor.provider.messages.getTypebotError.description':
|
||||||
|
'Impossible de trouver le typebot.',
|
||||||
|
'editor.provider.messages.publishedTypebotError.title':
|
||||||
|
'Erreur lors de la récupération du typebot publié',
|
||||||
|
'editor.provider.messages.updateTypebotError.title':
|
||||||
|
'Erreur lors de la mise à jour du typebot',
|
||||||
|
'editor.provider.groups.copy.title': 'copier',
|
||||||
|
'editor.blocks.start.text': 'Démarrer',
|
||||||
|
'editor.blocks.bubbles.audio.settings.upload.label': 'Uploader',
|
||||||
|
'editor.blocks.bubbles.audio.settings.embedLink.label': 'Lien intégré',
|
||||||
|
'editor.blocks.bubbles.audio.settings.chooseFile.label': 'Choisir un fichier',
|
||||||
|
'editor.blocks.bubbles.audio.settings.worksWith.text':
|
||||||
|
'Fonctionne avec les fichiers .MP3 et .WAV',
|
||||||
|
'editor.blocks.bubbles.audio.settings.worksWith.placeholder':
|
||||||
|
'Collez le lien du fichier audio...',
|
||||||
|
'editor.blocks.bubbles.audio.settings.autoplay.label':
|
||||||
|
'Activer la lecture automatique',
|
||||||
|
'editor.blocks.bubbles.audio.node.clickToEdit.text':
|
||||||
|
'Cliquez pour modifier...',
|
||||||
|
'editor.blocks.bubbles.embed.node.clickToEdit.text':
|
||||||
|
'Cliquez pour modifier...',
|
||||||
|
'editor.blocks.bubbles.embed.node.show.text': "Afficher l'intégration",
|
||||||
|
'editor.blocks.bubbles.embed.settings.worksWith.placeholder':
|
||||||
|
'Collez le lien ou le code...',
|
||||||
|
'editor.blocks.bubbles.embed.settings.worksWith.text':
|
||||||
|
'Fonctionne avec les PDF, les iframes, les sites web...',
|
||||||
|
'editor.blocks.bubbles.embed.settings.numberInput.unit': 'px',
|
||||||
|
'editor.blocks.bubbles.image.node.clickToEdit.text':
|
||||||
|
'Cliquez pour modifier...',
|
||||||
|
'editor.blocks.bubbles.image.switchWithLabel.onClick.label':
|
||||||
|
'Redirection au clic',
|
||||||
|
'editor.blocks.bubbles.image.switchWithLabel.onClick.placeholder':
|
||||||
|
'Texte alternatif du lien (description)',
|
||||||
|
'editor.blocks.bubbles.video.node.clickToEdit.text':
|
||||||
|
'Cliquez pour modifier...',
|
||||||
|
'editor.blocks.bubbles.video.settings.worksWith.text':
|
||||||
|
'Fonctionne avec Youtube, Vimeo et autres',
|
||||||
|
'editor.blocks.bubbles.video.settings.worksWith.placeholder':
|
||||||
|
'Collez le lien de la vidéo...',
|
||||||
|
'editor.blocks.bubbles.textEditor.plate.label': 'Éditeur de texte',
|
||||||
|
'editor.blocks.bubbles.textEditor.searchVariable.placeholder':
|
||||||
|
'Rechercher une variable',
|
||||||
})
|
})
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import { createI18n } from 'next-international'
|
import { createI18n } from 'next-international'
|
||||||
|
|
||||||
|
export type I18nFunction = (key: string) => string;
|
||||||
|
|
||||||
export const {
|
export const {
|
||||||
useI18n,
|
useI18n,
|
||||||
useScopedI18n,
|
useScopedI18n,
|
||||||
@ -9,8 +11,9 @@ export const {
|
|||||||
useChangeLocale,
|
useChangeLocale,
|
||||||
defineLocale,
|
defineLocale,
|
||||||
} = createI18n({
|
} = createI18n({
|
||||||
en: () => import('./en'),
|
en: () => import('./en'),
|
||||||
fr: () => import('./fr'),
|
fr: () => import('./fr'),
|
||||||
pt: () => import('./pt'),
|
pt: () => import('./pt'),
|
||||||
de: () => import('./de'),
|
pt_BR: () => import('./pt_BR'),
|
||||||
|
de: () => import('./de'),
|
||||||
})
|
})
|
@ -2,10 +2,10 @@ import { defineLocale } from '.'
|
|||||||
|
|
||||||
export default defineLocale({
|
export default defineLocale({
|
||||||
back: 'Voltar',
|
back: 'Voltar',
|
||||||
'confirmModal.defaultTitle': 'Tem certeza?',
|
'confirmModal.defaultTitle': 'Tem a certeza?',
|
||||||
'dashboard.header.settingsButton.label': 'Configurações & Membros',
|
'dashboard.header.settingsButton.label': 'Configurações & Membros',
|
||||||
'dashboard.redirectionMessage': 'Você está sendo redirecionado...',
|
'dashboard.redirectionMessage': 'Está a ser redirecionado...',
|
||||||
'dashboard.title': 'Meus typebots',
|
'dashboard.title': 'Os meus typebots',
|
||||||
delete: 'Apagar',
|
delete: 'Apagar',
|
||||||
errorMessage: 'Ocorreu um erro',
|
errorMessage: 'Ocorreu um erro',
|
||||||
cancel: 'Cancelar',
|
cancel: 'Cancelar',
|
||||||
@ -14,48 +14,48 @@ export default defineLocale({
|
|||||||
downgrade: 'Downgrade',
|
downgrade: 'Downgrade',
|
||||||
remove: 'Remover',
|
remove: 'Remover',
|
||||||
pending: 'Pendente',
|
pending: 'Pendente',
|
||||||
skip: 'Pular',
|
skip: 'Saltar',
|
||||||
'folders.createFolderButton.label': 'Criar uma pasta',
|
'folders.createFolderButton.label': 'Criar uma pasta',
|
||||||
'folders.createTypebotButton.label': 'Criar um typebot',
|
'folders.createTypebotButton.label': 'Criar um typebot',
|
||||||
'folders.folderButton.deleteConfirmationMessage':
|
'folders.folderButton.deleteConfirmationMessage':
|
||||||
'Tem certeza de que deseja excluir a pasta {folderName}? (Tudo o que estiver dentro será movido para o seu painel)',
|
'Tem a certeza de que deseja excluir a pasta {folderName}? (Tudo o que estiver dentro será movido para o seu painel)',
|
||||||
'folders.typebotButton.live': 'Live',
|
'folders.typebotButton.live': 'Ao Vivo',
|
||||||
'folders.typebotButton.showMoreOptions': 'Mostrar mais opções',
|
'folders.typebotButton.showMoreOptions': 'Mostrar mais opções',
|
||||||
'folders.typebotButton.unpublish': 'Despublicar',
|
'folders.typebotButton.unpublish': 'Despublicar',
|
||||||
'folders.typebotButton.duplicate': 'Duplicar',
|
'folders.typebotButton.duplicate': 'Duplicar',
|
||||||
'folders.typebotButton.delete': 'Apagar',
|
'folders.typebotButton.delete': 'Apagar',
|
||||||
'folders.typebotButton.deleteConfirmationMessage':
|
'folders.typebotButton.deleteConfirmationMessage':
|
||||||
'Tem certeza de que deseja excluir seu typebot {typebotName}?',
|
'Tem a certeza de que deseja excluir o seu typebot {typebotName}?',
|
||||||
'folders.typebotButton.deleteConfirmationMessageWarning':
|
'folders.typebotButton.deleteConfirmationMessageWarning':
|
||||||
'Todos os dados associados serão excluídos e não poderão ser recuperados.',
|
'Todos os dados associados serão excluídos e não poderão ser recuperados.',
|
||||||
'account.apiTokens.heading': 'Tokens de API',
|
'account.apiTokens.heading': 'Tokens de API',
|
||||||
'account.apiTokens.description':
|
'account.apiTokens.description':
|
||||||
'Esses tokens permitem que outros aplicativos controlem toda a sua conta e typebots. Tenha cuidado!',
|
'Estes tokens permitem que outras aplicações controlem toda a sua conta e typebots. Tenha cuidado!',
|
||||||
'account.apiTokens.createButton.label': 'Criar',
|
'account.apiTokens.createButton.label': 'Criar',
|
||||||
'account.apiTokens.deleteButton.label': 'Excluir',
|
'account.apiTokens.deleteButton.label': 'Excluir',
|
||||||
'account.apiTokens.table.nameHeader': 'Nome',
|
'account.apiTokens.table.nameHeader': 'Nome',
|
||||||
'account.apiTokens.table.createdHeader': 'Criado',
|
'account.apiTokens.table.createdHeader': 'Criado',
|
||||||
'account.apiTokens.deleteConfirmationMessage':
|
'account.apiTokens.deleteConfirmationMessage':
|
||||||
'O token {tokenName} será revogado permanentemente. Tem certeza de que deseja continuar?',
|
'O token {tokenName} será revogado permanentemente. Tem a certeza de que deseja continuar?',
|
||||||
'account.apiTokens.createModal.createHeading': 'Criar Token',
|
'account.apiTokens.createModal.createHeading': 'Criar Token',
|
||||||
'account.apiTokens.createModal.createdHeading': 'Token Criado',
|
'account.apiTokens.createModal.createdHeading': 'Token Criado',
|
||||||
'account.apiTokens.createModal.nameInput.label':
|
'account.apiTokens.createModal.nameInput.label':
|
||||||
'Insira um nome único para o seu token para diferenciá-lo de outros tokens.',
|
'Insira um nome único para o seu token para o diferenciar de outros tokens.',
|
||||||
'account.apiTokens.createModal.nameInput.placeholder':
|
'account.apiTokens.createModal.nameInput.placeholder':
|
||||||
'Ex. Zapier, Github, Make.com',
|
'Ex. Zapier, Github, Make.com',
|
||||||
'account.apiTokens.createModal.createButton.label': 'Criar token',
|
'account.apiTokens.createModal.createButton.label': 'Criar token',
|
||||||
'account.apiTokens.createModal.doneButton.label': 'Concluído',
|
'account.apiTokens.createModal.doneButton.label': 'Concluído',
|
||||||
'account.apiTokens.createModal.copyInstruction':
|
'account.apiTokens.createModal.copyInstruction':
|
||||||
'Por favor, copie seu token e guarde-o em um lugar seguro.',
|
'Por favor, copie o seu token e guarde-o num lugar seguro.',
|
||||||
'account.apiTokens.createModal.securityWarning':
|
'account.apiTokens.createModal.securityWarning':
|
||||||
'Por motivos de segurança, não podemos mostrá-lo novamente.',
|
'Por razões de segurança, não o podemos mostrar novamente.',
|
||||||
'account.preferences.language.heading': 'Idioma',
|
'account.preferences.language.heading': 'Idioma',
|
||||||
'account.preferences.language.tooltip':
|
'account.preferences.language.tooltip':
|
||||||
'As traduções ainda não estão completas. É um trabalho em andamento. 🤓',
|
'As traduções ainda não estão completas. É um trabalho em curso. 🤓',
|
||||||
'account.preferences.graphNavigation.heading': 'Navegação do Editor',
|
'account.preferences.graphNavigation.heading': 'Navegação do Editor',
|
||||||
'account.preferences.graphNavigation.mouse.label': 'Mouse',
|
'account.preferences.graphNavigation.mouse.label': 'Rato',
|
||||||
'account.preferences.graphNavigation.mouse.description':
|
'account.preferences.graphNavigation.mouse.description':
|
||||||
'Mova arrastando o quadro e amplie/reduza usando a roda de rolagem',
|
'Mova arrastando o quadro e amplie/reduza usando a roda de deslocamento',
|
||||||
'account.preferences.graphNavigation.trackpad.label': 'Trackpad',
|
'account.preferences.graphNavigation.trackpad.label': 'Trackpad',
|
||||||
'account.preferences.graphNavigation.trackpad.description':
|
'account.preferences.graphNavigation.trackpad.description':
|
||||||
'Mova o quadro usando 2 dedos e amplie/reduza fazendo pinça',
|
'Mova o quadro usando 2 dedos e amplie/reduza fazendo pinça',
|
||||||
@ -67,7 +67,7 @@ export default defineLocale({
|
|||||||
'account.myAccount.changePhotoButton.specification':
|
'account.myAccount.changePhotoButton.specification':
|
||||||
'.jpg ou.png, máximo 1MB',
|
'.jpg ou.png, máximo 1MB',
|
||||||
'account.myAccount.emailInput.disabledTooltip':
|
'account.myAccount.emailInput.disabledTooltip':
|
||||||
'A atualização do e-mail não está disponível. Entre em contato com o suporte se quiser alterá-lo.',
|
'A atualização do e-mail não está disponível. Entre em contacto com o apoio se quiser alterá-lo.',
|
||||||
'account.myAccount.emailInput.label': 'Endereço de e-mail:',
|
'account.myAccount.emailInput.label': 'Endereço de e-mail:',
|
||||||
'account.myAccount.nameInput.label': 'Nome:',
|
'account.myAccount.nameInput.label': 'Nome:',
|
||||||
'analytics.viewsLabel': 'Visualizações',
|
'analytics.viewsLabel': 'Visualizações',
|
||||||
@ -76,120 +76,251 @@ export default defineLocale({
|
|||||||
'analytics.completionRateLabel': 'Taxa de conclusão',
|
'analytics.completionRateLabel': 'Taxa de conclusão',
|
||||||
'auth.signin.heading': 'Entrar',
|
'auth.signin.heading': 'Entrar',
|
||||||
'auth.signin.noAccountLabel.preLink': 'Não tem uma conta?',
|
'auth.signin.noAccountLabel.preLink': 'Não tem uma conta?',
|
||||||
'auth.signin.noAccountLabel.link': 'Registre-se gratuitamente',
|
'auth.signin.noAccountLabel.link': 'Registe-se gratuitamente',
|
||||||
'auth.register.heading': 'Criar uma conta',
|
'auth.register.heading': 'Criar uma conta',
|
||||||
'auth.register.alreadyHaveAccountLabel.preLink': 'Já tem uma conta?',
|
'auth.register.alreadyHaveAccountLabel.preLink': 'Já tem uma conta?',
|
||||||
'auth.register.alreadyHaveAccountLabel.link': 'Entrar',
|
'auth.register.alreadyHaveAccountLabel.link': 'Entrar',
|
||||||
'auth.register.aggreeToTerms':
|
'auth.register.aggreeToTerms':
|
||||||
'Ao se cadastrar, você concorda com nossos {termsOfService} e {privacyPolicy}.',
|
'Ao registar-se, concorda com os nossos {termsOfService} e {privacyPolicy}.',
|
||||||
'auth.register.termsOfService': 'termos de serviço',
|
'auth.register.termsOfService': 'termos de serviço',
|
||||||
'auth.register.privacyPolicy': 'política de privacidade',
|
'auth.register.privacyPolicy': 'política de privacidade',
|
||||||
'auth.error.default': 'Tente entrar com uma conta diferente.',
|
'auth.error.default': 'Tente entrar com uma conta diferente.',
|
||||||
'auth.error.email':
|
'auth.error.email':
|
||||||
'E-mail não encontrado. Tente entrar com um provedor diferente.',
|
'E-mail não encontrado. Tente entrar com um fornecedor diferente.',
|
||||||
'auth.error.oauthNotLinked':
|
'auth.error.oauthNotLinked':
|
||||||
'Para confirmar sua identidade, entre com a mesma conta que você usou originalmente.',
|
'Para confirmar a sua identidade, entre com a mesma conta que usou originalmente.',
|
||||||
'auth.error.unknown': 'Ocorreu um erro. Tente novamente.',
|
'auth.error.unknown': 'Ocorreu um erro. Tente novamente.',
|
||||||
'auth.signinErrorToast.title': 'Não autorizado',
|
'auth.signinErrorToast.title': 'Não autorizado',
|
||||||
'auth.signinErrorToast.description': 'As inscrições estão desativadas.',
|
'auth.signinErrorToast.description': 'As inscrições estão desativadas.',
|
||||||
'auth.signinErrorToast.tooManyRequests':
|
'auth.signinErrorToast.tooManyRequests':
|
||||||
'Muitas tentativas. Tente novamente mais tarde.',
|
'Muitas tentativas. Tente novamente mais tarde.',
|
||||||
'auth.noProvider.preLink': 'Você precisa',
|
'auth.noProvider.preLink': 'Precisa de',
|
||||||
'auth.noProvider.link':
|
'auth.noProvider.link':
|
||||||
'configurar pelo menos um provedor de autenticação (E-mail, Google, GitHub, Facebook ou Azure AD).',
|
'configurar pelo menos um fornecedor de autenticação (E-mail, Google, GitHub, Facebook ou Azure AD).',
|
||||||
'auth.orEmailLabel': 'Ou com seu email',
|
'auth.orEmailLabel': 'Ou com o seu e-mail',
|
||||||
'auth.emailSubmitButton.label': 'Enviar',
|
'auth.emailSubmitButton.label': 'Enviar',
|
||||||
'auth.magicLink.title': 'Um email com o link mágico foi enviado. 🪄',
|
'auth.magicLink.title': 'Foi enviado um e-mail com a ligação mágica. 🪄',
|
||||||
'auth.magicLink.description': 'Certifique-se de verificar sua pasta de spam.',
|
'auth.magicLink.description':
|
||||||
|
'Certifique-se de verificar a sua pasta de spam.',
|
||||||
'auth.socialLogin.githubButton.label': 'Continuar com GitHub',
|
'auth.socialLogin.githubButton.label': 'Continuar com GitHub',
|
||||||
'auth.socialLogin.googleButton.label': 'Continuar com Google',
|
'auth.socialLogin.googleButton.label': 'Continuar com Google',
|
||||||
'auth.socialLogin.facebookButton.label': 'Continuar com Facebook',
|
'auth.socialLogin.facebookButton.label': 'Continuar com Facebook',
|
||||||
'auth.socialLogin.azureButton.label': 'Continuar com {azureProviderName}',
|
'auth.socialLogin.azureButton.label': 'Continuar com {azureProviderName}',
|
||||||
'auth.socialLogin.gitlabButton.label': 'Continuar com {gitlabProviderName}',
|
'auth.socialLogin.gitlabButton.label': 'Continuar com {gitlabProviderName}',
|
||||||
'auth.socialLogin.customButton.label': 'Continuar com {customProviderName}',
|
'auth.socialLogin.customButton.label': 'Continuar com {customProviderName}',
|
||||||
'billing.billingPortalButton.label': 'Portal de cobrança',
|
'billing.billingPortalButton.label': 'Portal de facturação',
|
||||||
'billing.contribution.preLink':
|
'billing.contribution.preLink':
|
||||||
'A Typebot está contribuindo com 1% da sua assinatura para remover o CO₂ da atmosfera.',
|
'A Typebot está a contribuir com 1% da sua subscrição para remover o CO₂ da atmosfera.',
|
||||||
'billing.contribution.link': 'Saiba mais.',
|
'billing.contribution.link': 'Saiba mais.',
|
||||||
'billing.updateSuccessToast.description':
|
'billing.updateSuccessToast.description':
|
||||||
'Sua assinatura {plan} foi atualizada com sucesso 🎉',
|
'A sua subscrição {plan} foi atualizada com sucesso 🎉',
|
||||||
'billing.customLimit.preLink':
|
'billing.customLimit.preLink':
|
||||||
'Precisa de limites personalizados? Recursos específicos?',
|
'Precisa de limites personalizados? Funcionalidades específicas?',
|
||||||
'billing.customLimit.link': 'Vamos conversar!',
|
'billing.customLimit.link': 'Vamos falar!',
|
||||||
'billing.upgradeLimitLabel':
|
'billing.upgradeLimitLabel':
|
||||||
'Você precisa atualizar sua assinatura para {type}',
|
'Precisa de atualizar a sua subscrição para {type}',
|
||||||
'billing.currentSubscription.heading': 'Assinatura',
|
'billing.currentSubscription.heading': 'Subscrição',
|
||||||
'billing.currentSubscription.subheading':
|
'billing.currentSubscription.subheading':
|
||||||
'Assinatura atual do espaço de trabalho:',
|
'Subscrição actual do espaço de trabalho:',
|
||||||
'billing.invoices.heading': 'Faturas',
|
'billing.currentSubscription.cancelDate': 'Será cancelado em',
|
||||||
|
'billing.invoices.heading': 'Facturas',
|
||||||
'billing.invoices.empty':
|
'billing.invoices.empty':
|
||||||
'Nenhuma fatura encontrada para este espaço de trabalho.',
|
'Nenhuma factura encontrada para este espaço de trabalho.',
|
||||||
'billing.invoices.paidAt': 'Pago em',
|
'billing.invoices.paidAt': 'Pago em',
|
||||||
'billing.invoices.subtotal': 'Subtotal',
|
'billing.invoices.subtotal': 'Subtotal',
|
||||||
'billing.preCheckoutModal.companyInput.label': 'Nome da empresa:',
|
'billing.preCheckoutModal.companyInput.label': 'Nome da empresa:',
|
||||||
'billing.preCheckoutModal.emailInput.label': 'E-mail:',
|
'billing.preCheckoutModal.emailInput.label': 'E-mail:',
|
||||||
'billing.preCheckoutModal.taxId.label': 'Identificação fiscal (CPF):',
|
'billing.preCheckoutModal.taxId.label': 'Identificação fiscal (NIF):',
|
||||||
'billing.preCheckoutModal.taxId.placeholder': 'Tipo de ID',
|
'billing.preCheckoutModal.taxId.placeholder': 'Tipo de ID',
|
||||||
'billing.preCheckoutModal.submitButton.label':
|
'billing.preCheckoutModal.submitButton.label':
|
||||||
'Ir para a finalização da compra',
|
'Ir para a finalização da compra',
|
||||||
'billing.pricingCard.heading': 'Mudar para {plan}',
|
'billing.pricingCard.heading': 'Mudar para {plan}',
|
||||||
'billing.pricingCard.perMonth': '/ mês',
|
'billing.pricingCard.perMonth': '/ mês',
|
||||||
'billing.pricingCard.plus': ', mais:',
|
'billing.pricingCard.plus': ', mais:',
|
||||||
'billing.pricingCard.upgradeButton.current': 'Sua assinatura atual',
|
'billing.pricingCard.upgradeButton.current': 'A sua subscrição atual',
|
||||||
'billing.pricingCard.chatsPerMonth': 'chats/mês',
|
'billing.pricingCard.chatsPerMonth': 'chats/mês',
|
||||||
'billing.pricingCard.chatsTooltip':
|
'billing.pricingCard.chatsTooltip':
|
||||||
'Um chat é contado sempre que um usuário inicia uma discussão. Ele é independente do número de mensagens que ele envia e recebe.',
|
'Um chat é contado sempre que um utilizador inicia uma discussão. Ele é independente do número de mensagens que envia e recebe.',
|
||||||
'billing.pricingCard.storageLimit': 'GB de armazenamento',
|
'billing.pricingCard.storageLimit': 'GB de armazenamento',
|
||||||
'billing.pricingCard.storageLimitTooltip':
|
'billing.pricingCard.storageLimitTooltip':
|
||||||
'Você acumula armazenamento para cada arquivo que seu usuário carrega em seu bot. Se você excluir o resultado, ele liberará espaço.',
|
'Acumula armazenamento para cada ficheiro que o seu utilizador carrega no seu bot. Se excluir o resultado, ele libertará espaço.',
|
||||||
'billing.pricingCard.starter.description':
|
'billing.pricingCard.starter.description':
|
||||||
'Para indivíduos e pequenas empresas.',
|
'Para indivíduos e pequenas empresas.',
|
||||||
'billing.pricingCard.starter.includedSeats': '2 assentos incluídos',
|
'billing.pricingCard.starter.includedSeats': '2 lugares incluídos',
|
||||||
'billing.pricingCard.starter.brandingRemoved': 'Marca removida',
|
'billing.pricingCard.starter.brandingRemoved': 'Marca removida',
|
||||||
'billing.pricingCard.starter.fileUploadBlock': 'Bloco de envio de arquivo',
|
'billing.pricingCard.starter.fileUploadBlock': 'Bloco de envio de ficheiro',
|
||||||
'billing.pricingCard.starter.createFolders': 'Criar pastas',
|
'billing.pricingCard.starter.createFolders': 'Criar pastas',
|
||||||
'billing.pricingCard.pro.mostPopularLabel': 'Mais popular',
|
'billing.pricingCard.pro.mostPopularLabel': 'Mais popular',
|
||||||
'billing.pricingCard.pro.description':
|
'billing.pricingCard.pro.description':
|
||||||
'Para agências e startups em crescimento.',
|
'Para agências e startups em crescimento.',
|
||||||
'billing.pricingCard.pro.everythingFromStarter': 'Tudo em Starter',
|
'billing.pricingCard.pro.everythingFromStarter': 'Tudo em Starter',
|
||||||
'billing.pricingCard.pro.includedSeats': '5 assentos incluídos',
|
'billing.pricingCard.pro.includedSeats': '5 lugares incluídos',
|
||||||
'billing.pricingCard.pro.customDomains': 'Domínios personalizados',
|
'billing.pricingCard.pro.customDomains': 'Domínios personalizados',
|
||||||
'billing.pricingCard.pro.analytics': 'Análises aprofundadas',
|
'billing.pricingCard.pro.analytics': 'Análises aprofundadas',
|
||||||
'billing.usage.heading': 'Uso',
|
'billing.usage.heading': 'Uso',
|
||||||
|
'billing.usage.unlimited': 'Ilimitado',
|
||||||
'billing.usage.chats.heading': 'Chats',
|
'billing.usage.chats.heading': 'Chats',
|
||||||
'billing.usage.chats.alert.soonReach':
|
'billing.usage.chats.alert.soonReach':
|
||||||
'Seus typebots são populares! Você logo alcançará o limite de chats de seu plano. 🚀',
|
'Os seus typebots são populares! Vai alcançar em breve o limite de chats do seu plano. 🚀',
|
||||||
'billing.usage.chats.alert.updatePlan':
|
'billing.usage.chats.alert.updatePlan':
|
||||||
'Certifique-se de atualizar seu plano para aumentar esse limite e continuar conversando com seus usuários.',
|
'Certifique-se de atualizar o seu plano para aumentar esse limite e continuar a conversar com os seus utilizadores.',
|
||||||
'billing.usage.chats.resetInfo': '(reiniciado todo dia 1)',
|
'billing.usage.chats.resetInfo': '(reiniciado a cada dia 1)',
|
||||||
'billing.usage.storage.heading': 'Armazenamento',
|
'billing.usage.storage.heading': 'Armazenamento',
|
||||||
'billing.usage.storage.alert.soonReach':
|
'billing.usage.storage.alert.soonReach':
|
||||||
'Seus typebots são populares! Você logo alcançará o limite de armazenamento de seu plano. 🚀',
|
'Os seus typebots são populares! Vai alcançar em breve o limite de armazenamento do seu plano. 🚀',
|
||||||
'billing.usage.storage.alert.updatePlan':
|
'billing.usage.storage.alert.updatePlan':
|
||||||
'Certifique-se de atualizar seu plano para continuar coletando arquivos enviados. Você também pode excluir arquivos para liberar espaço.',
|
'Certifique-se de atualizar o seu plano para continuar a recolher ficheiros enviados. Também pode excluir ficheiros para libertar espaço.',
|
||||||
'billing.limitMessage.brand': 'remover a marca',
|
'billing.limitMessage.brand': 'remover a marca',
|
||||||
'billing.limitMessage.customDomain': 'adicionar domínios personalizados',
|
'billing.limitMessage.customDomain': 'adicionar domínios personalizados',
|
||||||
'billing.limitMessage.analytics': 'desbloquear análises aprofundadas',
|
'billing.limitMessage.analytics': 'desbloquear análises aprofundadas',
|
||||||
'billing.limitMessage.fileInput': 'usar blocos de envio de arquivo',
|
'billing.limitMessage.fileInput': 'usar blocos de envio de ficheiros',
|
||||||
'billing.limitMessage.folder': 'criar pastas',
|
'billing.limitMessage.folder': 'criar pastas',
|
||||||
'billing.upgradeAlert.buttonDefaultLabel': 'Mais informações',
|
'billing.upgradeAlert.buttonDefaultLabel': 'Mais informações',
|
||||||
'workspace.membersList.inviteInput.placeholder': 'colega@empresa.com',
|
'workspace.membersList.inviteInput.placeholder': 'colega@empresa.com',
|
||||||
'workspace.membersList.inviteButton.label': 'Convidar',
|
'workspace.membersList.inviteButton.label': 'Convidar',
|
||||||
'workspace.membersList.unlockBanner.label':
|
'workspace.membersList.unlockBanner.label':
|
||||||
'Atualize seu plano para trabalhar com mais membros da equipe e desbloqueie recursos incríveis 🚀',
|
'Atualize o seu plano para trabalhar com mais membros da equipa e desbloquear funcionalidades incríveis 🚀',
|
||||||
'workspace.membersList.title': 'Membros',
|
'workspace.membersList.title': 'Membros',
|
||||||
'workspace.settings.icon.title': 'Ícone',
|
'workspace.settings.icon.title': 'Ícone',
|
||||||
'workspace.settings.name.label': 'Nome:',
|
'workspace.settings.name.label': 'Nome:',
|
||||||
'workspace.settings.deleteButton.label': 'Excluir espaço de trabalho',
|
'workspace.settings.deleteButton.label': 'Eliminar espaço de trabalho',
|
||||||
'workspace.settings.deleteButton.confirmMessage':
|
'workspace.settings.deleteButton.confirmMessage':
|
||||||
'Você tem certeza de que deseja excluir o espaço de trabalho {workspaceName}? Todas as suas pastas, typebots e resultados serão excluídos permanentemente.',
|
'Tem a certeza de que deseja eliminar o espaço de trabalho {workspaceName}? Todas as suas pastas, typebots e resultados serão excluídos permanentemente.',
|
||||||
'workspace.settings.modal.menu.myAccount.label': 'Minha conta',
|
'workspace.settings.modal.menu.myAccount.label': 'A minha conta',
|
||||||
'workspace.settings.modal.menu.preferences.label': 'Preferências',
|
'workspace.settings.modal.menu.preferences.label': 'Preferências',
|
||||||
'workspace.settings.modal.menu.workspace.label': 'Espaço de trabalho',
|
'workspace.settings.modal.menu.workspace.label': 'Espaço de trabalho',
|
||||||
'workspace.settings.modal.menu.settings.label': 'Configurações',
|
'workspace.settings.modal.menu.settings.label': 'Configurações',
|
||||||
'workspace.settings.modal.menu.members.label': 'Membros',
|
'workspace.settings.modal.menu.members.label': 'Membros',
|
||||||
'workspace.settings.modal.menu.billingAndUsage.label': 'Faturamento e uso',
|
'workspace.settings.modal.menu.billingAndUsage.label': 'Faturação e uso',
|
||||||
'workspace.settings.modal.menu.version.label': 'Versão: {version}',
|
'workspace.settings.modal.menu.version.label': 'Versão: {version}',
|
||||||
'workspace.dropdown.newButton.label': 'Novo espaço de trabalho',
|
'workspace.dropdown.newButton.label': 'Novo espaço de trabalho',
|
||||||
'workspace.dropdown.logoutButton.label': 'Sair',
|
'workspace.dropdown.logoutButton.label': 'Sair',
|
||||||
|
'templates.buttons.heading': 'Criar um novo typebot',
|
||||||
|
'templates.buttons.fromScratchButton.label': 'Comece do zero',
|
||||||
|
'templates.buttons.fromTemplateButton.label': 'Comece a partir de um modelo',
|
||||||
|
'templates.buttons.importFileButton.label': 'Importar um ficheiro',
|
||||||
|
'templates.modal.menuHeading.marketing': 'Marketing',
|
||||||
|
'templates.modal.menuHeading.product': 'Produto',
|
||||||
|
'templates.modal.menuHeading.other': 'Outros',
|
||||||
|
'templates.modal.menuHeading.new.tag': 'Novo',
|
||||||
|
'templates.modal.useTemplateButton.label': 'Usar este modelo',
|
||||||
|
'templates.importFromFileButon.toastError.description':
|
||||||
|
'Falha ao analisar o ficheiro. Tem certeza de que é um typebot?',
|
||||||
|
'editor.headers.flowButton.label': 'Fluxo',
|
||||||
|
'editor.headers.themeButton.label': 'Tema',
|
||||||
|
'editor.headers.settingsButton.label': 'Configurações',
|
||||||
|
'editor.headers.shareButton.label': 'Compartilhar',
|
||||||
|
'editor.headers.resultsButton.label': 'Resultados',
|
||||||
|
'editor.headers.helpButton.label': 'Ajuda',
|
||||||
|
'editor.headers.savingSpinner.label': 'Salvando...',
|
||||||
|
'editor.headers.previewButton.label': 'Visualizar',
|
||||||
|
'editor.sidebarBlocks.sidebar.lock.label': 'Bloquear barra lateral',
|
||||||
|
'editor.sidebarBlocks.sidebar.unlock.label': 'Desbloquear barra lateral',
|
||||||
|
'editor.sidebarBlocks.sidebar.icon.lock.label': 'Bloquear',
|
||||||
|
'editor.sidebarBlocks.sidebar.icon.unlock.label': 'Desbloquear',
|
||||||
|
'editor.sidebarBlocks.blockType.bubbles.heading': 'Bubbles',
|
||||||
|
'editor.sidebarBlocks.blockType.inputs.heading': 'Inputs',
|
||||||
|
'editor.sidebarBlocks.blockType.logic.heading': 'Condicionais',
|
||||||
|
'editor.sidebarBlocks.blockType.integrations.heading': 'Integrações',
|
||||||
|
'editor.sidebarBlock.start.label': 'Início',
|
||||||
|
'editor.sidebarBlock.text.label': 'Texto',
|
||||||
|
'editor.sidebarBlock.image.label': 'Imagem',
|
||||||
|
'editor.sidebarBlock.video.label': 'Vídeo',
|
||||||
|
'editor.sidebarBlock.embed.label': 'Incorporar',
|
||||||
|
'editor.sidebarBlock.audio.label': 'Áudio',
|
||||||
|
'editor.sidebarBlock.number.label': 'Número',
|
||||||
|
'editor.sidebarBlock.email.label': 'Email',
|
||||||
|
'editor.sidebarBlock.website.label': 'Website',
|
||||||
|
'editor.sidebarBlock.date.label': 'Data',
|
||||||
|
'editor.sidebarBlock.phone.label': 'Telefone',
|
||||||
|
'editor.sidebarBlock.button.label': 'Botão',
|
||||||
|
'editor.sidebarBlock.picChoice.label': 'Seleção de Imagem',
|
||||||
|
'editor.sidebarBlock.payment.label': 'Pagamento',
|
||||||
|
'editor.sidebarBlock.rating.label': 'Classificação',
|
||||||
|
'editor.sidebarBlock.file.label': 'Ficheiro',
|
||||||
|
'editor.sidebarBlock.setVariable.label': 'Variável',
|
||||||
|
'editor.sidebarBlock.condition.label': 'Condição',
|
||||||
|
'editor.sidebarBlock.redirect.label': 'Redirecionar',
|
||||||
|
'editor.sidebarBlock.script.label': 'Script',
|
||||||
|
'editor.sidebarBlock.typebot.label': 'Typebot',
|
||||||
|
'editor.sidebarBlock.wait.label': 'Espera',
|
||||||
|
'editor.sidebarBlock.jump.label': 'Saltar',
|
||||||
|
'editor.sidebarBlock.abTest.label': 'Teste AB',
|
||||||
|
'editor.sidebarBlock.sheets.label': 'Sheets',
|
||||||
|
'editor.sidebarBlock.analytics.label': 'Analytics',
|
||||||
|
'editor.sidebarBlock.webhook.label': 'Webhook',
|
||||||
|
'editor.sidebarBlock.zapier.label': 'Zapier',
|
||||||
|
'editor.sidebarBlock.makecom.label': 'Make.com',
|
||||||
|
'editor.sidebarBlock.pabbly.label': 'Pabbly',
|
||||||
|
'editor.sidebarBlock.chatwoot.label': 'Chatwoot',
|
||||||
|
'editor.sidebarBlock.openai.label': 'OpenAI',
|
||||||
|
'editor.sidebarBlock.pixel.label': 'Pixel',
|
||||||
|
'editor.blockCard.bubbleBlock.tooltip.label':
|
||||||
|
'Incorporar pdf, iframe, website...',
|
||||||
|
'editor.blockCard.inputBlock.tooltip.files.label': 'Carregar Ficheiros',
|
||||||
|
'editor.blockCard.logicBlock.tooltip.code.label':
|
||||||
|
'Executar código Javascript',
|
||||||
|
'editor.blockCard.logicBlock.tooltip.typebotLink.label':
|
||||||
|
'Link e salte para outro typebot',
|
||||||
|
'editor.blockCard.logicBlock.tooltip.jump.label':
|
||||||
|
'Encaminhar fluxo para outro grupo',
|
||||||
|
'editor.blockCard.integrationBlock.tooltip.googleSheets.label':
|
||||||
|
'Google Sheets',
|
||||||
|
'editor.blockCard.integrationBlock.tooltip.googleAnalytics.label':
|
||||||
|
'Google Analytics',
|
||||||
|
'editor.editableTypebotName.tooltip.rename.label': 'Renomear',
|
||||||
|
'editor.gettingStartedModal.editorBasics.heading': 'Noções básicas de editor',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.one.label':
|
||||||
|
'A barra lateral esquerda contém blocos que pode arrastar e largar no quadro.',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.two.label':
|
||||||
|
'Pode agrupar blocos juntos, colocando-os uns abaixo ou acima dos outros',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.three.label':
|
||||||
|
'Ligue os grupos entre si',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.four.label':
|
||||||
|
'Pré-visualize o seu bot ao clicar no botão de visualizar no canto superior direito',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.label':
|
||||||
|
'Sinta-se à vontade para usar o chat no canto inferior direito para entrar em contacto se tiver alguma questão. Normalmente, respondo nas próximas 24 horas. 😃',
|
||||||
|
'editor.gettingStartedModal.seeAction.label': 'Veja o funcionamento em',
|
||||||
|
'editor.gettingStartedModal.seeAction.time': '5 minutos',
|
||||||
|
'editor.gettingStartedModal.seeAction.item.label': 'Outros vídeos',
|
||||||
|
'editor.provider.messages.getTypebotError.title':
|
||||||
|
'Erro ao obter o typebot. Atualize a página.',
|
||||||
|
'editor.provider.messages.getTypebotError.description':
|
||||||
|
'Não foi possível encontrar o typebot',
|
||||||
|
'editor.provider.messages.publishedTypebotError.title':
|
||||||
|
'Erro ao obter o typebot publicado',
|
||||||
|
'editor.provider.messages.updateTypebotError.title':
|
||||||
|
'Erro ao atualizar o typebot',
|
||||||
|
'editor.provider.groups.copy.title': 'Cópia',
|
||||||
|
'editor.blocks.start.text': 'Começar',
|
||||||
|
'editor.blocks.bubbles.audio.settings.upload.label': 'Carregar',
|
||||||
|
'editor.blocks.bubbles.audio.settings.embedLink.label': 'Incorporar link',
|
||||||
|
'editor.blocks.bubbles.audio.settings.chooseFile.label':
|
||||||
|
'Escolher um ficheiro',
|
||||||
|
'editor.blocks.bubbles.audio.settings.worksWith.text':
|
||||||
|
'Compatível com .MP3s e .WAVs',
|
||||||
|
'editor.blocks.bubbles.audio.settings.worksWith.placeholder':
|
||||||
|
'Colar o link do ficheiro de áudio...',
|
||||||
|
'editor.blocks.bubbles.audio.settings.autoplay.label':
|
||||||
|
'Ativar reprodução automática',
|
||||||
|
'editor.blocks.bubbles.audio.node.clickToEdit.text': 'Clique para editar...',
|
||||||
|
'editor.blocks.bubbles.embed.node.clickToEdit.text': 'Clique para editar...',
|
||||||
|
'editor.blocks.bubbles.embed.node.show.text': 'Mostrar incorporação',
|
||||||
|
'editor.blocks.bubbles.embed.settings.worksWith.placeholder':
|
||||||
|
'Colar o link ou código...',
|
||||||
|
'editor.blocks.bubbles.embed.settings.worksWith.text':
|
||||||
|
'Compatível com PDFs, iframes, websites...',
|
||||||
|
'editor.blocks.bubbles.embed.settings.numberInput.unit': 'px',
|
||||||
|
'editor.blocks.bubbles.image.node.clickToEdit.text': 'Clique para editar...',
|
||||||
|
'editor.blocks.bubbles.image.switchWithLabel.onClick.label': 'Link ao clicar',
|
||||||
|
'editor.blocks.bubbles.image.switchWithLabel.onClick.placeholder':
|
||||||
|
'Texto alternativo do link (descrição)',
|
||||||
|
'editor.blocks.bubbles.video.node.clickToEdit.text': 'Clique para editar...',
|
||||||
|
'editor.blocks.bubbles.video.settings.worksWith.text':
|
||||||
|
'Compatível com Youtube, Vimeo e outros',
|
||||||
|
'editor.blocks.bubbles.video.settings.worksWith.placeholder':
|
||||||
|
'Colar o link do vídeo...',
|
||||||
|
'editor.blocks.bubbles.textEditor.plate.label': 'Editor de texto',
|
||||||
|
'editor.blocks.bubbles.textEditor.searchVariable.placeholder':
|
||||||
|
'Pesquisar uma variável',
|
||||||
})
|
})
|
||||||
|
323
apps/builder/src/locales/pt_BR.ts
Normal file
323
apps/builder/src/locales/pt_BR.ts
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
export default {
|
||||||
|
back: 'Voltar',
|
||||||
|
'confirmModal.defaultTitle': 'Tem certeza?',
|
||||||
|
'dashboard.header.settingsButton.label': 'Configurações & Membros',
|
||||||
|
'dashboard.redirectionMessage': 'Você está sendo redirecionado...',
|
||||||
|
'dashboard.title': 'Meus typebots',
|
||||||
|
delete: 'Apagar',
|
||||||
|
errorMessage: 'Ocorreu um erro',
|
||||||
|
cancel: 'Cancelar',
|
||||||
|
update: 'Atualizar',
|
||||||
|
upgrade: 'Upgrade',
|
||||||
|
downgrade: 'Downgrade',
|
||||||
|
remove: 'Remover',
|
||||||
|
pending: 'Pendente',
|
||||||
|
skip: 'Pular',
|
||||||
|
'folders.createFolderButton.label': 'Criar uma pasta',
|
||||||
|
'folders.createTypebotButton.label': 'Criar um typebot',
|
||||||
|
'folders.folderButton.deleteConfirmationMessage':
|
||||||
|
'Tem certeza de que deseja excluir a pasta {folderName}? (Tudo o que estiver dentro será movido para o seu painel)',
|
||||||
|
'folders.typebotButton.live': 'Live',
|
||||||
|
'folders.typebotButton.showMoreOptions': 'Mostrar mais opções',
|
||||||
|
'folders.typebotButton.unpublish': 'Despublicar',
|
||||||
|
'folders.typebotButton.duplicate': 'Duplicar',
|
||||||
|
'folders.typebotButton.delete': 'Apagar',
|
||||||
|
'folders.typebotButton.deleteConfirmationMessage':
|
||||||
|
'Tem certeza de que deseja excluir seu typebot {typebotName}?',
|
||||||
|
'folders.typebotButton.deleteConfirmationMessageWarning':
|
||||||
|
'Todos os dados associados serão excluídos e não poderão ser recuperados.',
|
||||||
|
'account.apiTokens.heading': 'Tokens de API',
|
||||||
|
'account.apiTokens.description':
|
||||||
|
'Esses tokens permitem que outros aplicativos controlem toda a sua conta e typebots. Tenha cuidado!',
|
||||||
|
'account.apiTokens.createButton.label': 'Criar',
|
||||||
|
'account.apiTokens.deleteButton.label': 'Excluir',
|
||||||
|
'account.apiTokens.table.nameHeader': 'Nome',
|
||||||
|
'account.apiTokens.table.createdHeader': 'Criado',
|
||||||
|
'account.apiTokens.deleteConfirmationMessage':
|
||||||
|
'O token {tokenName} será revogado permanentemente. Tem certeza de que deseja continuar?',
|
||||||
|
'account.apiTokens.createModal.createHeading': 'Criar Token',
|
||||||
|
'account.apiTokens.createModal.createdHeading': 'Token Criado',
|
||||||
|
'account.apiTokens.createModal.nameInput.label':
|
||||||
|
'Insira um nome único para o seu token para diferenciá-lo de outros tokens.',
|
||||||
|
'account.apiTokens.createModal.nameInput.placeholder':
|
||||||
|
'Ex. Zapier, Github, Make.com',
|
||||||
|
'account.apiTokens.createModal.createButton.label': 'Criar token',
|
||||||
|
'account.apiTokens.createModal.doneButton.label': 'Concluído',
|
||||||
|
'account.apiTokens.createModal.copyInstruction':
|
||||||
|
'Por favor, copie seu token e guarde-o em um lugar seguro.',
|
||||||
|
'account.apiTokens.createModal.securityWarning':
|
||||||
|
'Por motivos de segurança, não podemos mostrá-lo novamente.',
|
||||||
|
'account.preferences.language.heading': 'Idioma',
|
||||||
|
'account.preferences.language.tooltip':
|
||||||
|
'As traduções ainda não estão completas. É um trabalho em andamento. 🤓',
|
||||||
|
'account.preferences.graphNavigation.heading': 'Navegação do Editor',
|
||||||
|
'account.preferences.graphNavigation.mouse.label': 'Mouse',
|
||||||
|
'account.preferences.graphNavigation.mouse.description':
|
||||||
|
'Mova arrastando o quadro e amplie/reduza usando a roda de rolagem',
|
||||||
|
'account.preferences.graphNavigation.trackpad.label': 'Trackpad',
|
||||||
|
'account.preferences.graphNavigation.trackpad.description':
|
||||||
|
'Mova o quadro usando 2 dedos e amplie/reduza fazendo pinça',
|
||||||
|
'account.preferences.appearance.heading': 'Aparência',
|
||||||
|
'account.preferences.appearance.systemLabel': 'Sistema',
|
||||||
|
'account.preferences.appearance.lightLabel': 'Claro',
|
||||||
|
'account.preferences.appearance.darkLabel': 'Escuro',
|
||||||
|
'account.myAccount.changePhotoButton.label': 'Alterar foto',
|
||||||
|
'account.myAccount.changePhotoButton.specification':
|
||||||
|
'.jpg ou.png, máximo 1MB',
|
||||||
|
'account.myAccount.emailInput.disabledTooltip':
|
||||||
|
'A atualização do e-mail não está disponível. Entre em contato com o suporte se quiser alterá-lo.',
|
||||||
|
'account.myAccount.emailInput.label': 'Endereço de e-mail:',
|
||||||
|
'account.myAccount.nameInput.label': 'Nome:',
|
||||||
|
'analytics.viewsLabel': 'Visualizações',
|
||||||
|
'analytics.startsLabel': 'Inícios',
|
||||||
|
'analytics.completionRateLabel': 'Taxa de conclusão',
|
||||||
|
'analytics.notAvailableLabel': 'Não disponível',
|
||||||
|
'auth.signin.heading': 'Entrar',
|
||||||
|
'auth.signin.noAccountLabel.preLink': 'Não tem uma conta?',
|
||||||
|
'auth.signin.noAccountLabel.link': 'Registre-se gratuitamente',
|
||||||
|
'auth.register.heading': 'Criar uma conta',
|
||||||
|
'auth.register.alreadyHaveAccountLabel.preLink': 'Já tem uma conta?',
|
||||||
|
'auth.register.alreadyHaveAccountLabel.link': 'Entrar',
|
||||||
|
'auth.register.aggreeToTerms':
|
||||||
|
'Ao se cadastrar, você concorda com nossos {termsOfService} e {privacyPolicy}.',
|
||||||
|
'auth.register.termsOfService': 'termos de serviço',
|
||||||
|
'auth.register.privacyPolicy': 'política de privacidade',
|
||||||
|
'auth.error.default': 'Tente entrar com uma conta diferente.',
|
||||||
|
'auth.error.email':
|
||||||
|
'E-mail não encontrado. Tente entrar com um provedor diferente.',
|
||||||
|
'auth.error.oauthNotLinked':
|
||||||
|
'Já existe uma conta vinculada a esse E-mail, entre com a mesma conta que você usou originalmente.',
|
||||||
|
'auth.error.unknown': 'Ocorreu um erro. Tente novamente.',
|
||||||
|
'auth.signinErrorToast.title': 'Não autorizado',
|
||||||
|
'auth.signinErrorToast.description': 'As inscrições estão desativadas.',
|
||||||
|
'auth.signinErrorToast.tooManyRequests':
|
||||||
|
'Muitas tentativas. Tente novamente mais tarde.',
|
||||||
|
'auth.noProvider.preLink': 'Você precisa',
|
||||||
|
'auth.noProvider.link':
|
||||||
|
'configurar pelo menos um provedor de autenticação (E-mail, Google, GitHub, Facebook ou Azure AD).',
|
||||||
|
'auth.orEmailLabel': 'Ou com seu email',
|
||||||
|
'auth.emailSubmitButton.label': 'Enviar',
|
||||||
|
'auth.magicLink.title': 'Um email com o link mágico foi enviado. 🪄',
|
||||||
|
'auth.magicLink.description': 'Certifique-se de verificar sua pasta de spam.',
|
||||||
|
'auth.socialLogin.githubButton.label': 'Continuar com GitHub',
|
||||||
|
'auth.socialLogin.googleButton.label': 'Continuar com Google',
|
||||||
|
'auth.socialLogin.facebookButton.label': 'Continuar com Facebook',
|
||||||
|
'auth.socialLogin.azureButton.label': 'Continuar com {azureProviderName}',
|
||||||
|
'auth.socialLogin.gitlabButton.label': 'Continuar com {gitlabProviderName}',
|
||||||
|
'auth.socialLogin.customButton.label': 'Continuar com {customProviderName}',
|
||||||
|
'billing.billingPortalButton.label': 'Portal de cobrança',
|
||||||
|
'billing.contribution.preLink':
|
||||||
|
'A Typebot está contribuindo com 1% da sua assinatura para remover o CO₂ da atmosfera.',
|
||||||
|
'billing.contribution.link': 'Saiba mais.',
|
||||||
|
'billing.updateSuccessToast.description':
|
||||||
|
'Sua assinatura {plan} foi atualizada com sucesso 🎉',
|
||||||
|
'billing.customLimit.preLink':
|
||||||
|
'Precisa de limites personalizados? Recursos específicos?',
|
||||||
|
'billing.customLimit.link': 'Vamos conversar!',
|
||||||
|
'billing.upgradeLimitLabel':
|
||||||
|
'Você precisa atualizar sua assinatura para {type}',
|
||||||
|
'billing.currentSubscription.heading': 'Assinatura',
|
||||||
|
'billing.currentSubscription.subheading':
|
||||||
|
'Assinatura atual do espaço de trabalho:',
|
||||||
|
'billing.currentSubscription.cancelDate': 'Será cancelado em',
|
||||||
|
'billing.invoices.heading': 'Faturas',
|
||||||
|
'billing.invoices.empty':
|
||||||
|
'Nenhuma fatura encontrada para este espaço de trabalho.',
|
||||||
|
'billing.invoices.paidAt': 'Pago em',
|
||||||
|
'billing.invoices.subtotal': 'Subtotal',
|
||||||
|
'billing.preCheckoutModal.companyInput.label': 'Nome da empresa:',
|
||||||
|
'billing.preCheckoutModal.emailInput.label': 'E-mail:',
|
||||||
|
'billing.preCheckoutModal.taxId.label': 'Identificação fiscal (CPF):',
|
||||||
|
'billing.preCheckoutModal.taxId.placeholder': 'Tipo de ID',
|
||||||
|
'billing.preCheckoutModal.submitButton.label':
|
||||||
|
'Ir para a finalização da compra',
|
||||||
|
'billing.pricingCard.heading': 'Mudar para {plan}',
|
||||||
|
'billing.pricingCard.perMonth': '/ mês',
|
||||||
|
'billing.pricingCard.plus': ', mais:',
|
||||||
|
'billing.pricingCard.upgradeButton.current': 'Sua assinatura atual',
|
||||||
|
'billing.pricingCard.chatsPerMonth': 'chats/mês',
|
||||||
|
'billing.pricingCard.chatsTooltip':
|
||||||
|
'Um chat é contado sempre que um usuário inicia uma discussão. Ele é independente do número de mensagens que ele envia e recebe.',
|
||||||
|
'billing.pricingCard.storageLimit': 'GB de armazenamento',
|
||||||
|
'billing.pricingCard.storageLimitTooltip':
|
||||||
|
'Você acumula armazenamento para cada arquivo que seu usuário carrega em seu bot. Se você excluir o resultado, ele liberará espaço.',
|
||||||
|
'billing.pricingCard.starter.description':
|
||||||
|
'Para indivíduos e pequenas empresas.',
|
||||||
|
'billing.pricingCard.starter.includedSeats': '2 assentos incluídos',
|
||||||
|
'billing.pricingCard.starter.brandingRemoved': 'Marca removida',
|
||||||
|
'billing.pricingCard.starter.fileUploadBlock': 'Bloco de envio de arquivo',
|
||||||
|
'billing.pricingCard.starter.createFolders': 'Criar pastas',
|
||||||
|
'billing.pricingCard.pro.mostPopularLabel': 'Mais popular',
|
||||||
|
'billing.pricingCard.pro.description':
|
||||||
|
'Para agências e startups em crescimento.',
|
||||||
|
'billing.pricingCard.pro.everythingFromStarter': 'Tudo em Starter',
|
||||||
|
'billing.pricingCard.pro.includedSeats': '5 assentos incluídos',
|
||||||
|
'billing.pricingCard.pro.customDomains': 'Domínios personalizados',
|
||||||
|
'billing.pricingCard.pro.analytics': 'Análises aprofundadas',
|
||||||
|
'billing.usage.heading': 'Uso',
|
||||||
|
'billing.usage.unlimited': 'Ilimitado',
|
||||||
|
'billing.usage.chats.heading': 'Chats',
|
||||||
|
'billing.usage.chats.alert.soonReach':
|
||||||
|
'Seus typebots são populares! Você logo alcançará o limite de chats de seu plano. 🚀',
|
||||||
|
'billing.usage.chats.alert.updatePlan':
|
||||||
|
'Certifique-se de atualizar seu plano para aumentar esse limite e continuar conversando com seus usuários.',
|
||||||
|
'billing.usage.chats.resetInfo': '(reiniciado todo dia 1)',
|
||||||
|
'billing.usage.storage.heading': 'Armazenamento',
|
||||||
|
'billing.usage.storage.alert.soonReach':
|
||||||
|
'Seus typebots são populares! Você logo alcançará o limite de armazenamento de seu plano. 🚀',
|
||||||
|
'billing.usage.storage.alert.updatePlan':
|
||||||
|
'Certifique-se de atualizar seu plano para continuar coletando arquivos enviados. Você também pode excluir arquivos para liberar espaço.',
|
||||||
|
'billing.limitMessage.brand': 'remover a marca',
|
||||||
|
'billing.limitMessage.customDomain': 'adicionar domínios personalizados',
|
||||||
|
'billing.limitMessage.analytics': 'desbloquear análises aprofundadas',
|
||||||
|
'billing.limitMessage.fileInput': 'usar blocos de envio de arquivo',
|
||||||
|
'billing.limitMessage.folder': 'criar pastas',
|
||||||
|
'billing.upgradeAlert.buttonDefaultLabel': 'Mais informações',
|
||||||
|
'workspace.membersList.inviteInput.placeholder': 'colega@empresa.com',
|
||||||
|
'workspace.membersList.inviteButton.label': 'Convidar',
|
||||||
|
'workspace.membersList.unlockBanner.label':
|
||||||
|
'Atualize seu plano para trabalhar com mais membros da equipe e desbloqueie recursos incríveis 🚀',
|
||||||
|
'workspace.membersList.title': 'Membros',
|
||||||
|
'workspace.settings.icon.title': 'Ícone',
|
||||||
|
'workspace.settings.name.label': 'Nome:',
|
||||||
|
'workspace.settings.deleteButton.label': 'Excluir espaço de trabalho',
|
||||||
|
'workspace.settings.deleteButton.confirmMessage':
|
||||||
|
'Você tem certeza de que deseja excluir o espaço de trabalho {workspaceName}? Todas as suas pastas, typebots e resultados serão excluídos permanentemente.',
|
||||||
|
'workspace.settings.modal.menu.myAccount.label': 'Minha conta',
|
||||||
|
'workspace.settings.modal.menu.preferences.label': 'Preferências',
|
||||||
|
'workspace.settings.modal.menu.workspace.label': 'Espaço de trabalho',
|
||||||
|
'workspace.settings.modal.menu.settings.label': 'Configurações',
|
||||||
|
'workspace.settings.modal.menu.members.label': 'Membros',
|
||||||
|
'workspace.settings.modal.menu.billingAndUsage.label': 'Faturamento e uso',
|
||||||
|
'workspace.settings.modal.menu.version.label': 'Versão: {version}',
|
||||||
|
'workspace.dropdown.newButton.label': 'Novo espaço de trabalho',
|
||||||
|
'workspace.dropdown.logoutButton.label': 'Sair',
|
||||||
|
'templates.buttons.heading': 'Criar um novo typebot',
|
||||||
|
'templates.buttons.fromScratchButton.label': 'Comece do zero',
|
||||||
|
'templates.buttons.fromTemplateButton.label': 'Comece a partir de um modelo',
|
||||||
|
'templates.buttons.importFileButton.label': 'Importar um arquivo',
|
||||||
|
'templates.modal.menuHeading.marketing': 'Marketing',
|
||||||
|
'templates.modal.menuHeading.product': 'Produto',
|
||||||
|
'templates.modal.menuHeading.other': 'Outros',
|
||||||
|
'templates.modal.menuHeading.new.tag': 'Novo',
|
||||||
|
'templates.modal.useTemplateButton.label': 'Usar esse modelo',
|
||||||
|
'templates.importFromFileButon.toastError.description':
|
||||||
|
'Falha ao analisar o arquivo. Tem certeza de que é um typebot?',
|
||||||
|
'editor.headers.flowButton.label': 'Fluxo',
|
||||||
|
'editor.headers.themeButton.label': 'Tema',
|
||||||
|
'editor.headers.settingsButton.label': 'Configurações',
|
||||||
|
'editor.headers.shareButton.label': 'Compartilhar',
|
||||||
|
'editor.headers.resultsButton.label': 'Resultados',
|
||||||
|
'editor.headers.helpButton.label': 'Ajuda',
|
||||||
|
'editor.headers.savingSpinner.label': 'Salvando...',
|
||||||
|
'editor.headers.previewButton.label': 'Visualizar',
|
||||||
|
'editor.sidebarBlocks.sidebar.lock.label': 'Bloquear barra lateral',
|
||||||
|
'editor.sidebarBlocks.sidebar.unlock.label': 'Desbloquear barra lateral',
|
||||||
|
'editor.sidebarBlocks.sidebar.icon.lock.label': 'Bloquear',
|
||||||
|
'editor.sidebarBlocks.sidebar.icon.unlock.label': 'Desbloquear',
|
||||||
|
'editor.sidebarBlocks.blockType.bubbles.heading': 'Bubbles',
|
||||||
|
'editor.sidebarBlocks.blockType.inputs.heading': 'Inputs',
|
||||||
|
'editor.sidebarBlocks.blockType.logic.heading': 'Condicionais',
|
||||||
|
'editor.sidebarBlocks.blockType.integrations.heading': 'Integrações',
|
||||||
|
'editor.sidebarBlock.start.label': 'Início',
|
||||||
|
'editor.sidebarBlock.text.label': 'Texto',
|
||||||
|
'editor.sidebarBlock.image.label': 'Imagem',
|
||||||
|
'editor.sidebarBlock.video.label': 'Vídeo',
|
||||||
|
'editor.sidebarBlock.embed.label': 'Incorporar',
|
||||||
|
'editor.sidebarBlock.audio.label': 'Áudio',
|
||||||
|
'editor.sidebarBlock.number.label': 'Número',
|
||||||
|
'editor.sidebarBlock.email.label': 'Email',
|
||||||
|
'editor.sidebarBlock.website.label': 'Website',
|
||||||
|
'editor.sidebarBlock.date.label': 'Data',
|
||||||
|
'editor.sidebarBlock.phone.label': 'Telefone',
|
||||||
|
'editor.sidebarBlock.button.label': 'Botão',
|
||||||
|
'editor.sidebarBlock.picChoice.label': 'Seleção de Imagem',
|
||||||
|
'editor.sidebarBlock.payment.label': 'Pagamento',
|
||||||
|
'editor.sidebarBlock.rating.label': 'Avaliação',
|
||||||
|
'editor.sidebarBlock.file.label': 'Arquivo',
|
||||||
|
'editor.sidebarBlock.setVariable.label': 'Variável',
|
||||||
|
'editor.sidebarBlock.condition.label': 'Condição',
|
||||||
|
'editor.sidebarBlock.redirect.label': 'Redirecionar',
|
||||||
|
'editor.sidebarBlock.script.label': 'Script',
|
||||||
|
'editor.sidebarBlock.typebot.label': 'Typebot',
|
||||||
|
'editor.sidebarBlock.wait.label': 'Espera',
|
||||||
|
'editor.sidebarBlock.jump.label': 'Pular',
|
||||||
|
'editor.sidebarBlock.abTest.label': 'Teste AB',
|
||||||
|
'editor.sidebarBlock.sheets.label': 'Sheets',
|
||||||
|
'editor.sidebarBlock.analytics.label': 'Analytics',
|
||||||
|
'editor.sidebarBlock.webhook.label': 'Webhook',
|
||||||
|
'editor.sidebarBlock.zapier.label': 'Zapier',
|
||||||
|
'editor.sidebarBlock.makecom.label': 'Make.com',
|
||||||
|
'editor.sidebarBlock.pabbly.label': 'Pabbly',
|
||||||
|
'editor.sidebarBlock.chatwoot.label': 'Chatwoot',
|
||||||
|
'editor.sidebarBlock.openai.label': 'OpenAI',
|
||||||
|
'editor.sidebarBlock.pixel.label': 'Pixel',
|
||||||
|
'editor.blockCard.bubbleBlock.tooltip.label':
|
||||||
|
'Incorporar pdf, iframe, website...',
|
||||||
|
'editor.blockCard.inputBlock.tooltip.files.label': 'Carregar Ficheiros',
|
||||||
|
'editor.blockCard.logicBlock.tooltip.code.label':
|
||||||
|
'Executar código Javascript',
|
||||||
|
'editor.blockCard.logicBlock.tooltip.typebotLink.label':
|
||||||
|
'Link e salte para outro typebot',
|
||||||
|
'editor.blockCard.logicBlock.tooltip.jump.label':
|
||||||
|
'Encaminhar fluxo para outro grupo',
|
||||||
|
'editor.blockCard.integrationBlock.tooltip.googleSheets.label':
|
||||||
|
'Google Sheets',
|
||||||
|
'editor.blockCard.integrationBlock.tooltip.googleAnalytics.label':
|
||||||
|
'Google Analytics',
|
||||||
|
'editor.editableTypebotName.tooltip.rename.label': 'Renomear',
|
||||||
|
'editor.gettingStartedModal.editorBasics.heading': 'Fundamentos do Editor',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.one.label':
|
||||||
|
'A barra lateral esquerda contém blocos que podem ser arrastados e soltos no quadro.',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.two.label':
|
||||||
|
'Você pode agrupar blocos juntos, colocando-os abaixo ou acima dos outros',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.three.label':
|
||||||
|
'Conecte os grupos entre eles',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.four.label':
|
||||||
|
'Pré-visualize o seu bot ao clicar no botão de visualizar no canto superior direito',
|
||||||
|
'editor.gettingStartedModal.editorBasics.list.label':
|
||||||
|
'Sinta-se à vontade para usar o chat no canto inferior direito para entrar em contato se tiver alguma dúvida. Normalmente, respondo nas próximas 24 horas. 😃',
|
||||||
|
'editor.gettingStartedModal.seeAction.label': 'Veja como funciona em',
|
||||||
|
'editor.gettingStartedModal.seeAction.time': '5 minutos',
|
||||||
|
'editor.gettingStartedModal.seeAction.item.label': 'Outros vídeos',
|
||||||
|
'editor.provider.messages.getTypebotError.title':
|
||||||
|
'Erro ao obter o typebot. Atualize a página.',
|
||||||
|
'editor.provider.messages.getTypebotError.description':
|
||||||
|
'Não foi possível encontrar o typebot',
|
||||||
|
'editor.provider.messages.publishedTypebotError.title':
|
||||||
|
'Erro ao obter o typebot publicado',
|
||||||
|
'editor.provider.messages.updateTypebotError.title':
|
||||||
|
'Erro ao atualizar o typebot',
|
||||||
|
'editor.provider.groups.copy.title': 'Cópia',
|
||||||
|
'editor.blocks.start.text': 'Início',
|
||||||
|
'editor.blocks.bubbles.audio.settings.upload.label': 'Carregar',
|
||||||
|
'editor.blocks.bubbles.audio.settings.embedLink.label': 'Incorporar link',
|
||||||
|
'editor.blocks.bubbles.audio.settings.chooseFile.label':
|
||||||
|
'Escolher um arquivo',
|
||||||
|
'editor.blocks.bubbles.audio.settings.worksWith.text':
|
||||||
|
'Compatível com .MP3s e .WAVs',
|
||||||
|
'editor.blocks.bubbles.audio.settings.worksWith.placeholder':
|
||||||
|
'Colar o link do arquivo de áudio...',
|
||||||
|
'editor.blocks.bubbles.audio.settings.autoplay.label':
|
||||||
|
'Ativar reprodução automática',
|
||||||
|
'editor.blocks.bubbles.audio.node.clickToEdit.text': 'Clique para editar...',
|
||||||
|
'editor.blocks.bubbles.embed.node.clickToEdit.text': 'Clique para editar...',
|
||||||
|
'editor.blocks.bubbles.embed.node.show.text': 'Mostrar incorporação',
|
||||||
|
'editor.blocks.bubbles.embed.settings.worksWith.placeholder':
|
||||||
|
'Colar o link ou código...',
|
||||||
|
'editor.blocks.bubbles.embed.settings.worksWith.text':
|
||||||
|
'Compatível com PDFs, iframes, websites...',
|
||||||
|
'editor.blocks.bubbles.embed.settings.numberInput.unit': 'px',
|
||||||
|
'editor.blocks.bubbles.image.node.clickToEdit.text': 'Clique para editar...',
|
||||||
|
'editor.blocks.bubbles.image.switchWithLabel.onClick.label': 'Link ao clicar',
|
||||||
|
'editor.blocks.bubbles.image.switchWithLabel.onClick.placeholder':
|
||||||
|
'Texto alternativo do link (descrição)',
|
||||||
|
'editor.blocks.bubbles.video.node.clickToEdit.text': 'Clique para editar...',
|
||||||
|
'editor.blocks.bubbles.video.settings.worksWith.text':
|
||||||
|
'Compatível com Youtube, Vimeo e outros',
|
||||||
|
'editor.blocks.bubbles.video.settings.worksWith.placeholder':
|
||||||
|
'Colar o link do vídeo...',
|
||||||
|
'editor.blocks.bubbles.textEditor.plate.label': 'Editor de texto',
|
||||||
|
'editor.blocks.bubbles.textEditor.searchVariable.placeholder':
|
||||||
|
'Pesquisar uma variável',
|
||||||
|
} as const
|
@ -16,10 +16,10 @@ import { Plan } from '@typebot.io/prisma'
|
|||||||
import { trpc } from '@/lib/trpc'
|
import { trpc } from '@/lib/trpc'
|
||||||
import { NewVersionPopup } from '@/components/NewVersionPopup'
|
import { NewVersionPopup } from '@/components/NewVersionPopup'
|
||||||
import { I18nProvider } from '@/locales'
|
import { I18nProvider } from '@/locales'
|
||||||
|
import en from '@/locales/en'
|
||||||
import { TypebotProvider } from '@/features/editor/providers/TypebotProvider'
|
import { TypebotProvider } from '@/features/editor/providers/TypebotProvider'
|
||||||
import { WorkspaceProvider } from '@/features/workspace/WorkspaceProvider'
|
import { WorkspaceProvider } from '@/features/workspace/WorkspaceProvider'
|
||||||
import { isCloudProdInstance } from '@/helpers/isCloudProdInstance'
|
import { isCloudProdInstance } from '@/helpers/isCloudProdInstance'
|
||||||
import en from '@/locales/en'
|
|
||||||
|
|
||||||
import { initPostHogIfEnabled } from '@/features/telemetry/posthog'
|
import { initPostHogIfEnabled } from '@/features/telemetry/posthog'
|
||||||
initPostHogIfEnabled()
|
initPostHogIfEnabled()
|
||||||
|
@ -1272,6 +1272,9 @@
|
|||||||
},
|
},
|
||||||
"isRange": {
|
"isRange": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"format": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
@ -5568,6 +5571,9 @@
|
|||||||
},
|
},
|
||||||
"isRange": {
|
"isRange": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"format": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
@ -9499,6 +9505,9 @@
|
|||||||
},
|
},
|
||||||
"isRange": {
|
"isRange": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"format": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
@ -13570,6 +13579,9 @@
|
|||||||
},
|
},
|
||||||
"isRange": {
|
"isRange": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"format": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
@ -17521,6 +17533,9 @@
|
|||||||
},
|
},
|
||||||
"isRange": {
|
"isRange": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"format": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
@ -21527,6 +21542,9 @@
|
|||||||
},
|
},
|
||||||
"isRange": {
|
"isRange": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"format": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
@ -25596,6 +25614,9 @@
|
|||||||
},
|
},
|
||||||
"isRange": {
|
"isRange": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"format": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
@ -855,6 +855,9 @@
|
|||||||
},
|
},
|
||||||
"isRange": {
|
"isRange": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"format": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
@ -4691,6 +4694,9 @@
|
|||||||
},
|
},
|
||||||
"isRange": {
|
"isRange": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"format": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
Reference in New Issue
Block a user