🌐 Add theme tab translation keys (#1119)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Implemented internationalization across various components, enabling dynamic language translation for UI elements. - **Enhancements** - Improved accessibility with translated `aria-label` attributes. - Enhanced user interface with translated button texts and labels. - **Refactor** - Streamlined translation handling with the `useTranslate` hook. - **Bug Fixes** - Corrected tooltip label for better clarity. - **Style** - Updated visual elements to reflect changes in language settings. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Baptiste Arnaud <baptiste.arnaud95@gmail.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import { ThemeTemplate } from '@typebot.io/schemas'
|
||||
import { areThemesEqual } from '../helpers/areThemesEqual'
|
||||
import { SaveThemeModal } from './SaveThemeModal'
|
||||
import { ThemeTemplateCard } from './ThemeTemplateCard'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
|
||||
type Props = {
|
||||
selectedTemplateId: string | undefined
|
||||
@@ -21,6 +22,7 @@ export const MyTemplates = ({
|
||||
workspaceId,
|
||||
onTemplateSelect,
|
||||
}: Props) => {
|
||||
const { t } = useTranslate()
|
||||
const { isOpen, onOpen, onClose } = useDisclosure()
|
||||
const { data } = trpc.theme.listThemeTemplates.useQuery({
|
||||
workspaceId,
|
||||
@@ -41,7 +43,7 @@ export const MyTemplates = ({
|
||||
{(!selectedTemplate ||
|
||||
!areThemesEqual(selectedTemplate?.theme, currentTheme)) && (
|
||||
<Button leftIcon={<SaveIcon />} onClick={onOpen} colorScheme="blue">
|
||||
Save current theme
|
||||
{t('theme.sideMenu.template.myTemplates.saveTheme')}
|
||||
</Button>
|
||||
)}
|
||||
<SaveThemeModal
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
ModalOverlay,
|
||||
} from '@chakra-ui/react'
|
||||
import { createId } from '@paralleldrive/cuid2'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
import { ThemeTemplate } from '@typebot.io/schemas'
|
||||
import { FormEvent, useRef, useState } from 'react'
|
||||
|
||||
@@ -31,6 +32,7 @@ export const SaveThemeModal = ({
|
||||
selectedTemplate,
|
||||
theme,
|
||||
}: Props) => {
|
||||
const { t } = useTranslate()
|
||||
const { showToast } = useToast()
|
||||
const [isSaving, setIsSaving] = useState(false)
|
||||
const inputRef = useRef<HTMLInputElement>(null)
|
||||
@@ -80,15 +82,19 @@ export const SaveThemeModal = ({
|
||||
<Modal isOpen={isOpen} onClose={onClose} initialFocusRef={inputRef}>
|
||||
<ModalOverlay />
|
||||
<ModalContent as="form" onSubmit={updateExistingTemplate}>
|
||||
<ModalHeader>Save theme</ModalHeader>
|
||||
<ModalHeader>
|
||||
{t('theme.sideMenu.template.myTemplates.saveTheme.title')}
|
||||
</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody>
|
||||
<TextInput
|
||||
ref={inputRef}
|
||||
label="Name:"
|
||||
label={t('theme.sideMenu.template.myTemplates.saveTheme.name')}
|
||||
defaultValue={selectedTemplate?.name}
|
||||
withVariableButton={false}
|
||||
placeholder="My template"
|
||||
placeholder={t(
|
||||
'theme.sideMenu.template.myTemplates.saveTheme.myTemplate'
|
||||
)}
|
||||
isRequired
|
||||
/>
|
||||
</ModalBody>
|
||||
@@ -96,11 +102,11 @@ export const SaveThemeModal = ({
|
||||
<ModalFooter as={HStack}>
|
||||
{selectedTemplate?.id && (
|
||||
<Button isLoading={isSaving} onClick={saveNewTemplate}>
|
||||
Save as new template
|
||||
{t('theme.sideMenu.template.myTemplates.saveTheme.saveAsNew')}
|
||||
</Button>
|
||||
)}
|
||||
<Button type="submit" colorScheme="blue" isLoading={isSaving}>
|
||||
{selectedTemplate?.id ? 'Update' : 'Save'}
|
||||
{selectedTemplate?.id ? t('update') : t('save')}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
|
||||
@@ -18,8 +18,11 @@ import { ChatThemeSettings } from './chat/ChatThemeSettings'
|
||||
import { GeneralSettings } from './general/GeneralSettings'
|
||||
import { ThemeTemplates } from './ThemeTemplates'
|
||||
import { defaultSettings } from '@typebot.io/schemas/features/typebot/settings/constants'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
|
||||
export const ThemeSideMenu = () => {
|
||||
const { t } = useTranslate()
|
||||
|
||||
const { typebot, updateTypebot, currentUserMode } = useTypebot()
|
||||
|
||||
const updateChatTheme = (chat: ChatTheme) =>
|
||||
@@ -67,7 +70,7 @@ export const ThemeSideMenu = () => {
|
||||
position="relative"
|
||||
>
|
||||
<Heading fontSize="xl" textAlign="center">
|
||||
Customize the theme
|
||||
{t('theme.sideMenu.title')}
|
||||
</Heading>
|
||||
<Accordion allowMultiple>
|
||||
{currentUserMode === 'write' && (
|
||||
@@ -75,7 +78,7 @@ export const ThemeSideMenu = () => {
|
||||
<AccordionButton py={6}>
|
||||
<HStack flex="1" pl={2}>
|
||||
<TableIcon />
|
||||
<Heading fontSize="lg">Templates</Heading>
|
||||
<Heading fontSize="lg">{t('theme.sideMenu.template')}</Heading>
|
||||
</HStack>
|
||||
<AccordionIcon />
|
||||
</AccordionButton>
|
||||
@@ -97,7 +100,7 @@ export const ThemeSideMenu = () => {
|
||||
<AccordionButton py={6}>
|
||||
<HStack flex="1" pl={2}>
|
||||
<DropletIcon />
|
||||
<Heading fontSize="lg">Global</Heading>
|
||||
<Heading fontSize="lg">{t('theme.sideMenu.global')}</Heading>
|
||||
</HStack>
|
||||
<AccordionIcon />
|
||||
</AccordionButton>
|
||||
@@ -119,7 +122,7 @@ export const ThemeSideMenu = () => {
|
||||
<AccordionButton py={6}>
|
||||
<HStack flex="1" pl={2}>
|
||||
<ChatIcon />
|
||||
<Heading fontSize="lg">Chat</Heading>
|
||||
<Heading fontSize="lg">{t('theme.sideMenu.chat')}</Heading>
|
||||
</HStack>
|
||||
<AccordionIcon />
|
||||
</AccordionButton>
|
||||
@@ -138,7 +141,7 @@ export const ThemeSideMenu = () => {
|
||||
<AccordionButton py={6}>
|
||||
<HStack flex="1" pl={2}>
|
||||
<CodeIcon />
|
||||
<Heading fontSize="lg">Custom CSS</Heading>
|
||||
<Heading fontSize="lg">{t('theme.sideMenu.customCSS')}</Heading>
|
||||
</HStack>
|
||||
<AccordionIcon />
|
||||
</AccordionButton>
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
BackgroundType,
|
||||
defaultTheme,
|
||||
} from '@typebot.io/schemas/features/typebot/theme/constants'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
|
||||
export const ThemeTemplateCard = ({
|
||||
workspaceId,
|
||||
@@ -38,6 +39,7 @@ export const ThemeTemplateCard = ({
|
||||
onClick: () => void
|
||||
onDeleteSuccess?: () => void
|
||||
}) => {
|
||||
const { t } = useTranslate()
|
||||
const borderWidth = useColorModeValue(undefined, '1px')
|
||||
const [isDeleting, setIsDeleting] = useState(false)
|
||||
|
||||
@@ -160,7 +162,9 @@ export const ThemeTemplateCard = ({
|
||||
<MenuButton
|
||||
as={IconButton}
|
||||
icon={<MoreHorizontalIcon />}
|
||||
aria-label="Open template menu"
|
||||
aria-label={t(
|
||||
'theme.sideMenu.template.myTemplates.menu.ariaLabel'
|
||||
)}
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
@@ -168,7 +172,7 @@ export const ThemeTemplateCard = ({
|
||||
<MenuList onClick={(e) => e.stopPropagation()}>
|
||||
{isSelected && (
|
||||
<MenuItem icon={<EditIcon />} onClick={onRenameClick}>
|
||||
Rename
|
||||
{t('rename')}
|
||||
</MenuItem>
|
||||
)}
|
||||
<MenuItem
|
||||
@@ -176,7 +180,7 @@ export const ThemeTemplateCard = ({
|
||||
color="red.500"
|
||||
onClick={deleteThemeTemplate}
|
||||
>
|
||||
Delete
|
||||
{t('delete')}
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
@@ -208,11 +212,12 @@ const AvatarPreview = ({
|
||||
}: {
|
||||
avatar: NonNullable<Theme['chat']>['hostAvatar']
|
||||
}) => {
|
||||
const { t } = useTranslate()
|
||||
if (avatar?.isEnabled) return null
|
||||
return avatar?.url ? (
|
||||
<Image
|
||||
src={avatar.url}
|
||||
alt="Avatar preview in theme template card"
|
||||
alt={t('theme.sideMenu.template.gallery.avatarPreview.alt')}
|
||||
boxSize="12px"
|
||||
rounded="full"
|
||||
/>
|
||||
|
||||
@@ -3,6 +3,7 @@ import { ThemeTemplate } from '@typebot.io/schemas'
|
||||
import { useState } from 'react'
|
||||
import { MyTemplates } from './MyTemplates'
|
||||
import { TemplatesGallery } from './TemplatesGallery'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
|
||||
type Tab = 'my-templates' | 'gallery'
|
||||
|
||||
@@ -21,6 +22,8 @@ export const ThemeTemplates = ({
|
||||
currentTheme,
|
||||
onTemplateSelect,
|
||||
}: Props) => {
|
||||
const { t } = useTranslate()
|
||||
|
||||
const [selectedTab, setSelectedTab] = useState<Tab>('my-templates')
|
||||
|
||||
return (
|
||||
@@ -32,7 +35,7 @@ export const ThemeTemplates = ({
|
||||
colorScheme={selectedTab === 'my-templates' ? 'blue' : 'gray'}
|
||||
onClick={() => setSelectedTab('my-templates')}
|
||||
>
|
||||
My templates
|
||||
{t('theme.sideMenu.template.myTemplates')}
|
||||
</Button>
|
||||
<Button
|
||||
flex="1"
|
||||
@@ -40,7 +43,7 @@ export const ThemeTemplates = ({
|
||||
colorScheme={selectedTab === 'gallery' ? 'blue' : 'gray'}
|
||||
onClick={() => setSelectedTab('gallery')}
|
||||
>
|
||||
Gallery
|
||||
{t('theme.sideMenu.template.gallery')}
|
||||
</Button>
|
||||
</HStack>
|
||||
<ThemeTemplatesBody
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Stack, Flex, Text } from '@chakra-ui/react'
|
||||
import { Theme } from '@typebot.io/schemas'
|
||||
import React from 'react'
|
||||
import { ColorPicker } from '../../../../components/ColorPicker'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
|
||||
type Props = {
|
||||
buttons: NonNullable<Theme['chat']>['buttons']
|
||||
@@ -9,6 +10,8 @@ type Props = {
|
||||
}
|
||||
|
||||
export const ButtonsTheme = ({ buttons, onButtonsChange }: Props) => {
|
||||
const { t } = useTranslate()
|
||||
|
||||
const handleBackgroundChange = (backgroundColor: string) =>
|
||||
onButtonsChange({ ...buttons, backgroundColor })
|
||||
const handleTextChange = (color: string) =>
|
||||
@@ -17,14 +20,14 @@ export const ButtonsTheme = ({ buttons, onButtonsChange }: Props) => {
|
||||
return (
|
||||
<Stack data-testid="buttons-theme">
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text>Background:</Text>
|
||||
<Text>{t('theme.sideMenu.chat.theme.background')}</Text>
|
||||
<ColorPicker
|
||||
value={buttons?.backgroundColor}
|
||||
onColorChange={handleBackgroundChange}
|
||||
/>
|
||||
</Flex>
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text>Text:</Text>
|
||||
<Text>{t('theme.sideMenu.chat.theme.text')}</Text>
|
||||
<ColorPicker value={buttons?.color} onColorChange={handleTextChange} />
|
||||
</Flex>
|
||||
</Stack>
|
||||
|
||||
@@ -13,6 +13,7 @@ import { GuestBubbles } from './GuestBubbles'
|
||||
import { HostBubbles } from './HostBubbles'
|
||||
import { InputsTheme } from './InputsTheme'
|
||||
import { defaultTheme } from '@typebot.io/schemas/features/typebot/theme/constants'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
|
||||
type Props = {
|
||||
workspaceId: string
|
||||
@@ -27,6 +28,8 @@ export const ChatThemeSettings = ({
|
||||
chatTheme,
|
||||
onChatThemeChange,
|
||||
}: Props) => {
|
||||
const { t } = useTranslate()
|
||||
|
||||
const updateHostBubbles = (
|
||||
hostBubbles: NonNullable<Theme['chat']>['hostBubbles']
|
||||
) => onChatThemeChange({ ...chatTheme, hostBubbles })
|
||||
@@ -55,7 +58,7 @@ export const ChatThemeSettings = ({
|
||||
typebotId,
|
||||
fileName: 'hostAvatar',
|
||||
}}
|
||||
title="Bot avatar"
|
||||
title={t('theme.sideMenu.chat.botAvatar')}
|
||||
avatarProps={chatTheme?.hostAvatar}
|
||||
isDefaultCheck
|
||||
onAvatarChange={updateHostAvatar}
|
||||
@@ -66,12 +69,12 @@ export const ChatThemeSettings = ({
|
||||
typebotId,
|
||||
fileName: 'guestAvatar',
|
||||
}}
|
||||
title="User avatar"
|
||||
title={t('theme.sideMenu.chat.userAvatar')}
|
||||
avatarProps={chatTheme?.guestAvatar}
|
||||
onAvatarChange={updateGuestAvatar}
|
||||
/>
|
||||
<Stack borderWidth={1} rounded="md" p="4" spacing={4}>
|
||||
<Heading fontSize="lg">Bot bubbles</Heading>
|
||||
<Heading fontSize="lg">{t('theme.sideMenu.chat.botBubbles')}</Heading>
|
||||
<HostBubbles
|
||||
hostBubbles={chatTheme?.hostBubbles}
|
||||
onHostBubblesChange={updateHostBubbles}
|
||||
@@ -79,25 +82,27 @@ export const ChatThemeSettings = ({
|
||||
</Stack>
|
||||
|
||||
<Stack borderWidth={1} rounded="md" p="4" spacing={4}>
|
||||
<Heading fontSize="lg">User bubbles</Heading>
|
||||
<Heading fontSize="lg">{t('theme.sideMenu.chat.userBubbles')}</Heading>
|
||||
<GuestBubbles
|
||||
guestBubbles={chatTheme?.guestBubbles}
|
||||
onGuestBubblesChange={updateGuestBubbles}
|
||||
/>
|
||||
</Stack>
|
||||
<Stack borderWidth={1} rounded="md" p="4" spacing={4}>
|
||||
<Heading fontSize="lg">Buttons</Heading>
|
||||
<Heading fontSize="lg">{t('theme.sideMenu.chat.buttons')}</Heading>
|
||||
<ButtonsTheme
|
||||
buttons={chatTheme?.buttons}
|
||||
onButtonsChange={updateButtons}
|
||||
/>
|
||||
</Stack>
|
||||
<Stack borderWidth={1} rounded="md" p="4" spacing={4}>
|
||||
<Heading fontSize="lg">Inputs</Heading>
|
||||
<Heading fontSize="lg">{t('theme.sideMenu.chat.inputs')}</Heading>
|
||||
<InputsTheme inputs={chatTheme?.inputs} onInputsChange={updateInputs} />
|
||||
</Stack>
|
||||
<Stack borderWidth={1} rounded="md" p="4" spacing={4}>
|
||||
<Heading fontSize="lg">Corners roundness</Heading>
|
||||
<Heading fontSize="lg">
|
||||
{t('theme.sideMenu.chat.cornersRoundness')}
|
||||
</Heading>
|
||||
<RadioButtons
|
||||
options={[
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@ import { ContainerColors } from '@typebot.io/schemas'
|
||||
import React from 'react'
|
||||
import { ColorPicker } from '../../../../components/ColorPicker'
|
||||
import { defaultTheme } from '@typebot.io/schemas/features/typebot/theme/constants'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
|
||||
type Props = {
|
||||
guestBubbles: ContainerColors | undefined
|
||||
@@ -10,6 +11,8 @@ type Props = {
|
||||
}
|
||||
|
||||
export const GuestBubbles = ({ guestBubbles, onGuestBubblesChange }: Props) => {
|
||||
const { t } = useTranslate()
|
||||
|
||||
const updateBackground = (backgroundColor: string) =>
|
||||
onGuestBubblesChange({ ...guestBubbles, backgroundColor })
|
||||
|
||||
@@ -19,7 +22,7 @@ export const GuestBubbles = ({ guestBubbles, onGuestBubblesChange }: Props) => {
|
||||
return (
|
||||
<Stack data-testid="guest-bubbles-theme">
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text>Background:</Text>
|
||||
<Text>{t('theme.sideMenu.chat.theme.background')}</Text>
|
||||
<ColorPicker
|
||||
value={
|
||||
guestBubbles?.backgroundColor ??
|
||||
@@ -29,7 +32,7 @@ export const GuestBubbles = ({ guestBubbles, onGuestBubblesChange }: Props) => {
|
||||
/>
|
||||
</Flex>
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text>Text:</Text>
|
||||
<Text>{t('theme.sideMenu.chat.theme.text')}</Text>
|
||||
<ColorPicker
|
||||
value={guestBubbles?.color ?? defaultTheme.chat.guestBubbles.color}
|
||||
onColorChange={updateText}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { ContainerColors } from '@typebot.io/schemas'
|
||||
import React from 'react'
|
||||
import { ColorPicker } from '../../../../components/ColorPicker'
|
||||
import { defaultTheme } from '@typebot.io/schemas/features/typebot/theme/constants'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
|
||||
type Props = {
|
||||
hostBubbles: ContainerColors | undefined
|
||||
@@ -10,6 +11,8 @@ type Props = {
|
||||
}
|
||||
|
||||
export const HostBubbles = ({ hostBubbles, onHostBubblesChange }: Props) => {
|
||||
const { t } = useTranslate()
|
||||
|
||||
const handleBackgroundChange = (backgroundColor: string) =>
|
||||
onHostBubblesChange({ ...hostBubbles, backgroundColor })
|
||||
const handleTextChange = (color: string) =>
|
||||
@@ -18,7 +21,7 @@ export const HostBubbles = ({ hostBubbles, onHostBubblesChange }: Props) => {
|
||||
return (
|
||||
<Stack data-testid="host-bubbles-theme">
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text>Background:</Text>
|
||||
<Text>{t('theme.sideMenu.chat.theme.background')}</Text>
|
||||
<ColorPicker
|
||||
value={
|
||||
hostBubbles?.backgroundColor ??
|
||||
@@ -28,7 +31,7 @@ export const HostBubbles = ({ hostBubbles, onHostBubblesChange }: Props) => {
|
||||
/>
|
||||
</Flex>
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text>Text:</Text>
|
||||
<Text>{t('theme.sideMenu.chat.theme.text')}</Text>
|
||||
<ColorPicker
|
||||
value={hostBubbles?.color ?? defaultTheme.chat.hostBubbles.color}
|
||||
onColorChange={handleTextChange}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Stack, Flex, Text } from '@chakra-ui/react'
|
||||
import { InputColors, Theme } from '@typebot.io/schemas'
|
||||
import React from 'react'
|
||||
import { ColorPicker } from '../../../../components/ColorPicker'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
|
||||
type Props = {
|
||||
inputs: NonNullable<Theme['chat']>['inputs']
|
||||
@@ -9,6 +10,8 @@ type Props = {
|
||||
}
|
||||
|
||||
export const InputsTheme = ({ inputs, onInputsChange }: Props) => {
|
||||
const { t } = useTranslate()
|
||||
|
||||
const handleBackgroundChange = (backgroundColor: string) =>
|
||||
onInputsChange({ ...inputs, backgroundColor })
|
||||
const handleTextChange = (color: string) =>
|
||||
@@ -19,18 +22,18 @@ export const InputsTheme = ({ inputs, onInputsChange }: Props) => {
|
||||
return (
|
||||
<Stack data-testid="inputs-theme">
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text>Background:</Text>
|
||||
<Text>{t('theme.sideMenu.chat.theme.background')}</Text>
|
||||
<ColorPicker
|
||||
value={inputs?.backgroundColor}
|
||||
onColorChange={handleBackgroundChange}
|
||||
/>
|
||||
</Flex>
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text>Text:</Text>
|
||||
<Text>{t('theme.sideMenu.chat.theme.text')}</Text>
|
||||
<ColorPicker value={inputs?.color} onColorChange={handleTextChange} />
|
||||
</Flex>
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text>Placeholder text:</Text>
|
||||
<Text>{t('theme.sideMenu.chat.theme.placeholder')}</Text>
|
||||
<ColorPicker
|
||||
value={inputs?.placeholderColor}
|
||||
onColorChange={handlePlaceholderChange}
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
BackgroundType,
|
||||
defaultTheme,
|
||||
} from '@typebot.io/schemas/features/typebot/theme/constants'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
|
||||
type BackgroundContentProps = {
|
||||
background?: Background
|
||||
@@ -28,6 +29,7 @@ export const BackgroundContent = ({
|
||||
background,
|
||||
onBackgroundContentChange,
|
||||
}: BackgroundContentProps) => {
|
||||
const { t } = useTranslate()
|
||||
const { typebot } = useTypebot()
|
||||
const handleContentChange = (content: string) =>
|
||||
onBackgroundContentChange(content)
|
||||
@@ -36,7 +38,7 @@ export const BackgroundContent = ({
|
||||
case BackgroundType.COLOR:
|
||||
return (
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text>Background color:</Text>
|
||||
<Text>{t('theme.sideMenu.global.background.color')}</Text>
|
||||
<ColorPicker
|
||||
value={
|
||||
background.content ?? defaultTheme.general.background.content
|
||||
@@ -53,7 +55,7 @@ export const BackgroundContent = ({
|
||||
{isNotEmpty(background.content) ? (
|
||||
<Image
|
||||
src={background.content}
|
||||
alt="Background image"
|
||||
alt={t('theme.sideMenu.global.background.image.alt')}
|
||||
cursor="pointer"
|
||||
_hover={{ filter: 'brightness(.9)' }}
|
||||
transition="filter 200ms"
|
||||
@@ -62,7 +64,9 @@ export const BackgroundContent = ({
|
||||
objectFit="cover"
|
||||
/>
|
||||
) : (
|
||||
<Button>Select an image</Button>
|
||||
<Button>
|
||||
{t('theme.sideMenu.global.background.image.button')}
|
||||
</Button>
|
||||
)}
|
||||
</PopoverTrigger>
|
||||
<Portal>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Background } from '@typebot.io/schemas'
|
||||
import React from 'react'
|
||||
import { BackgroundContent } from './BackgroundContent'
|
||||
import { BackgroundType } from '@typebot.io/schemas/features/typebot/theme/constants'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
|
||||
type Props = {
|
||||
background?: Background
|
||||
@@ -16,6 +17,8 @@ export const BackgroundSelector = ({
|
||||
background,
|
||||
onBackgroundChange,
|
||||
}: Props) => {
|
||||
const { t } = useTranslate()
|
||||
|
||||
const handleBackgroundTypeChange = (type: BackgroundType) =>
|
||||
background &&
|
||||
onBackgroundChange({ ...background, type, content: undefined })
|
||||
@@ -25,12 +28,21 @@ export const BackgroundSelector = ({
|
||||
|
||||
return (
|
||||
<Stack spacing={4}>
|
||||
<Text>Background</Text>
|
||||
<Text>{t('theme.sideMenu.global.background')}</Text>
|
||||
<RadioButtons
|
||||
options={[
|
||||
BackgroundType.COLOR,
|
||||
BackgroundType.IMAGE,
|
||||
BackgroundType.NONE,
|
||||
{
|
||||
label: t('theme.sideMenu.global.background.color.select'),
|
||||
value: BackgroundType.COLOR,
|
||||
},
|
||||
{
|
||||
label: t('theme.sideMenu.global.background.image.select'),
|
||||
value: BackgroundType.IMAGE,
|
||||
},
|
||||
{
|
||||
label: t('theme.sideMenu.global.background.none.select'),
|
||||
value: BackgroundType.NONE,
|
||||
},
|
||||
]}
|
||||
value={background?.type ?? defaultBackgroundType}
|
||||
onSelect={handleBackgroundTypeChange}
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'
|
||||
import { Text, HStack } from '@chakra-ui/react'
|
||||
import { AutocompleteInput } from '@/components/inputs/AutocompleteInput'
|
||||
import { env } from '@typebot.io/env'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
|
||||
type FontSelectorProps = {
|
||||
activeFont?: string
|
||||
@@ -12,6 +13,7 @@ export const FontSelector = ({
|
||||
activeFont,
|
||||
onSelectFont,
|
||||
}: FontSelectorProps) => {
|
||||
const { t } = useTranslate()
|
||||
const [currentFont, setCurrentFont] = useState(activeFont)
|
||||
const [googleFonts, setGoogleFonts] = useState<string[]>([])
|
||||
|
||||
@@ -37,7 +39,7 @@ export const FontSelector = ({
|
||||
|
||||
return (
|
||||
<HStack justify="space-between" align="center">
|
||||
<Text>Font</Text>
|
||||
<Text>{t('theme.sideMenu.global.font')}</Text>
|
||||
<AutocompleteInput
|
||||
value={activeFont}
|
||||
items={googleFonts}
|
||||
|
||||
@@ -53,7 +53,7 @@ export const GeneralSettings = ({
|
||||
onClick={isWorkspaceFreePlan ? onOpen : undefined}
|
||||
>
|
||||
<FormLabel htmlFor="branding" mb="0" cursor="pointer">
|
||||
Show Typebot brand{' '}
|
||||
{t('theme.sideMenu.global.typebotBrand')}{' '}
|
||||
{isWorkspaceFreePlan && <LockTag plan={Plan.STARTER} />}
|
||||
</FormLabel>
|
||||
<Switch
|
||||
|
||||
Reference in New Issue
Block a user