feat(editor): ♿️ Improve graph navigation setting
This commit is contained in:
78
apps/builder/components/account/EditorSection.tsx
Normal file
78
apps/builder/components/account/EditorSection.tsx
Normal file
@ -0,0 +1,78 @@
|
||||
import {
|
||||
Stack,
|
||||
Heading,
|
||||
HStack,
|
||||
Text,
|
||||
Radio,
|
||||
RadioGroup,
|
||||
VStack,
|
||||
} from '@chakra-ui/react'
|
||||
import { MouseIcon, LaptopIcon } from 'assets/icons'
|
||||
import { useUser } from 'contexts/UserContext'
|
||||
import { GraphNavigation } from 'db'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
|
||||
export const EditorSection = () => <EditorSettings />
|
||||
|
||||
export const EditorSettings = () => {
|
||||
const { user, saveUser } = useUser()
|
||||
const [value, setValue] = useState<string>(
|
||||
user?.graphNavigation ?? GraphNavigation.TRACKPAD
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (user?.graphNavigation === value) return
|
||||
saveUser({ graphNavigation: value as GraphNavigation }).then()
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [value])
|
||||
|
||||
const options = [
|
||||
{
|
||||
value: GraphNavigation.MOUSE,
|
||||
label: 'Mouse',
|
||||
description:
|
||||
'Move by dragging the board and zoom in/out using the scroll wheel',
|
||||
icon: <MouseIcon boxSize="35px" />,
|
||||
},
|
||||
{
|
||||
value: GraphNavigation.TRACKPAD,
|
||||
label: 'Trackpad',
|
||||
description: 'Move the board using 2 fingers and zoom in/out by pinching',
|
||||
icon: <LaptopIcon boxSize="35px" />,
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<Stack spacing={6}>
|
||||
<Heading size="md">Navigation</Heading>
|
||||
<RadioGroup onChange={setValue} value={value}>
|
||||
<HStack spacing={4} w="full" align="stretch">
|
||||
{options.map((option) => (
|
||||
<VStack
|
||||
key={option.value}
|
||||
as="label"
|
||||
htmlFor={option.label}
|
||||
cursor="pointer"
|
||||
borderWidth="1px"
|
||||
borderRadius="md"
|
||||
w="full"
|
||||
p="6"
|
||||
spacing={6}
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<VStack spacing={6}>
|
||||
{option.icon}
|
||||
<Stack>
|
||||
<Text fontWeight="bold">{option.label}</Text>
|
||||
<Text>{option.description}</Text>
|
||||
</Stack>
|
||||
</VStack>
|
||||
|
||||
<Radio value={option.value} id={option.label} />
|
||||
</VStack>
|
||||
))}
|
||||
</HStack>
|
||||
</RadioGroup>
|
||||
</Stack>
|
||||
)
|
||||
}
|
@ -10,15 +10,30 @@ import {
|
||||
import assert from 'assert'
|
||||
import { DownloadIcon, MoreVerticalIcon, SettingsIcon } from 'assets/icons'
|
||||
import { useTypebot } from 'contexts/TypebotContext'
|
||||
import React, { useState } from 'react'
|
||||
import { useUser } from 'contexts/UserContext'
|
||||
import { useRouter } from 'next/router'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { parseDefaultPublicId } from 'services/typebots'
|
||||
import { isNotDefined } from 'utils'
|
||||
import { EditorSettingsModal } from './EditorSettingsModal'
|
||||
|
||||
export const BoardMenuButton = (props: MenuButtonProps) => {
|
||||
const { query } = useRouter()
|
||||
const { typebot } = useTypebot()
|
||||
const { user } = useUser()
|
||||
const [isDownloading, setIsDownloading] = useState(false)
|
||||
const { isOpen, onOpen, onClose } = useDisclosure()
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
user &&
|
||||
isNotDefined(user.graphNavigation) &&
|
||||
isNotDefined(query.isFirstBot)
|
||||
)
|
||||
onOpen()
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
const downloadFlow = () => {
|
||||
assert(typebot)
|
||||
setIsDownloading(true)
|
||||
|
@ -1,21 +1,12 @@
|
||||
import {
|
||||
Heading,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
ModalContent,
|
||||
ModalOverlay,
|
||||
Stack,
|
||||
Text,
|
||||
Radio,
|
||||
VStack,
|
||||
RadioGroup,
|
||||
HStack,
|
||||
} from '@chakra-ui/react'
|
||||
import { LaptopIcon, MouseIcon } from 'assets/icons'
|
||||
import { useUser } from 'contexts/UserContext'
|
||||
import { GraphNavigation } from 'db'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { EditorSettings } from 'components/account/EditorSection'
|
||||
import React from 'react'
|
||||
|
||||
type Props = {
|
||||
isOpen: boolean
|
||||
@ -35,63 +26,3 @@ export const EditorSettingsModal = ({ isOpen, onClose }: Props) => {
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
const EditorSettings = () => {
|
||||
const { user, saveUser } = useUser()
|
||||
const [value, setValue] = useState<string>(
|
||||
user?.graphNavigation ?? GraphNavigation.TRACKPAD
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (user?.graphNavigation === value) return
|
||||
saveUser({ graphNavigation: value as GraphNavigation }).then()
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [value])
|
||||
|
||||
const options = [
|
||||
{
|
||||
value: GraphNavigation.MOUSE,
|
||||
label: 'Mouse',
|
||||
description:
|
||||
'Move by dragging the board and zoom in/out using the scroll wheel',
|
||||
icon: <MouseIcon boxSize="35px" />,
|
||||
},
|
||||
{
|
||||
value: GraphNavigation.TRACKPAD,
|
||||
label: 'Trackpad',
|
||||
description: 'Move the board using 2 fingers and zoom in/out by pinching',
|
||||
icon: <LaptopIcon boxSize="35px" />,
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<Stack spacing={4}>
|
||||
<Heading size="md">Navigation</Heading>
|
||||
<RadioGroup onChange={setValue} value={value}>
|
||||
<HStack spacing={4} w="full">
|
||||
{options.map((option) => (
|
||||
<VStack
|
||||
key={option.value}
|
||||
as="label"
|
||||
htmlFor={option.label}
|
||||
cursor="pointer"
|
||||
borderWidth="1px"
|
||||
borderRadius="md"
|
||||
w="full"
|
||||
p="6"
|
||||
spacing={6}
|
||||
>
|
||||
{option.icon}
|
||||
<Stack>
|
||||
<Text fontWeight="bold">{option.label}</Text>
|
||||
<Text>{option.description}</Text>
|
||||
</Stack>
|
||||
|
||||
<Radio value={option.value} id={option.label} />
|
||||
</VStack>
|
||||
))}
|
||||
</HStack>
|
||||
</RadioGroup>
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
|
@ -55,7 +55,12 @@ export const CreateNewTypebotButtons = () => {
|
||||
if (data)
|
||||
router.push({
|
||||
pathname: `/typebots/${data.id}/edit`,
|
||||
query: { isFirstBot: router.query.isFirstBot },
|
||||
query:
|
||||
router.query.isFirstBot === 'true'
|
||||
? {
|
||||
isFirstBot: 'true',
|
||||
}
|
||||
: {},
|
||||
})
|
||||
setIsLoading(false)
|
||||
}
|
||||
|
@ -4,10 +4,11 @@ import { NextChakraLink } from 'components/nextChakra/NextChakraLink'
|
||||
import React from 'react'
|
||||
import { PersonalInfoForm } from 'components/account/PersonalInfoForm'
|
||||
import { BillingSection } from 'components/account/BillingSection'
|
||||
import { EditorSection } from 'components/account/EditorSection'
|
||||
|
||||
export const AccountContent = () => {
|
||||
return (
|
||||
<Flex h="full" w="full" justifyContent="center" align="flex-start">
|
||||
<Flex h="full" w="full" justifyContent="center" align="flex-start" pb="20">
|
||||
<Stack maxW="600px" w="full" pt="4" spacing={10}>
|
||||
<Flex>
|
||||
<Button
|
||||
@ -28,6 +29,8 @@ export const AccountContent = () => {
|
||||
<PersonalInfoForm />
|
||||
<Divider />
|
||||
<BillingSection />
|
||||
<Divider />
|
||||
<EditorSection />
|
||||
</Stack>
|
||||
</Flex>
|
||||
)
|
||||
|
Reference in New Issue
Block a user