2
0

chore(lp): 📦️ Import existing Landing page

This commit is contained in:
Baptiste Arnaud
2022-02-09 18:40:40 +01:00
parent 65b30bfc48
commit 36be3577e1
136 changed files with 14867 additions and 20 deletions

View File

@ -0,0 +1,202 @@
import { GetStaticPropsContext } from 'next'
import { NotionBlock, NotionText } from 'notion-blocks-chakra-ui'
import React from 'react'
import { getPage, getBlocks, getFullDatabase } from '../../lib/notion'
import Image from 'next/image'
import {
Stack,
Container,
Button,
VStack,
Heading,
HStack,
Text,
} from '@chakra-ui/react'
import {
Page,
Block,
TitlePropertyValue,
RichTextPropertyValue,
CheckboxPropertyValue,
} from '@notionhq/client/build/src/api-types'
import { Footer } from 'components/common/Footer'
import { Navbar } from 'components/common/Navbar/Navbar'
import { NextChakraLink } from 'components/common/nextChakraAdapters/NextChakraLink'
import { SocialMetaTags } from 'components/common/SocialMetaTags'
export default function Post({
page,
blocks,
}: {
page: Page
blocks: Block[]
}) {
return (
<>
<Stack
alignItems="center"
w="full"
overflowX="hidden"
pb={20}
minH="calc(100vh - 267px)"
spacing={10}
>
{page && (
<SocialMetaTags
title={
(page.properties.Name as TitlePropertyValue).title[0]?.plain_text
}
description={
(page.properties.Description as RichTextPropertyValue)
.rich_text[0]?.plain_text
}
currentUrl={`https://www.typebot.io/blog/${
(page.properties.Slug as RichTextPropertyValue).rich_text[0]
?.plain_text
}`}
imagePreviewUrl={
(page.properties.Thumbnail as RichTextPropertyValue).rich_text[0]
?.plain_text
}
/>
)}
<Navbar />
<Container as="article" maxW="900px">
{((page?.properties?.Published as CheckboxPropertyValue | undefined)
?.checkbox ||
!page) && (
<Button
as={NextChakraLink}
href="/blog"
colorScheme="gray"
variant="outline"
size="sm"
>
{'<'} Blog
</Button>
)}
{page ? (
<>
<VStack>
<Heading as="h1" fontSize="5xl" textAlign="center" mt={6}>
<NotionText
text={(page.properties.Name as TitlePropertyValue).title}
/>
</Heading>
<Heading
fontSize="md"
fontWeight="normal"
textAlign="center"
textColor="gray.500"
>
<NotionText
text={
(page.properties.Description as RichTextPropertyValue)
.rich_text
}
/>
</Heading>
{(page.properties.Author as RichTextPropertyValue | undefined)
?.rich_text[0]?.plain_text && (
<Author
author={
(page.properties.Author as RichTextPropertyValue)
.rich_text[0]?.plain_text
}
/>
)}
</VStack>
<Stack mt={6} spacing={4} maxW="700px" mx="auto">
{blocks.map((block) => (
<NotionBlock key={block.id} block={block} />
))}
</Stack>
</>
) : (
<Text textAlign="center">Blog post not found</Text>
)}
</Container>
</Stack>
<Footer />
</>
)
}
export const getStaticPaths = async () => {
if (!process.env.NOTION_DATABASE_ID)
throw new Error("Couldn't find NOTION_DATABASE_ID")
const database = await getFullDatabase(process.env.NOTION_DATABASE_ID)
return {
paths: database.filter(pageWithSlugAndId).map((page) => ({
params: {
slug: (page.properties.Slug as RichTextPropertyValue).rich_text[0]
.plain_text,
id: page.id,
},
})),
fallback: true,
}
}
const pageWithSlugAndId = (page: Page) =>
(page.properties.Slug as RichTextPropertyValue).rich_text[0]?.plain_text &&
page.id
const Author = ({ author }: { author: string }) => {
return (
<HStack>
<Image
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
src={/\(([^)]+)\)/.exec(author)![0].slice(1, -1)}
width="30px"
height="30px"
className="rounded-full"
alt="Author's picture"
/>
<Text>{author.split(' (')[0]}</Text>
</HStack>
)
}
export const getStaticProps = async (
context: GetStaticPropsContext<{ slug: string; locale: 'fr' | 'en' }>
) => {
if (!process.env.NOTION_DATABASE_ID)
throw new Error("Couldn't find NOTION_DATABASE_ID")
if (!context.params) throw new Error("Couldn't find params")
const { slug } = context.params
const page = await getPage(process.env.NOTION_DATABASE_ID, slug)
if (!page?.id) return
const blocks = await getBlocks(page?.id)
const childBlocks = await Promise.all(
blocks
.filter((block) => block.has_children)
.map(async (block) => {
return {
id: block.id,
children: await getBlocks(block.id),
}
})
)
const blocksWithChildren = blocks.map((block) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
if (block.has_children && !block[block.type].children) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
block[block.type]['children'] = childBlocks.find(
(x) => x.id === block.id
)?.children
}
return block
})
return {
props: {
page,
blocks: blocksWithChildren,
},
revalidate: 1,
}
}

View File

@ -0,0 +1,155 @@
import React from 'react'
import {
Box,
Heading,
Image,
Text,
Container,
VStack,
SimpleGrid,
Flex,
} from '@chakra-ui/react'
import { getDatabase } from '../../lib/notion'
import {
DatePropertyValue,
Page,
RichText,
RichTextPropertyValue,
TitlePropertyValue,
} from '@notionhq/client/build/src/api-types'
import { NotionText } from 'notion-blocks-chakra-ui'
import { Footer } from 'components/common/Footer'
import { Navbar } from 'components/common/Navbar/Navbar'
import { NextChakraLink } from 'components/common/nextChakraAdapters/NextChakraLink'
import { SocialMetaTags } from 'components/common/SocialMetaTags'
const ArticleList = ({ posts }: { posts: Page[] }) => {
return (
<>
<Flex
alignItems="center"
justifyContent="space-between"
w="full"
flexDir="column"
>
<SocialMetaTags
title="Blog"
description="Keep up to date with the latest news related to Typebot. Learn
about conversationnal forms and how to convert more."
currentUrl={`https://www.typebot.io/blog`}
imagePreviewUrl={`https://www.typebot.io/images/previews/blog.png`}
/>
<Navbar />
<VStack maxW="1200px" mt={20} pb={56}>
<VStack maxW="700px">
<Heading as="h1" fontSize="5xl">
Blog
</Heading>
<Heading
fontSize="md"
fontWeight="normal"
textAlign="center"
textColor="gray.500"
>
Keep up to date with the latest news related to Typebot. Learn
about conversationnal forms and how to convert more.
</Heading>
</VStack>
<Container maxW="1200px">
<SimpleGrid columns={[1, 2, 3]} mt={6} py={4} spacing={10}>
{posts.map((post) => (
<BlogPost
key={post.id}
slug={`/${
(post.properties.Slug as RichTextPropertyValue).rich_text[0]
?.plain_text
}`}
title={
(post.properties.Name as TitlePropertyValue).title[0]
?.plain_text
}
description={
(post.properties.Description as RichTextPropertyValue)
.rich_text
}
imageSrc={
(post.properties.Thumbnail as RichTextPropertyValue)
.rich_text[0]?.plain_text
}
date={
new Date(
(post.properties.Created as DatePropertyValue)?.date
?.start ?? ''
)
}
/>
))}
</SimpleGrid>
</Container>
</VStack>
</Flex>
<Footer />
</>
)
}
type BlogPostProps = {
slug: string
title: string
description: RichText[]
imageSrc: string
date: Date
}
const BlogPost = ({
slug,
title,
description,
imageSrc,
date,
}: BlogPostProps) => (
<NextChakraLink
href={'/blog' + slug}
w="100%"
shadow="lg"
p={4}
rounded="lg"
_hover={{ textDecoration: 'none' }}
>
<Box borderRadius="lg" overflow="hidden">
<Image
transform="scale(1.0)"
src={imageSrc}
objectFit="contain"
width="100%"
transition="0.3s ease-in-out"
_hover={{
transform: 'scale(1.05)',
}}
alt="title thumbnail"
/>
</Box>
<Heading fontSize="xl" marginTop="4">
{title}
</Heading>
<NotionText text={description} as="p" fontSize="md" marginTop="2" />
<Text textColor="gray.400" fontSize="sm" mt={2}>
{date.toDateString()}
</Text>
</NextChakraLink>
)
export const getStaticProps = async () => {
if (!process.env.NOTION_DATABASE_ID)
throw new Error("Couldn't find NOTION_DATABASE_ID")
const database = await getDatabase(process.env.NOTION_DATABASE_ID)
return {
props: {
posts: database,
},
revalidate: 1,
}
}
export default ArticleList