({
post,
views,
reactions,
relatedViews,
}: {
post: PostDetail
views?: number
reactions?: number[]
relatedViews: number[]
})
| 28 | import { BlogPostTableOfContents } from './BlogPostTableOfContents' |
| 29 | |
| 30 | export function BlogPostPage({ |
| 31 | post, |
| 32 | views, |
| 33 | reactions, |
| 34 | relatedViews, |
| 35 | }: { |
| 36 | post: PostDetail |
| 37 | views?: number |
| 38 | reactions?: number[] |
| 39 | relatedViews: number[] |
| 40 | }) { |
| 41 | return ( |
| 42 | <Container className="mt-16 lg:mt-32"> |
| 43 | <div className="w-full md:flex md:justify-between xl:relative"> |
| 44 | <aside className="hidden w-[160px] shrink-0 lg:block"> |
| 45 | <div className="sticky top-2 pt-20"> |
| 46 | <BlogPostTableOfContents headings={post.headings} /> |
| 47 | </div> |
| 48 | </aside> |
| 49 | <div className="max-w-2xl md:flex-1 md:shrink-0"> |
| 50 | <Button |
| 51 | href="/blog" |
| 52 | variant="secondary" |
| 53 | aria-label="返回博客页面" |
| 54 | className="group mb-8 flex h-10 w-10 items-center justify-center rounded-full bg-white shadow-md shadow-zinc-800/5 ring-1 ring-zinc-900/5 transition dark:border dark:border-zinc-700/50 dark:bg-zinc-800 dark:ring-0 dark:ring-white/10 dark:hover:border-zinc-700 dark:hover:ring-white/20 lg:absolute lg:-left-5 lg:-mt-2 lg:mb-0 xl:-top-1.5 xl:left-0 xl:mt-0" |
| 55 | > |
| 56 | <UTurnLeftIcon className="h-8 w-8 stroke-zinc-500 transition group-hover:stroke-zinc-700 dark:stroke-zinc-500 dark:group-hover:stroke-zinc-400" /> |
| 57 | </Button> |
| 58 | <article data-postid={post._id}> |
| 59 | <header className="relative flex flex-col items-center pb-5 after:absolute after:-bottom-1 after:block after:h-px after:w-full after:rounded after:bg-gradient-to-r after:from-zinc-400/20 after:via-zinc-200/10 after:to-transparent dark:after:from-zinc-600/20 dark:after:via-zinc-700/10"> |
| 60 | <motion.div |
| 61 | className="relative mb-7 aspect-[240/135] w-full md:mb-12 md:w-[120%]" |
| 62 | initial={{ opacity: 0, scale: 0.96, y: 10 }} |
| 63 | animate={{ opacity: 1, scale: 1, y: 0 }} |
| 64 | transition={{ |
| 65 | duration: 0.35, |
| 66 | type: 'spring', |
| 67 | stiffness: 120, |
| 68 | damping: 20, |
| 69 | }} |
| 70 | > |
| 71 | <div className="absolute z-0 hidden aspect-[240/135] w-full blur-xl saturate-150 after:absolute after:inset-0 after:hidden after:bg-white/50 dark:after:bg-black/50 md:block md:after:block"> |
| 72 | <Image |
| 73 | src={post.mainImage.asset.url} |
| 74 | alt="" |
| 75 | className="select-none" |
| 76 | unoptimized |
| 77 | fill |
| 78 | aria-hidden={true} |
| 79 | /> |
| 80 | </div> |
| 81 | <Image |
| 82 | src={post.mainImage.asset.url} |
| 83 | alt={post.title} |
| 84 | className="select-none rounded-2xl ring-1 ring-zinc-900/5 transition dark:ring-0 dark:ring-white/10 dark:hover:border-zinc-700 dark:hover:ring-white/20 md:rounded-3xl" |
| 85 | placeholder="blur" |
| 86 | blurDataURL={post.mainImage.asset.lqip} |
| 87 | unoptimized |
nothing calls this directly
no test coverage detected