🦴 Add results backbone
This commit is contained in:
11
apps/builder/assets/styles/submissionsTable.css
Normal file
11
apps/builder/assets/styles/submissionsTable.css
Normal file
@ -0,0 +1,11 @@
|
||||
.table-wrapper {
|
||||
background-image: linear-gradient(to right, white, white),
|
||||
linear-gradient(to right, white, white),
|
||||
linear-gradient(to right, rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0)),
|
||||
linear-gradient(to left, rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0));
|
||||
background-position: left center, right center, left center, right center;
|
||||
background-repeat: no-repeat;
|
||||
background-color: white;
|
||||
background-size: 30px 100%, 30px 100%, 15px 100%, 15px 100%;
|
||||
background-attachment: local, local, scroll, scroll;
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/* eslint-disable react/jsx-key */
|
||||
import { Box, Flex } from '@chakra-ui/react'
|
||||
import { useTypebot } from 'contexts/TypebotContext'
|
||||
import React from 'react'
|
||||
import { useTable } from 'react-table'
|
||||
import { parseSubmissionsColumns } from 'services/publicTypebot'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
type SubmissionsTableProps = {}
|
||||
|
||||
export const SubmissionsTable = ({}: SubmissionsTableProps) => {
|
||||
const { publishedTypebot } = useTypebot()
|
||||
const columns: any = React.useMemo(
|
||||
() => parseSubmissionsColumns(publishedTypebot),
|
||||
[publishedTypebot]
|
||||
)
|
||||
const data = React.useMemo(() => [], [])
|
||||
const { getTableProps, headerGroups, rows, prepareRow, getTableBodyProps } =
|
||||
useTable({ columns, data })
|
||||
return (
|
||||
<Flex overflowX="scroll" maxW="full" className="table-wrapper" rounded="md">
|
||||
<Box as="table" rounded="md" {...getTableProps()}>
|
||||
<Box as="thead">
|
||||
{headerGroups.map((headerGroup) => {
|
||||
return (
|
||||
<Box as="tr" {...headerGroup.getHeaderGroupProps()}>
|
||||
{headerGroup.headers.map((column) => {
|
||||
return (
|
||||
<Box
|
||||
py={2}
|
||||
px={4}
|
||||
border="1px"
|
||||
borderColor="gray.200"
|
||||
as="th"
|
||||
minW="200px"
|
||||
color="gray.500"
|
||||
fontWeight="normal"
|
||||
textAlign="left"
|
||||
{...column.getHeaderProps()}
|
||||
>
|
||||
{column.render('Header')}
|
||||
</Box>
|
||||
)
|
||||
})}
|
||||
</Box>
|
||||
)
|
||||
})}
|
||||
</Box>
|
||||
|
||||
<Box as="tbody" {...getTableBodyProps()}>
|
||||
{rows.map((row) => {
|
||||
prepareRow(row)
|
||||
return (
|
||||
<Box as="tr" {...row.getRowProps()}>
|
||||
{row.cells.map((cell) => {
|
||||
return (
|
||||
<Box
|
||||
py={2}
|
||||
px={4}
|
||||
border="1px"
|
||||
as="td"
|
||||
minW="200px"
|
||||
borderColor="gray.200"
|
||||
{...cell.getCellProps()}
|
||||
>
|
||||
{cell.render('Cell')}
|
||||
</Box>
|
||||
)
|
||||
})}
|
||||
</Box>
|
||||
)
|
||||
})}
|
||||
</Box>
|
||||
</Box>
|
||||
</Flex>
|
||||
)
|
||||
}
|
@ -0,0 +1 @@
|
||||
export { SubmissionsTable } from './SubmissionsTable'
|
@ -69,7 +69,7 @@ export const TypebotHeader = () => {
|
||||
</Button>
|
||||
<Button
|
||||
as={NextChakraLink}
|
||||
href={`/typebots/${typebot?.id}/results/responses`}
|
||||
href={`/typebots/${typebot?.id}/results`}
|
||||
colorScheme={router.pathname.includes('results') ? 'blue' : 'gray'}
|
||||
variant={router.pathname.includes('results') ? 'outline' : 'ghost'}
|
||||
>
|
||||
|
5
apps/builder/layouts/results/AnalyticsContent.tsx
Normal file
5
apps/builder/layouts/results/AnalyticsContent.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import React from 'react'
|
||||
|
||||
export const AnalyticsContent = () => {
|
||||
return <>Hi</>
|
||||
}
|
43
apps/builder/layouts/results/ResultsContent.tsx
Normal file
43
apps/builder/layouts/results/ResultsContent.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
import { Button, Flex, HStack, Stack } from '@chakra-ui/react'
|
||||
import { NextChakraLink } from 'components/nextChakra/NextChakraLink'
|
||||
import { useTypebot } from 'contexts/TypebotContext'
|
||||
import { useRouter } from 'next/router'
|
||||
import React, { useMemo } from 'react'
|
||||
import { AnalyticsContent } from './AnalyticsContent'
|
||||
import { SubmissionsContent } from './SubmissionContent'
|
||||
|
||||
export const ResultsContent = () => {
|
||||
const router = useRouter()
|
||||
const { typebot } = useTypebot()
|
||||
const isAnalytics = useMemo(
|
||||
() => router.pathname.endsWith('analytics'),
|
||||
[router.pathname]
|
||||
)
|
||||
return (
|
||||
<Flex h="full" w="full" justifyContent="center" align="flex-start">
|
||||
<Stack maxW="1200px" w="full" pt="4" spacing={6}>
|
||||
<HStack>
|
||||
<Button
|
||||
as={NextChakraLink}
|
||||
colorScheme={!isAnalytics ? 'blue' : 'gray'}
|
||||
variant={!isAnalytics ? 'outline' : 'ghost'}
|
||||
size="sm"
|
||||
href={`/typebots/${typebot?.id}/results`}
|
||||
>
|
||||
Submissions
|
||||
</Button>
|
||||
<Button
|
||||
as={NextChakraLink}
|
||||
colorScheme={isAnalytics ? 'blue' : 'gray'}
|
||||
variant={isAnalytics ? 'outline' : 'ghost'}
|
||||
href={`/typebots/${typebot?.id}/results/analytics`}
|
||||
size="sm"
|
||||
>
|
||||
Analytics
|
||||
</Button>
|
||||
</HStack>
|
||||
{isAnalytics ? <AnalyticsContent /> : <SubmissionsContent />}
|
||||
</Stack>
|
||||
</Flex>
|
||||
)
|
||||
}
|
10
apps/builder/layouts/results/SubmissionContent.tsx
Normal file
10
apps/builder/layouts/results/SubmissionContent.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
import { SubmissionsTable } from 'components/results/SubmissionsTable'
|
||||
import React from 'react'
|
||||
|
||||
export const SubmissionsContent = () => {
|
||||
return (
|
||||
<>
|
||||
<SubmissionsTable />
|
||||
</>
|
||||
)
|
||||
}
|
@ -38,6 +38,7 @@
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-frame-component": "^5.2.1",
|
||||
"react-table": "^7.7.0",
|
||||
"short-uuid": "^4.2.0",
|
||||
"slate": "^0.72.0",
|
||||
"slate-history": "^0.66.0",
|
||||
@ -53,6 +54,7 @@
|
||||
"@types/node": "^16.11.9",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@types/react": "^17.0.37",
|
||||
"@types/react-table": "^7.7.9",
|
||||
"@types/testing-library__cypress": "^5.0.9",
|
||||
"@typescript-eslint/eslint-plugin": "^5.8.0",
|
||||
"cypress": "^9.2.0",
|
||||
|
@ -7,6 +7,7 @@ import { useRouterProgressBar } from 'libs/routerProgressBar'
|
||||
import 'assets/styles/routerProgressBar.css'
|
||||
import 'assets/styles/plate.css'
|
||||
import 'focus-visible/dist/focus-visible'
|
||||
import 'assets/styles/submissionsTable.css'
|
||||
|
||||
const App = ({ Component, pageProps }: AppProps) => {
|
||||
useRouterProgressBar()
|
||||
|
23
apps/builder/pages/typebots/[id]/results.tsx
Normal file
23
apps/builder/pages/typebots/[id]/results.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import { Flex } from '@chakra-ui/layout'
|
||||
import withAuth from 'components/HOC/withUser'
|
||||
import { ResultsContent } from 'layouts/results/ResultsContent'
|
||||
import { Seo } from 'components/Seo'
|
||||
import { TypebotHeader } from 'components/shared/TypebotHeader'
|
||||
import { TypebotContext } from 'contexts/TypebotContext'
|
||||
import { useRouter } from 'next/router'
|
||||
import React from 'react'
|
||||
|
||||
const ResultsPage = () => {
|
||||
const { query } = useRouter()
|
||||
return (
|
||||
<TypebotContext typebotId={query.id?.toString()}>
|
||||
<Seo title="Share" />
|
||||
<Flex overflow="hidden" h="100vh" flexDir="column">
|
||||
<TypebotHeader />
|
||||
<ResultsContent />
|
||||
</Flex>
|
||||
</TypebotContext>
|
||||
)
|
||||
}
|
||||
|
||||
export default withAuth(ResultsPage)
|
23
apps/builder/pages/typebots/[id]/results/analytics.tsx
Normal file
23
apps/builder/pages/typebots/[id]/results/analytics.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import { Flex } from '@chakra-ui/layout'
|
||||
import withAuth from 'components/HOC/withUser'
|
||||
import { ResultsContent } from 'layouts/results/ResultsContent'
|
||||
import { Seo } from 'components/Seo'
|
||||
import { TypebotHeader } from 'components/shared/TypebotHeader'
|
||||
import { TypebotContext } from 'contexts/TypebotContext'
|
||||
import { useRouter } from 'next/router'
|
||||
import React from 'react'
|
||||
|
||||
const AnalyticsPage = () => {
|
||||
const { query } = useRouter()
|
||||
return (
|
||||
<TypebotContext typebotId={query.id?.toString()}>
|
||||
<Seo title="Analytics" />
|
||||
<Flex overflow="hidden" h="100vh" flexDir="column">
|
||||
<TypebotHeader />
|
||||
<ResultsContent />
|
||||
</Flex>
|
||||
</TypebotContext>
|
||||
)
|
||||
}
|
||||
|
||||
export default withAuth(AnalyticsPage)
|
@ -1,4 +1,11 @@
|
||||
import { PublicTypebot, Typebot } from 'bot-engine'
|
||||
import {
|
||||
Block,
|
||||
InputStep,
|
||||
PublicTypebot,
|
||||
Step,
|
||||
StepType,
|
||||
Typebot,
|
||||
} from 'bot-engine'
|
||||
import { sendRequest } from './utils'
|
||||
import shortId from 'short-uuid'
|
||||
|
||||
@ -33,3 +40,18 @@ export const updatePublishedTypebot = async (
|
||||
method: 'PUT',
|
||||
body: typebot,
|
||||
})
|
||||
|
||||
export const parseSubmissionsColumns = (
|
||||
typebot?: PublicTypebot
|
||||
): {
|
||||
Header: string
|
||||
accessor: string
|
||||
}[] =>
|
||||
(typebot?.blocks ?? [])
|
||||
.filter(blockContainsInput)
|
||||
.map((block) => ({ Header: block.title, accessor: block.id }))
|
||||
|
||||
const blockContainsInput = (block: Block) => block.steps.some(stepIsInput)
|
||||
|
||||
const stepIsInput = (step: Step): step is InputStep =>
|
||||
step.type === StepType.TEXT_INPUT
|
||||
|
12
yarn.lock
12
yarn.lock
@ -1467,6 +1467,13 @@
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-table@^7.7.9":
|
||||
version "7.7.9"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-table/-/react-table-7.7.9.tgz#ea82875775fc6ee71a28408dcc039396ae067c92"
|
||||
integrity sha512-ejP/J20Zlj9VmuLh73YgYkW2xOSFTW39G43rPH93M4mYWdMmqv66lCCr+axZpkdtlNLGjvMG2CwzT4S6abaeGQ==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-transition-group@^4.4.4":
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.4.tgz#acd4cceaa2be6b757db61ed7b432e103242d163e"
|
||||
@ -6110,6 +6117,11 @@ react-style-singleton@^2.1.0:
|
||||
invariant "^2.2.4"
|
||||
tslib "^1.0.0"
|
||||
|
||||
react-table@^7.7.0:
|
||||
version "7.7.0"
|
||||
resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.7.0.tgz#e2ce14d7fe3a559f7444e9ecfe8231ea8373f912"
|
||||
integrity sha512-jBlj70iBwOTvvImsU9t01LjFjy4sXEtclBovl3mTiqjz23Reu0DKnRza4zlLtOPACx6j2/7MrQIthIK1Wi+LIA==
|
||||
|
||||
react-transition-group@^4.4.2:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470"
|
||||
|
Reference in New Issue
Block a user