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 (

{label}

{'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.author} {author.position}
) })}
)}
{/* Content */}
{blogMetaData.youtubeHero ? (