11'use client'
2- import { type ReactNode } from 'react'
2+ import { useMemo , type ReactNode } from 'react'
33import { usePathname } from 'next/navigation'
44import clsx from 'clsx'
55
@@ -11,6 +11,70 @@ import Contributors from '@/components/contributors'
1111import Schedule from '@/components/schedule'
1212import 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+
1478export 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