Skip to content

Commit ab7f619

Browse files
committed
Update guides
1 parent b2dfda9 commit ab7f619

6 files changed

Lines changed: 165 additions & 26 deletions

File tree

components/Main.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Component } from "react"
33
export default class Main extends Component<{className?: string, homePage?: true}> {
44
render() {
55
const classes =
6-
(!this.props.homePage ? "max-w-6xl w-full" : "") +
6+
(!this.props.homePage ? "max-w-4xl w-full" : "") +
77
(this.props.className ?? "")
88

99
return (

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"react": "17.0.2",
1616
"react-dom": "17.0.2",
1717
"react-markdown": "^7.1.1",
18+
"react-youtube": "^7.14.0",
1819
"sharp": "^0.29.3"
1920
},
2021
"devDependencies": {
Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,45 +10,37 @@ interface Props {
1010
guide: Guide
1111
}
1212

13-
export default function GuidePage({ guide, location }: Props & { location: string }) {
13+
export default function CategoryWebpage({ guide, location }: Props & { location: string }) {
1414
return (
1515
<Main>
1616
<Head>
1717
<title>{guide.name} | Hu Tao</title>
1818
<meta name="twitter:card" content="summary" />
1919
<meta property="og:title" content={`${guide.name} | Hu Tao`} />
20-
<meta property="og:description" content={`View ${guide.name} routes`} />
20+
<meta property="og:description" content={`View ${guide.name} guides`} />
2121
</Head>
2222
<h1 className="text-3xl font-bold">
2323
{guide.name}
2424
</h1>
2525
<ul>
26-
{guide.pages.map(p => (<li key={p.name} id={urlify(p.name, true)}>
27-
<FormattedLink href={`#${urlify(p.name, true)}`} location={location} font="semibold" size="2xl">
28-
<h2 className="text-2xl font-semibold">{p.name}</h2>
29-
</FormattedLink>
30-
<ReactMarkdown>{(p.desc?.replace(/ ?\$\{.*?\}/g, "") ?? "")}</ReactMarkdown>
31-
32-
{p.img && <ExternalImg src={p.img}/>}
26+
{guide.pages.map(p => (<li key={p.name} id={urlify(p.name, false)}>
27+
<h2 className="text-2xl font-semibold">
28+
<FormattedLink href={`${urlify(guide.name, false)}/${urlify(p.name, true)}`} location={location} font="semibold" size="2xl">
29+
{p.name}
30+
</FormattedLink>
31+
</h2>
3332
</li>))}
3433
</ul>
3534
</Main>
3635
)
3736
}
38-
function ExternalImg({ src }: {src: string}) {
39-
// eslint-disable-next-line @next/next/no-img-element
40-
return <FormattedLink href={src} target="_blank"><img className="p-1 relative max-w-2xl max-h-96" decoding="async" alt="Guide Image" src={src} /></FormattedLink>
41-
// return <div className="p-1 relative max-w-2xl">
42-
// <Image alt="Guide Image" src={src} width={825} height={963}/>
43-
// </div>
44-
}
4537

4638
export async function getStaticProps(context: GetStaticPropsContext): Promise<GetStaticPropsResult<Props>> {
47-
const guideName = context.params?.guide
39+
const categoryName = context.params?.category
4840
const data = await getGuides()
4941

50-
const guide = data?.find(g => urlify(g.name) == guideName)
51-
if (!data || !guide) {
42+
const category = data?.find(g => urlify(g.name, false) == categoryName)
43+
if (!data || !category) {
5244
return {
5345
notFound: true,
5446
revalidate: 5 * 60
@@ -57,7 +49,7 @@ export async function getStaticProps(context: GetStaticPropsContext): Promise<Ge
5749

5850
return {
5951
props: {
60-
guide
52+
guide: category
6153
},
6254
revalidate: 60 * 60
6355
}
@@ -67,7 +59,7 @@ export async function getStaticPaths(): Promise<GetStaticPathsResult> {
6759
const data = await getGuides()
6860
return {
6961
paths: data?.map(g => ({
70-
params: { guide: urlify(g.name) }
62+
params: { category: urlify(g.name, false) }
7163
})) ?? [],
7264
fallback: "blocking"
7365
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { GetStaticPathsResult, GetStaticPropsContext, GetStaticPropsResult } from "next"
2+
import Head from "next/head"
3+
import ReactMarkdown from "react-markdown"
4+
import FormattedLink from "../../../components/FormattedLink"
5+
import Main from "../../../components/Main"
6+
import { getGuides, urlify, yeetBrackets } from "../../../utils/data-cache"
7+
import { Guide, GuidePage } from "../../../utils/types"
8+
import YouTube from "react-youtube"
9+
10+
interface Props {
11+
guide: Guide
12+
pageNumber: number
13+
}
14+
15+
export default function GuideWebpage({ guide, pageNumber, location }: Props & { location: string }) {
16+
const page = guide.pages[pageNumber]
17+
const nextPage = guide.pages[pageNumber + 1]
18+
const prevPage = guide.pages[pageNumber - 1]
19+
20+
return (
21+
<Main>
22+
<Head>
23+
<title>{page.name} | Hu Tao</title>
24+
<meta name="twitter:card" content="summary" />
25+
<meta property="og:title" content={`${page.name} | Hu Tao`} />
26+
<meta property="og:description" content={`View ${page.name} guide`} />
27+
</Head>
28+
<h2 className="font-semibold">
29+
<FormattedLink href={`/guides/${urlify(guide.name, false)}`} location={location} font="semibold" size="lg">
30+
{guide.name}
31+
</FormattedLink>
32+
</h2>
33+
34+
<h1 className="text-3xl font-bold">
35+
{page.name}
36+
</h1>
37+
38+
<div className="flex justify-between text-base">
39+
<div className="px-1">
40+
{prevPage && <FormattedLink href={`/guides/${urlify(guide.name, false)}/${urlify(prevPage.name, true)}`} location={location} font="bold" size="lg">
41+
&larr; {yeetBrackets(prevPage.name)}
42+
</FormattedLink>}
43+
</div>
44+
45+
<div>
46+
{nextPage &&
47+
<FormattedLink href={`/guides/${urlify(guide.name, false)}/${urlify(nextPage.name, true)}`} location={location} font="bold" size="lg">
48+
{yeetBrackets(nextPage.name)} &rarr;
49+
</FormattedLink>}
50+
</div>
51+
</div>
52+
53+
<ul>
54+
<ReactMarkdown>{(page.desc?.replace(/ ?\$\{.*?\}/g, "") ?? "")}</ReactMarkdown>
55+
{page.img && <ExternalImg src={page.img} />}
56+
{page.url && page.url.startsWith("https://youtu.be/") && <div>
57+
<h2 className="text-xl font-semibold pt-1">Video:</h2>
58+
<YouTube videoId={page.url.replace("https://youtu.be/", "")} containerClassName="w-xl" className="w-xl" />
59+
</div>
60+
}
61+
</ul>
62+
</Main>
63+
)
64+
}
65+
function ExternalImg({ src }: { src: string }) {
66+
// eslint-disable-next-line @next/next/no-img-element
67+
return <FormattedLink href={src} target="_blank"><img className="p-1 relative max-w-4xl" style={{ maxHeight: "56rem" }} decoding="async" alt="Guide Image" src={src} /></FormattedLink>
68+
// return <div className="p-1 relative max-w-2xl">
69+
// <Image alt="Guide Image" src={src} width={825} height={963}/>
70+
// </div>
71+
}
72+
73+
export async function getStaticProps(context: GetStaticPropsContext): Promise<GetStaticPropsResult<Props>> {
74+
const guideName = context.params?.guide
75+
const categoryName = context.params?.category
76+
const data = await getGuides()
77+
78+
const guide = data?.find(g => urlify(g.name, false) == categoryName)
79+
const pageNumber = guide?.pages?.findIndex(g => urlify(g.name, true) == guideName)
80+
81+
if (!data || !guide || pageNumber === undefined || pageNumber === -1) {
82+
return {
83+
notFound: true,
84+
revalidate: 5 * 60
85+
}
86+
}
87+
88+
return {
89+
props: {
90+
guide,
91+
pageNumber
92+
},
93+
revalidate: 60 * 60
94+
}
95+
}
96+
97+
export async function getStaticPaths(): Promise<GetStaticPathsResult> {
98+
const data = await getGuides()
99+
return {
100+
paths: data?.flatMap(category => category.pages.map(p => ({
101+
params: { guide: urlify(p.name, true), category: urlify(category.name, false) }
102+
}))) ?? [],
103+
fallback: "blocking"
104+
}
105+
}

pnpm-lock.yaml

Lines changed: 38 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

utils/data-cache.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,16 @@ const cached: Cache = {
1515
time: 0
1616
}
1717
}
18-
export function urlify(input: string, yeetBrackets?: boolean): string {
19-
if (yeetBrackets)
20-
input = input.replace(/\(.*\)/g, "")
18+
export function urlify(input: string, shouldYeetBrackets: boolean): string {
19+
if (shouldYeetBrackets)
20+
input = yeetBrackets(input)
2121
return input.toLowerCase().replace(/\(|\)|:/g, "").trim().replace(/ +/g, "-")
2222
}
2323

24+
export function yeetBrackets(input: string) {
25+
return input.replace(/\(.*\)/g, "").replace(/ +:/, ":")
26+
}
27+
2428
export async function getGuides(): Promise<Guide[] | undefined> {
2529
if (cached.guides.time > Date.now() - 60 * 1000)
2630
return await cached.guides.data

0 commit comments

Comments
 (0)