import dayjs from 'dayjs'
import { ChevronLeft } from 'lucide-react'
import Image from 'next/image'
import Link from 'next/link'
import ReactMarkdown from 'react-markdown'
import type { PostReturnType, ProcessedBlogData, StaticAuthor, Tag } from 'types/post'
import { Badge } from 'ui'
import DraftModeBanner from '@/components/Blog/DraftModeBanner'
import ShareArticleActions from '@/components/Blog/ShareArticleActions'
import CTABanner from '@/components/CTABanner'
import BlogLinks from '@/components/LaunchWeek/7/BlogLinks'
import LW11Summary from '@/components/LaunchWeek/11/LW11Summary'
import LW12Summary from '@/components/LaunchWeek/12/LWSummary'
import LW13Summary from '@/components/LaunchWeek/13/Releases/LWSummary'
import LW14Summary from '@/components/LaunchWeek/14/Releases/LWSummary'
import LW15Summary from '@/components/LaunchWeek/15/LWSummary'
import LWXSummary from '@/components/LaunchWeek/X/LWXSummary'
import DefaultLayout from '@/components/Layouts/Default'
import { BLOG_POST_HERO_IMAGE_SIZES, getBlogThumbnailImage } from '@/lib/blog-images'
import { compileBlogMdx } from '@/lib/mdx/compileBlogMdx'
import mdxComponents from '@/lib/mdx/mdxComponents'
type NextCardProps = {
post: { path: string; title: string; formattedDate: string }
label: string
className?: string
}
const NextCard = (props: NextCardProps) => {
const { post, label, className } = props
return (
{'title' in post && (
{(post as { title?: string }).title}
)}
{'formattedDate' in post && (
{(post as { formattedDate?: string }).formattedDate}
)}
)
}
const BlogPostRenderer = async ({
blog,
blogMetaData,
isDraftMode,
prevPost,
nextPost,
authors,
}: {
blog: ProcessedBlogData
blogMetaData: ProcessedBlogData
isDraftMode: boolean
prevPost?: PostReturnType | null
nextPost?: PostReturnType | null
authors: Array
}) => {
const mdxRendered = await compileBlogMdx(blog.content as string, mdxComponents('blog'))
const isLaunchWeek7 = blogMetaData.launchweek === '7'
const isLaunchWeekX = blogMetaData.launchweek?.toString().toLocaleLowerCase() === 'x'
const isGAWeek = blogMetaData.launchweek?.toString().toLocaleLowerCase() === '11'
const isLaunchWeek12 = blogMetaData.launchweek?.toString().toLocaleLowerCase() === '12'
const isLaunchWeek13 = blogMetaData.launchweek?.toString().toLocaleLowerCase() === '13'
const isLaunchWeek14 = blogMetaData.launchweek?.toString().toLocaleLowerCase() === '14'
const isLaunchWeek15 = blogMetaData.launchweek?.toString().toLocaleLowerCase() === '15'
const toc = blogMetaData.toc && (
On this page
{blogMetaData.toc && (
{typeof blogMetaData.toc === 'string'
? (blogMetaData.toc as string)
: (blogMetaData.toc as { content: string }).content}
)}
)
const imageUrl = getBlogThumbnailImage(blogMetaData, {
fallbackToPlaceholder: false,
})
return (
<>
{isDraftMode && }
{/* Back button */}
Back
{/* Title and description */}
Blog
{blogMetaData.title}
{dayjs(blogMetaData.date).format('DD MMM YYYY')}
ยท
{(blogMetaData as any).readingTime}
{authors.length > 0 && (
{authors.map((author, i: number) => {
const authorImageUrl = author.author_image_url
const authorId =
(author as any).author_id ||
(author as any).username ||
author.author.toLowerCase().replace(/\s+/g, '_')
return (
{authorImageUrl && (
)}
{author.author}
{author.position}
)
})}
)}
{/* Content */}
{blogMetaData.youtubeHero ? (
) : (
imageUrl && (
)
)}
{mdxRendered}
{isLaunchWeek7 &&
}
{isLaunchWeekX &&
}
{isGAWeek &&
}
{isLaunchWeek12 &&
}
{isLaunchWeek13 &&
}
{isLaunchWeek14 &&
}
{isLaunchWeek15 &&
}
{prevPost && (
)}
{nextPost && (
)}
{/* Sidebar */}
{(blogMetaData.tags as Array)?.map((tag) => {
const tagName = typeof tag === 'string' ? tag : tag.name
const tagId = typeof tag === 'string' ? tag : tag.id.toString()
return (
{tagName}
)
})}
{toc}
>
)
}
export default BlogPostRenderer