Skip to content

Commit 13b6502

Browse files
author
Tu Phan
committed
fix: prev/next button
1 parent ab01284 commit 13b6502

File tree

2 files changed

+72
-40
lines changed

2 files changed

+72
-40
lines changed

src/app/blog/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { type ReactNode } from 'react'
1+
import type { ReactNode } from 'react'
22
import type { Metadata } from 'next'
33
import { headers } from 'next/headers'
44
import { all } from '@/db'

src/app/blog/template.tsx

Lines changed: 71 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'use client'
2-
import { type ReactNode } from 'react'
2+
import { useMemo, type ReactNode } from 'react'
33
import { usePathname } from 'next/navigation'
44
import clsx from 'clsx'
55

@@ -11,6 +11,70 @@ import Contributors from '@/components/contributors'
1111
import Schedule from '@/components/schedule'
1212
import Header from './header'
1313

14+
function PrevBlog({ route }: { route?: string }) {
15+
const { data: { parent } = {} } = useBlog(route)
16+
const { data: { children: siblings = [] } = {} } = useBlog(parent)
17+
const brother = useMemo(() => {
18+
const index = siblings.findIndex((r) => r === route)
19+
return siblings[index + 1]
20+
}, [route, siblings])
21+
const { data: { route: prev = '', title: left = '←' } = {} } = useBlog(
22+
brother || (parent !== '/blog' ? parent : ''),
23+
)
24+
25+
return (
26+
<Link
27+
className={clsx(
28+
'w-full h-full p-4 flex flex-col gap-1 items-start rounded-box bg-base-200 transition-all border-2 border-base-300',
29+
{
30+
'pointer-events-none opacity-60': !prev,
31+
'hover:bg-base-300': prev,
32+
},
33+
)}
34+
href={prev || '#'}
35+
aria-disabled={!prev}
36+
>
37+
<span className="text-xs opacity-60">Old Post</span>
38+
<span className="font-semibold text-left">{left}</span>
39+
</Link>
40+
)
41+
}
42+
43+
function NextBlog({ route }: { route?: string }) {
44+
const { data: { parent, children = [] } = {} } = useBlog(route)
45+
const { data: { parent: grand, children: siblings = [] } = {} } =
46+
useBlog(parent)
47+
const brother = useMemo(() => {
48+
const index = siblings.findIndex((r) => r === route)
49+
return siblings[index - 1]
50+
}, [route, siblings])
51+
const { data: { children: uncles = [] } = {} } = useBlog(grand)
52+
const uncle = useMemo(() => {
53+
const index = uncles.findIndex((r) => r === parent)
54+
return uncles[index - 1]
55+
}, [parent, uncles])
56+
const { data: { route: next = '', title: right = '→' } = {} } = useBlog(
57+
children.at(-1) || brother || uncle,
58+
)
59+
60+
return (
61+
<Link
62+
className={clsx(
63+
'w-full h-full p-4 flex flex-col gap-1 items-end rounded-box bg-base-200 transition-all border-2 border-base-300',
64+
{
65+
'pointer-events-none opacity-60': !next,
66+
'hover:bg-base-300': next,
67+
},
68+
)}
69+
href={next || '#'}
70+
aria-disabled={!next}
71+
>
72+
<span className="text-xs opacity-60">Next Post</span>
73+
<span className="font-semibold text-right">{right}</span>
74+
</Link>
75+
)
76+
}
77+
1478
export default function Template({ children }: { children: ReactNode }) {
1579
const pathname = usePathname()
1680

@@ -19,22 +83,12 @@ export default function Template({ children }: { children: ReactNode }) {
1983
route = '',
2084
authors = [],
2185
tags = [],
22-
parent,
2386
children: routes = [],
2487
date,
2588
} = {},
2689
isLoading,
2790
} = useBlog(pathname)
2891

29-
const { data: { children: siblings = [] } = {} } = useBlog(parent)
30-
const { data: { route: prev = '', title: left = '←' } = {} } = useBlog(
31-
siblings[siblings.findIndex((e) => e === route) + 1] ||
32-
(parent !== '/blog' ? parent : '/404'),
33-
)
34-
const { data: { route: next = '', title: right = '→' } = {} } = useBlog(
35-
routes.at(-1) || siblings[siblings.findIndex((e) => e === route) - 1],
36-
)
37-
3892
return (
3993
<div className="w-full flex flex-col gap-4 items-center relative">
4094
<div className="w-full mb-16 bg-base-100">
@@ -68,34 +122,12 @@ export default function Template({ children }: { children: ReactNode }) {
68122
</p>
69123
</div>
70124
<div id="prev-next" className="w-full grid grid-cols-2 gap-4">
71-
<Link
72-
className={clsx(
73-
'col-span-1 p-4 flex flex-col gap-1 items-start rounded-box bg-base-200 transition-all border-2 border-base-300',
74-
{
75-
'pointer-events-none opacity-60': !prev,
76-
'hover:bg-base-300': prev,
77-
},
78-
)}
79-
href={prev || '#'}
80-
aria-disabled={!prev}
81-
>
82-
<span className="text-xs opacity-60">Old Post</span>
83-
<span className="font-semibold text-left">{left}</span>
84-
</Link>
85-
<Link
86-
className={clsx(
87-
'col-span-1 p-4 flex flex-col gap-1 items-end rounded-box bg-base-200 transition-all border-2 border-base-300',
88-
{
89-
'pointer-events-none opacity-60': !next,
90-
'hover:bg-base-300': next,
91-
},
92-
)}
93-
href={next || '#'}
94-
aria-disabled={!next}
95-
>
96-
<span className="text-xs opacity-60">Next Post</span>
97-
<span className="font-semibold text-right">{right}</span>
98-
</Link>
125+
<div className="col-span-1">
126+
<PrevBlog route={route} />
127+
</div>
128+
<div className="col-span-1">
129+
<NextBlog route={route} />
130+
</div>
99131
</div>
100132
<div id="suggestion" className="w-full grid grid-cols-12 gap-4">
101133
{[...routes].reverse().map((route) => (

0 commit comments

Comments
 (0)