({ params }: PostPageProps)
| 84 | } |
| 85 | |
| 86 | export default async function PostPage({ params }: PostPageProps) { |
| 87 | const post = await getPostFromParams(params) |
| 88 | |
| 89 | if (!post) { |
| 90 | notFound() |
| 91 | } |
| 92 | |
| 93 | const authors = post.authors.map((author) => |
| 94 | allAuthors.find(({ slug }) => slug === `/authors/${author}`) |
| 95 | ) |
| 96 | |
| 97 | return ( |
| 98 | <article className="container relative max-w-3xl py-6 lg:py-10"> |
| 99 | <Link |
| 100 | href="/blog" |
| 101 | className={cn( |
| 102 | buttonVariants({ variant: "ghost" }), |
| 103 | "absolute left-[-200px] top-14 hidden xl:inline-flex" |
| 104 | )} |
| 105 | > |
| 106 | <Icons.chevronLeft className="mr-2 h-4 w-4" /> |
| 107 | See all posts |
| 108 | </Link> |
| 109 | <div> |
| 110 | {post.date && ( |
| 111 | <time |
| 112 | dateTime={post.date} |
| 113 | className="block text-sm text-muted-foreground" |
| 114 | > |
| 115 | Published on {formatDate(post.date)} |
| 116 | </time> |
| 117 | )} |
| 118 | <h1 className="mt-2 inline-block font-heading text-4xl leading-tight lg:text-5xl"> |
| 119 | {post.title} |
| 120 | </h1> |
| 121 | {authors?.length ? ( |
| 122 | <div className="mt-4 flex space-x-4"> |
| 123 | {authors.map((author) => |
| 124 | author ? ( |
| 125 | <Link |
| 126 | key={author._id} |
| 127 | href={`https://twitter.com/${author.twitter}`} |
| 128 | className="flex items-center space-x-2 text-sm" |
| 129 | > |
| 130 | <Image |
| 131 | src={author.avatar} |
| 132 | alt={author.title} |
| 133 | width={42} |
| 134 | height={42} |
| 135 | className="rounded-full bg-white" |
| 136 | /> |
| 137 | <div className="flex-1 text-left leading-tight"> |
| 138 | <p className="font-medium">{author.title}</p> |
| 139 | <p className="text-[12px] text-muted-foreground"> |
| 140 | @{author.twitter} |
| 141 | </p> |
| 142 | </div> |
| 143 | </Link> |
nothing calls this directly
no test coverage detected