From c963803320dd98f7390eaafd55f19836835dbddc Mon Sep 17 00:00:00 2001 From: Ryan Freeman Date: Tue, 1 Oct 2024 22:00:02 +0100 Subject: [PATCH] Added Article navigation --- app/api/articles/route.ts | 7 +++ components/layouts/ArticleLayout.tsx | 5 +- components/ui/ArticleNav.tsx | 85 ++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 app/api/articles/route.ts create mode 100644 components/ui/ArticleNav.tsx diff --git a/app/api/articles/route.ts b/app/api/articles/route.ts new file mode 100644 index 0000000..8937e6f --- /dev/null +++ b/app/api/articles/route.ts @@ -0,0 +1,7 @@ +import {getAllArticles} from '@/lib/getAllArticles' + +export async function GET(request: Request) { + const articles = await getAllArticles() + + return new Response(JSON.stringify(articles), {status: 200}) +} diff --git a/components/layouts/ArticleLayout.tsx b/components/layouts/ArticleLayout.tsx index e21e7e2..530268d 100644 --- a/components/layouts/ArticleLayout.tsx +++ b/components/layouts/ArticleLayout.tsx @@ -5,6 +5,7 @@ import {Prose} from '@/components/ui/Prose' import {Views} from '@/components/ui/Views' import {ArrowDownIcon} from '@/components/icons/ArrowDownIcon' import {formatDate} from '@/lib/formatDate' +import ArticleNav from '@/components/ui/ArticleNav' type ArticleLayout = { title: string @@ -12,7 +13,6 @@ type ArticleLayout = { description: string slug: string children?: ReactNode - ogImage?: string } const gradients = [ @@ -26,10 +26,8 @@ const gradients = [ export function ArticleLayout({ title, date, - description, slug, children, - ogImage }: ArticleLayout) { return ( @@ -60,6 +58,7 @@ export function ArticleLayout({ {children} + diff --git a/components/ui/ArticleNav.tsx b/components/ui/ArticleNav.tsx new file mode 100644 index 0000000..3f571a1 --- /dev/null +++ b/components/ui/ArticleNav.tsx @@ -0,0 +1,85 @@ +'use client' + +import React, {ReactElement, useEffect, useState} from 'react' +import fetcher from '@/lib/fetcher' +import useSWR from 'swr' +import {Card} from '@/components/ui/Card' + + +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({next: null, prev: null}) + + useEffect(() => { + const findAdjacentArticles = (articles: Article[], slug: string) => { + if (articles) { + const index = articles.findIndex(article => article.slug === slug) + const next = index > 0 ? articles[index - 1] : null + const prev = index < articles.length - 1 ? articles[index + 1] : null + + setPagination({next, prev}) + } + } + + findAdjacentArticles(articles, slug) + }, [articles, slug]) + + if (isError) return null + + return ( +
+
    + {prev !== null && + +

    + {prev.title} +

    +
    + } + {next !== null && + +

    + {next.title} +

    +
    + } +
+
+ ) +} \ No newline at end of file