-
Notifications
You must be signed in to change notification settings - Fork 0
/
[slug].js
129 lines (122 loc) · 4.78 KB
/
[slug].js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { getGlobalData } from '../../utils/global-data';
import {
getNextPostBySlug,
getPostBySlug,
getPreviousPostBySlug,
postFilePaths,
} from '../../utils/mdx-utils';
import { MDXRemote } from 'next-mdx-remote';
import Head from 'next/head';
import Link from 'next/link';
import ArrowIcon from '../../components/ArrowIcon';
import CustomLink from '../../components/CustomLink';
import Footer from '../../components/Footer';
import Header from '../../components/Header';
import Layout, { GradientBackground } from '../../components/Layout';
import SEO from '../../components/SEO';
// Custom components/renderers to pass to MDX.
// Since the MDX files aren't loaded by webpack, they have no knowledge of how
// to handle import statements. Instead, you must include components in scope
// here.
const components = {
a: CustomLink,
// It also works with dynamically-imported components, which is especially
// useful for conditionally loading components for certain routes.
// See the notes in README.md for more details.
Head,
};
export default function PostPage({
source,
frontMatter,
prevPost,
nextPost,
globalData,
}) {
return (
<Layout>
<SEO
title={`${frontMatter.title} - ${globalData.name}`}
description={frontMatter.description}
/>
<Header name={globalData.name} />
<article className="px-6 md:px-0">
<header>
<h1 className="text-3xl md:text-5xl dark:text-white text-center mb-12">
{frontMatter.title}
</h1>
{frontMatter.description && (
<p className="text-xl mb-4">{frontMatter.description}</p>
)}
</header>
<main>
<article className="prose dark:prose-dark">
<MDXRemote {...source} components={components} />
</article>
</main>
<div className="grid md:grid-cols-2 lg:-mx-24 mt-12">
{prevPost && (
<Link href={`/posts/${prevPost.slug}`}>
<a className="py-8 px-10 text-center md:text-right first:rounded-t-lg md:first:rounded-tr-none md:first:rounded-l-lg last:rounded-r-lg first last:rounded-b-lg backdrop-blur-lg bg-white dark:bg-black dark:bg-opacity-30 bg-opacity-10 hover:bg-opacity-20 dark:hover:bg-opacity-50 transition border border-gray-800 dark:border-white border-opacity-10 dark:border-opacity-10 last:border-t md:border-r-0 md:last:border-r md:last:rounded-r-none flex flex-col">
<p className="uppercase text-gray-500 mb-4 dark:text-white dark:opacity-60">
Previous
</p>
<h4 className="text-2xl text-gray-700 mb-6 dark:text-white">
{prevPost.title}
</h4>
<ArrowIcon className="transform rotate-180 mx-auto md:mr-0 mt-auto" />
</a>
</Link>
)}
{nextPost && (
<Link href={`/posts/${nextPost.slug}`}>
<a className="py-8 px-10 text-center md:text-left md:first:rounded-t-lg last:rounded-b-lg first:rounded-l-lg md:last:rounded-bl-none md:last:rounded-r-lg backdrop-blur-lg bg-white dark:bg-black dark:bg-opacity-30 bg-opacity-10 hover:bg-opacity-20 dark:hover:bg-opacity-50 transition border border-gray-800 dark:border-white border-opacity-10 dark:border-opacity-10 border-t-0 first:border-t first:rounded-t-lg md:border-t border-b-0 last:border-b flex flex-col">
<p className="uppercase text-gray-500 mb-4 dark:text-white dark:opacity-60">
Next
</p>
<h4 className="text-2xl text-gray-700 mb-6 dark:text-white">
{nextPost.title}
</h4>
<ArrowIcon className="mt-auto mx-auto md:ml-0" />
</a>
</Link>
)}
</div>
</article>
<Footer copyrightText={globalData.footerText} />
<GradientBackground
variant="large"
className="absolute -top-32 opacity-30 dark:opacity-50"
/>
<GradientBackground
variant="small"
className="absolute bottom-0 opacity-20 dark:opacity-10"
/>
</Layout>
);
}
export const getStaticProps = async ({ params }) => {
const globalData = getGlobalData();
const { mdxSource, data } = await getPostBySlug(params.slug);
const prevPost = getPreviousPostBySlug(params.slug);
const nextPost = getNextPostBySlug(params.slug);
return {
props: {
globalData,
source: mdxSource,
frontMatter: data,
prevPost,
nextPost,
},
};
};
export const getStaticPaths = async () => {
const paths = postFilePaths
// Remove file extensions for page paths
.map((path) => path.replace(/\.mdx?$/, ''))
// Map the path into the static paths object required by Next.js
.map((slug) => ({ params: { slug } }));
return {
paths,
fallback: false,
};
};