2
0

🦴 Add results backbone

This commit is contained in:
Baptiste Arnaud
2021-12-24 10:08:41 +01:00
parent d369b4d941
commit 698867da5d
13 changed files with 232 additions and 2 deletions

View 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;
}

View File

@ -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>
)
}

View File

@ -0,0 +1 @@
export { SubmissionsTable } from './SubmissionsTable'

View File

@ -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'}
>

View File

@ -0,0 +1,5 @@
import React from 'react'
export const AnalyticsContent = () => {
return <>Hi</>
}

View 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>
)
}

View File

@ -0,0 +1,10 @@
import { SubmissionsTable } from 'components/results/SubmissionsTable'
import React from 'react'
export const SubmissionsContent = () => {
return (
<>
<SubmissionsTable />
</>
)
}

View File

@ -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",

View File

@ -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()

View 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)

View 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)

View File

@ -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