Render article nav on server
All checks were successful
Build And Publish / BuildAndPublish (push) Successful in 3m9s

This commit is contained in:
Ryan Freeman 2025-03-27 15:47:52 +00:00
parent 42a46b93d3
commit a6e8c373b8
4 changed files with 32 additions and 74 deletions

View File

@ -1,7 +0,0 @@
import {getAllArticles} from '@/lib/getAllArticles'
export async function GET(request: Request) {
const articles = await getAllArticles(false)
return new Response(JSON.stringify(articles), {status: 200})
}

View File

@ -14,7 +14,7 @@ export async function GET(request: Request, {params}: { params: Promise<{ slug:
published, published,
created_at, created_at,
user:users!inner(id, name, image), user:users!inner(id, name, image),
article:articles!inner(id, slug) article:articles!inner(id, title, slug)
`) `)
.eq('article.slug', slug) .eq('article.slug', slug)
.eq('published', true) .eq('published', true)

View File

@ -7,6 +7,7 @@ import {ArrowDownIcon} from '@/components/icons/ArrowDownIcon'
import {formatDate} from '@/lib/formatDate' import {formatDate} from '@/lib/formatDate'
import ArticleNav from '@/components/ui/ArticleNav' import ArticleNav from '@/components/ui/ArticleNav'
import Comments from '@/components/ui/Comments' import Comments from '@/components/ui/Comments'
import {getAllArticles} from '@/lib/getAllArticles'
type ArticleLayout = { type ArticleLayout = {
title: string title: string
@ -24,12 +25,33 @@ const gradients = [
'bg-gradient-to-r from-sky-400 to-blue-500' 'bg-gradient-to-r from-sky-400 to-blue-500'
] ]
export function ArticleLayout({ type Article = {
title, slug: string
date, authors: string
slug, title: string
children date: string
}: ArticleLayout) { description: string
}
function findAdjacentArticles(articles: Article[], slug: string) {
let prev, next
if (articles) {
const index = articles.findIndex(article => article.slug === slug)
prev = index > 0 ? articles[index - 1] : null
next = index < articles.length - 1 ? articles[index + 1] : null
}
return {prev, next}
}
export async function ArticleLayout({
title,
date,
slug,
children
}: ArticleLayout) {
const articles = await getAllArticles(false)
const {prev, next} = findAdjacentArticles(articles, slug)
return ( return (
<Container className="mt-16 lg:mt-32"> <Container className="mt-16 lg:mt-32">
@ -60,7 +82,7 @@ export function ArticleLayout({
<Prose className="mt-8" data-mdx-content>{children}</Prose> <Prose className="mt-8" data-mdx-content>{children}</Prose>
</article> </article>
<Comments slug={slug}/> <Comments slug={slug}/>
<ArticleNav slug={slug}/> <ArticleNav prev={prev} next={next}/>
</div> </div>
</div> </div>
</Container> </Container>

View File

@ -1,65 +1,8 @@
'use client' import React from 'react'
import React, {ReactElement, useEffect, useState} from 'react'
import fetcher from '@/lib/fetcher'
import useSWR from 'swr'
import {Card} from '@/components/ui/Card' import {Card} from '@/components/ui/Card'
import clsx from 'clsx' import clsx from 'clsx'
export default function ArticleNav({prev, next}: { prev: any, next: any }) {
type Article = {
slug: string
authors: string
title: string
date: string
description: string
}
type FetchArticlesResponse = {
data: Article[]
error: string
isLoading: boolean
}
type ArticleNavProps = {
slug: string
}
type PaginationProps = {
next: Article | null
prev: Article | null
}
function useFetchArticles() {
const {data, error, isLoading} = useSWR(`/api/articles/`, fetcher) as FetchArticlesResponse
return {
articles: data,
isLoading,
isError: error
}
}
export default function ArticleNav({slug}: ArticleNavProps): ReactElement | null {
const {articles, isLoading, isError} = useFetchArticles()
const [{next, prev}, setPagination] = useState<PaginationProps>({next: null, prev: null})
useEffect(() => {
const findAdjacentArticles = (articles: Article[], slug: string) => {
if (articles) {
const index = articles.findIndex(article => article.slug === slug)
const next = index < articles.length - 1 ? articles[index + 1] : null
const prev = index > 0 ? articles[index - 1] : null
setPagination({next, prev})
}
}
findAdjacentArticles(articles, slug)
}, [articles, slug])
if (isError) return null
return ( return (
<section className="mt-24"> <section className="mt-24">
<ul <ul