import dayjs from 'dayjs' import { ArrowLeft } 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 { CTASection } from '@/app/(home)/_components/CTASection' import DraftModeBanner from '@/components/Blog/DraftModeBanner' import ShareArticleActions from '@/components/Blog/ShareArticleActions' 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 { 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 && }
{/* Row 1, Col 1: Back button */}
Blog
{/* Row 1, Col 2: Title + meta */}
{(blogMetaData.tags as Tag[])?.length > 0 && (
{(blogMetaData.tags as Tag[])?.map((tag) => { const tagName = typeof tag === 'string' ? tag : tag.name const tagId = typeof tag === 'string' ? tag : tag.id.toString() return ( {tagName} ) })}
)}

{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}
) })}
)}
{/* Row 2: Hero image — col-start-1 col-span-9 = equal overhang each side of content (col 2–8) */} {!blogMetaData.youtubeHero && blogMetaData.imgThumb && imageUrl && (
{blogMetaData.title}
)} {/* Row 3: Article */}
{blogMetaData.youtubeHero ? (