mirror of
https://github.com/r-freeman/portfolio.git
synced 2025-04-21 23:54:37 +00:00
Render article nav on server
All checks were successful
Build And Publish / BuildAndPublish (push) Successful in 3m9s
All checks were successful
Build And Publish / BuildAndPublish (push) Successful in 3m9s
This commit is contained in:
parent
42a46b93d3
commit
a6e8c373b8
@ -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})
|
|
||||||
}
|
|
@ -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)
|
||||||
|
@ -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>
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user