📝 Improve blog capabilities and components
This commit is contained in:
@@ -1,9 +1,29 @@
|
||||
/* eslint-disable jsx-a11y/alt-text */
|
||||
'use client'
|
||||
|
||||
import { Link } from '@chakra-ui/next-js'
|
||||
import { Heading, Stack, Text } from '@chakra-ui/react'
|
||||
import {
|
||||
Alert,
|
||||
AlertIcon,
|
||||
Heading,
|
||||
Stack,
|
||||
Table,
|
||||
TableCaption,
|
||||
TableContainer,
|
||||
Tbody,
|
||||
Td,
|
||||
Text,
|
||||
Tfoot,
|
||||
Th,
|
||||
Thead,
|
||||
Tr,
|
||||
Image,
|
||||
} from '@chakra-ui/react'
|
||||
import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote'
|
||||
import { highlight } from 'sugar-high'
|
||||
import { Tweet } from './Tweet'
|
||||
import { Standard } from '@typebot.io/nextjs'
|
||||
import { EndCta } from '@/components/Homepage/EndCta'
|
||||
|
||||
type Props = {
|
||||
metadata: {
|
||||
@@ -14,7 +34,7 @@ type Props = {
|
||||
}
|
||||
|
||||
export const Post = ({ metadata, mdxSource }: Props) => (
|
||||
<Stack spacing={10} my="20">
|
||||
<Stack spacing={10} my="20" w="full">
|
||||
<Stack mx="auto" w="full" maxW="65ch">
|
||||
<Heading>{metadata.title}</Heading>
|
||||
<Text>{formatDate(metadata.publishedAt)}</Text>
|
||||
@@ -23,7 +43,7 @@ export const Post = ({ metadata, mdxSource }: Props) => (
|
||||
mx="auto"
|
||||
spacing={0}
|
||||
as="article"
|
||||
className="prose prose-quoteless prose-neutral prose-invert"
|
||||
className="prose prose-quoteless prose-neutral prose-invert max-w-none w-full px-3 sm:px-0"
|
||||
>
|
||||
<MDXRemote
|
||||
{...mdxSource}
|
||||
@@ -42,6 +62,87 @@ export const Post = ({ metadata, mdxSource }: Props) => (
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
link: (props: any) => <Link {...props} />,
|
||||
Image: (props) => (
|
||||
<Image rounded="md" maxW={['full', '65ch']} {...props} />
|
||||
),
|
||||
Callout: ({ children, ...props }) => (
|
||||
<Alert rounded="md" {...props}>
|
||||
<AlertIcon />
|
||||
{children}
|
||||
</Alert>
|
||||
),
|
||||
Tweet,
|
||||
Typebot: Standard,
|
||||
Youtube: ({ id }: { id: string }) => (
|
||||
<div className="w-full">
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
paddingBottom: '64.63195691202873%',
|
||||
height: 0,
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<iframe
|
||||
src={`https://www.youtube.com/embed/${id}`}
|
||||
allowFullScreen
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
}}
|
||||
></iframe>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
Loom: ({ id }: { id: string }) => (
|
||||
<div className="w-full">
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
paddingBottom: '64.63195691202873%',
|
||||
height: 0,
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<iframe
|
||||
src={`https://www.loom.com/embed/${id}`}
|
||||
allowFullScreen
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
}}
|
||||
></iframe>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
Cta: (props) => (
|
||||
<EndCta
|
||||
{...props}
|
||||
style={{ maxWidth: 'none' }}
|
||||
w="full"
|
||||
height="70vh"
|
||||
className="w-full"
|
||||
bgGradient={undefined}
|
||||
/>
|
||||
),
|
||||
table: (props) => (
|
||||
<TableContainer>
|
||||
<Table {...props} />
|
||||
</TableContainer>
|
||||
),
|
||||
thead: Thead,
|
||||
tbody: Tbody,
|
||||
th: Th,
|
||||
td: Td,
|
||||
tfoot: Tfoot,
|
||||
tr: Tr,
|
||||
caption: TableCaption,
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
36
apps/landing-page/app/blog/[slug]/Tweet.tsx
Normal file
36
apps/landing-page/app/blog/[slug]/Tweet.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import { getTweet } from 'react-tweet/api'
|
||||
import { EmbeddedTweet, TweetNotFound, type TweetProps } from 'react-tweet'
|
||||
import './tweet.css'
|
||||
|
||||
const TweetContent = async ({ id, components, onError }: TweetProps) => {
|
||||
let error
|
||||
const tweet = id
|
||||
? await getTweet(id).catch((err) => {
|
||||
if (onError) {
|
||||
error = onError(err)
|
||||
} else {
|
||||
console.error(err)
|
||||
error = err
|
||||
}
|
||||
})
|
||||
: undefined
|
||||
|
||||
if (!tweet) {
|
||||
const NotFound = components?.TweetNotFound || TweetNotFound
|
||||
return <NotFound error={error} />
|
||||
}
|
||||
|
||||
return <EmbeddedTweet tweet={tweet} components={components} />
|
||||
}
|
||||
|
||||
export const ReactTweet = (props: TweetProps) => <TweetContent {...props} />
|
||||
|
||||
export async function Tweet({ id }: { id: string }) {
|
||||
return (
|
||||
<div className="tweet my-6">
|
||||
<div className={`flex justify-center`}>
|
||||
<ReactTweet id={id} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
63
apps/landing-page/app/blog/[slug]/tweet.css
Normal file
63
apps/landing-page/app/blog/[slug]/tweet.css
Normal file
@@ -0,0 +1,63 @@
|
||||
/* Light theme (default) */
|
||||
.tweet .react-tweet-theme {
|
||||
/* margin is handled by our wrappers */
|
||||
--tweet-container-margin: 0;
|
||||
--tweet-font-family: inherit;
|
||||
--tweet-font-color: inherit;
|
||||
|
||||
--tweet-bg-color: #222;
|
||||
--tweet-bg-color-hover: var(--tweet-bg-color);
|
||||
--tweet-quoted-bg-color-hover: rgba(255, 255, 255, 0.03);
|
||||
--tweet-border: 1px solid #333;
|
||||
--tweet-color-blue-secondary: theme('colors.white');
|
||||
--tweet-color-blue-secondary-hover: #333;
|
||||
--tweet-font-color-secondary: theme('colors.gray.400');
|
||||
|
||||
/* Common properties for both themes */
|
||||
--tweet-quoted-bg-color-hover: rgba(0, 0, 0, 0.03);
|
||||
--tweet-border: 1px solid rgb(64, 64, 64);
|
||||
--tweet-skeleton-gradient: linear-gradient(
|
||||
270deg,
|
||||
#fafafa,
|
||||
#eaeaea,
|
||||
#eaeaea,
|
||||
#fafafa
|
||||
);
|
||||
--tweet-color-red-primary: rgb(249, 24, 128);
|
||||
--tweet-color-red-primary-hover: rgba(249, 24, 128, 0.1);
|
||||
--tweet-color-green-primary: rgb(0, 186, 124);
|
||||
--tweet-color-green-primary-hover: rgba(0, 186, 124, 0.1);
|
||||
--tweet-twitter-icon-color: var(--tweet-font-color);
|
||||
--tweet-verified-old-color: rgb(130, 154, 171);
|
||||
--tweet-verified-blue-color: var(--tweet-color-blue-primary);
|
||||
|
||||
--tweet-actions-font-weight: 500;
|
||||
--tweet-replies-font-weight: 500;
|
||||
}
|
||||
|
||||
/* Common styles for both themes */
|
||||
.tweet .react-tweet-theme p {
|
||||
font-size: inherit;
|
||||
line-height: 1.3rem;
|
||||
}
|
||||
|
||||
.tweet .react-tweet-theme p a {
|
||||
@apply border-b transition-[border-color] border-gray-500 text-white hover:border-white;
|
||||
}
|
||||
|
||||
/* Remove link underline on hover for both themes */
|
||||
.tweet .react-tweet-theme p a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.tweet a div {
|
||||
@apply font-medium tracking-tight;
|
||||
}
|
||||
|
||||
.tweet div[class*='mediaWrapper'] {
|
||||
max-height: 250px;
|
||||
}
|
||||
|
||||
.tweet .react-tweet-theme img {
|
||||
margin: 0;
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import type { Metadata } from 'next'
|
||||
import { Header } from 'components/common/Header/Header'
|
||||
import { Footer } from 'components/common/Footer'
|
||||
import { Providers } from './providers'
|
||||
import { EndCta } from '@/components/Homepage/EndCta'
|
||||
import 'assets/style.css'
|
||||
|
||||
export const metadata: Metadata = {
|
||||
@@ -33,7 +32,6 @@ export default function RootLayout({
|
||||
<Providers>
|
||||
<Header />
|
||||
{children}
|
||||
<EndCta />
|
||||
<Footer />
|
||||
</Providers>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user