portfolio/components/layouts/ArticleLayout.tsx

123 lines
4.8 KiB
TypeScript
Raw Normal View History

2023-02-17 22:33:59 +00:00
import React, {ReactNode} from 'react'
2023-03-07 20:53:27 +00:00
import * as process from 'process'
2022-12-06 12:54:34 +00:00
import Head from 'next/head'
2023-02-23 21:22:50 +00:00
import Link from 'next/link'
import {Container} from '@/components/Container'
2023-02-14 21:40:16 +00:00
import {Prose} from '@/components/ui/Prose'
import {Views} from '@/components/ui/Views'
2023-02-17 22:33:59 +00:00
import {ArrowDownIcon} from '@/components/icons/ArrowDownIcon'
import {formatDate} from '@/lib/formatDate'
2022-12-06 12:54:34 +00:00
2023-01-14 23:18:52 +00:00
type ArticleLayout = {
children?: ReactNode
isRssFeed: boolean
title: string
description: string
ogImage: string
date: string
2023-01-17 21:24:16 +00:00
slug: string
2023-01-14 23:18:52 +00:00
}
2023-03-07 20:53:27 +00:00
const isProd = process.env.NODE_ENV === 'production'
2022-12-06 12:54:34 +00:00
export function ArticleLayout({
children,
isRssFeed = false,
2023-01-14 19:31:05 +00:00
title,
description,
ogImage,
2023-01-17 21:24:16 +00:00
date,
slug
2023-01-14 23:18:52 +00:00
}: ArticleLayout) {
2022-12-06 12:54:34 +00:00
if (isRssFeed) {
return children
}
return (
<>
<Head>
2023-01-14 19:31:05 +00:00
<title>{`${title} - Ryan Freeman`}</title>
<meta name="description" content={description}/>
2022-12-06 12:54:34 +00:00
<meta
property="og:url"
2023-02-23 21:22:50 +00:00
content={`${process.env.NEXT_PUBLIC_SITE_URL}/writing/${slug}`}
2022-12-06 12:54:34 +00:00
/>
<meta
property="og:type"
content="website"
/>
<meta
property="og:title"
2023-01-14 19:31:05 +00:00
content={title}
2022-12-06 12:54:34 +00:00
/>
<meta
property="og:description"
2023-01-14 19:31:05 +00:00
content={description}
2022-12-06 12:54:34 +00:00
/>
2023-01-14 19:31:05 +00:00
{ogImage &&
2022-12-06 12:54:34 +00:00
<>
<meta
property="og:image"
2023-01-14 19:31:05 +00:00
content={ogImage}
2022-12-06 12:54:34 +00:00
/>
<meta
name="twitter:card"
content="summary_large_image"
/>
<meta
name="twitter:image"
2023-01-14 19:31:05 +00:00
content={ogImage}
2022-12-06 12:54:34 +00:00
/>
</>
}
<meta
property="twitter:domain"
content="ryanfreeman.dev"
/>
<meta
property="twitter:url"
2023-02-23 21:22:50 +00:00
content={`${process.env.NEXT_PUBLIC_SITE_URL}/writing/${slug}`}
2022-12-06 12:54:34 +00:00
/>
<meta
name="twitter:title"
2023-01-14 19:31:05 +00:00
content={title}
2022-12-06 12:54:34 +00:00
/>
<meta
name="twitter:description"
2023-01-14 19:31:05 +00:00
content={description}
2022-12-06 12:54:34 +00:00
/>
</Head>
<Container className="mt-16 lg:mt-32">
<div className="xl:relative">
<div className="mx-auto max-w-2xl">
2023-02-17 22:33:59 +00:00
<Link href="/writing" replace>
<button
type="button"
aria-label="Go back to articles"
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:mb-0 lg:-mt-2 xl:-top-1.5 xl:left-0 xl:mt-0"
>
<ArrowDownIcon
className="h-4 w-4 stroke-zinc-500 transition group-hover:stroke-zinc-700 dark:stroke-zinc-500 dark:group-hover:stroke-zinc-400 rotate-90"/>
</button>
</Link>
2022-12-06 12:54:34 +00:00
<article>
<header className="flex flex-col">
<h1 className="mt-6 text-4xl font-bold tracking-tight text-zinc-800 dark:text-zinc-100 sm:text-5xl">
2023-01-14 19:31:05 +00:00
{title}
2022-12-06 12:54:34 +00:00
</h1>
2023-01-17 21:24:16 +00:00
<p className="order-first text-base text-zinc-500 dark:text-zinc-400">
<time dateTime={date}>
<span>{formatDate(date)}</span>
</time>
2023-03-07 20:53:27 +00:00
<Views slug={slug} shouldUpdateViews={isProd}/>
2023-01-17 21:24:16 +00:00
</p>
2022-12-06 12:54:34 +00:00
</header>
<Prose className="mt-8">{children}</Prose>
</article>
</div>
</div>
</Container>
</>
)
}