From 754a4289f0453f82966e9b367bd3bd970901852d Mon Sep 17 00:00:00 2001 From: Mats <64415243+mnyflot@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:02:01 +0200 Subject: [PATCH] 223 fix total count of blog posts in pagination (#230) * feat(frontend): :sparkles: improve blog pagination One can no longer access pages without blogs * style(frontend): remove console logs * style(frontend): :rotating_light: fix lint error * fix(frontend): :bug: fix type error --- frontend/src/__generated__/gql.ts | 4 +- frontend/src/__generated__/graphql.ts | 4 +- frontend/src/app/blog/page.tsx | 15 +++-- frontend/src/components/BlogPaginator.tsx | 77 +++++++++++++--------- frontend/src/lib/data/fetchArticleInfo.tsx | 11 +++- 5 files changed, 69 insertions(+), 42 deletions(-) diff --git a/frontend/src/__generated__/gql.ts b/frontend/src/__generated__/gql.ts index fa264a6..b758d1b 100644 --- a/frontend/src/__generated__/gql.ts +++ b/frontend/src/__generated__/gql.ts @@ -18,7 +18,7 @@ const documents = { "\n query GET_PROJECTS {\n projects(sort: [\"publishedAt:desc\"]) {\n data {\n id\n attributes {\n title\n content\n satellites {\n data {\n attributes {\n catalogNumberNORAD\n }\n }\n }\n slug\n previewImage {\n data {\n attributes {\n url\n }\n }\n }\n }\n }\n }\n }": types.Get_ProjectsDocument, "\nquery GET_SATELLITES {\n satellites {\n data {\n id\n attributes {\n celestrakURL\n catalogNumberNORAD\n name\n previewImage {\n data {\n attributes {\n url\n }\n }\n }\n missionStatus\n }\n }\n }\n }\n": types.Get_SatellitesDocument, "query Satellites($filters: SatelliteFiltersInput) {\n satellites(filters: $filters) {\n data {\n attributes {\n celestrakURL\n catalogNumberNORAD\n }\n }\n }\n }\n ": types.SatellitesDocument, - "\nquery GET_ARTICLES($pagination: PaginationArg, $filters: ArticleFiltersInput) {\n articles(sort: [\"datePublished:desc\"], pagination: $pagination, filters: $filters) {\n data {\n id\n attributes {\n author {\n data {\n attributes {\n name\n avatar {\n data {\n attributes {\n url\n }\n }\n }\n }\n }\n }\n title\n datePublished\n body\n coverImage {\n data {\n attributes {\n url\n }\n }\n }\n createdAt\n publishedAt\n slug\n subtitle\n Tag\n }\n }\n }\n}\n": types.Get_ArticlesDocument, + "\nquery GET_ARTICLES($pagination: PaginationArg, $filters: ArticleFiltersInput) {\n articles(sort: [\"datePublished:desc\"], pagination: $pagination, filters: $filters) {\n data {\n id\n attributes {\n author {\n data {\n attributes {\n name\n avatar {\n data {\n attributes {\n url\n }\n }\n }\n }\n }\n }\n title\n datePublished\n body\n coverImage {\n data {\n attributes {\n url\n }\n }\n }\n createdAt\n publishedAt\n slug\n subtitle\n Tag\n }\n }\n meta {\n pagination {\n total\n }\n }\n }\n}\n": types.Get_ArticlesDocument, "\nquery MostRecentImages {\n mostRecentImages(sort: [\"publishedAt:desc\"]) {\n data {\n attributes {\n mostRecentImage {\n data {\n attributes {\n url\n }\n }\n }\n satellite {\n data {\n attributes {\n catalogNumberNORAD\n name\n }\n }\n }\n createdAt\n updatedAt\n publishedAt\n }\n }\n }\n}\n\n": types.MostRecentImagesDocument, "query GET_SATELLITE_INFO($filters: SatelliteFiltersInput) {\n satellites(filters: $filters) {\n data {\n id\n attributes {\n celestrakURL\n catalogNumberNORAD\n content\n name\n projects {\n data {\n attributes {\n title\n previewImage {\n data {\n attributes {\n url\n }\n }\n }\n slug\n }\n id\n }\n }\n }\n }\n }\n }\n ": types.Get_Satellite_InfoDocument, }; @@ -60,7 +60,7 @@ export function gql(source: "query Satellites($filters: SatelliteFiltersInput) { /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function gql(source: "\nquery GET_ARTICLES($pagination: PaginationArg, $filters: ArticleFiltersInput) {\n articles(sort: [\"datePublished:desc\"], pagination: $pagination, filters: $filters) {\n data {\n id\n attributes {\n author {\n data {\n attributes {\n name\n avatar {\n data {\n attributes {\n url\n }\n }\n }\n }\n }\n }\n title\n datePublished\n body\n coverImage {\n data {\n attributes {\n url\n }\n }\n }\n createdAt\n publishedAt\n slug\n subtitle\n Tag\n }\n }\n }\n}\n"): (typeof documents)["\nquery GET_ARTICLES($pagination: PaginationArg, $filters: ArticleFiltersInput) {\n articles(sort: [\"datePublished:desc\"], pagination: $pagination, filters: $filters) {\n data {\n id\n attributes {\n author {\n data {\n attributes {\n name\n avatar {\n data {\n attributes {\n url\n }\n }\n }\n }\n }\n }\n title\n datePublished\n body\n coverImage {\n data {\n attributes {\n url\n }\n }\n }\n createdAt\n publishedAt\n slug\n subtitle\n Tag\n }\n }\n }\n}\n"]; +export function gql(source: "\nquery GET_ARTICLES($pagination: PaginationArg, $filters: ArticleFiltersInput) {\n articles(sort: [\"datePublished:desc\"], pagination: $pagination, filters: $filters) {\n data {\n id\n attributes {\n author {\n data {\n attributes {\n name\n avatar {\n data {\n attributes {\n url\n }\n }\n }\n }\n }\n }\n title\n datePublished\n body\n coverImage {\n data {\n attributes {\n url\n }\n }\n }\n createdAt\n publishedAt\n slug\n subtitle\n Tag\n }\n }\n meta {\n pagination {\n total\n }\n }\n }\n}\n"): (typeof documents)["\nquery GET_ARTICLES($pagination: PaginationArg, $filters: ArticleFiltersInput) {\n articles(sort: [\"datePublished:desc\"], pagination: $pagination, filters: $filters) {\n data {\n id\n attributes {\n author {\n data {\n attributes {\n name\n avatar {\n data {\n attributes {\n url\n }\n }\n }\n }\n }\n }\n title\n datePublished\n body\n coverImage {\n data {\n attributes {\n url\n }\n }\n }\n createdAt\n publishedAt\n slug\n subtitle\n Tag\n }\n }\n meta {\n pagination {\n total\n }\n }\n }\n}\n"]; /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/frontend/src/__generated__/graphql.ts b/frontend/src/__generated__/graphql.ts index 14ba33e..dd9e9d3 100644 --- a/frontend/src/__generated__/graphql.ts +++ b/frontend/src/__generated__/graphql.ts @@ -1432,7 +1432,7 @@ export type Get_ArticlesQueryVariables = Exact<{ }>; -export type Get_ArticlesQuery = { __typename?: 'Query', articles?: { __typename?: 'ArticleEntityResponseCollection', data: Array<{ __typename?: 'ArticleEntity', id?: string | null, attributes?: { __typename?: 'Article', title: string, datePublished: any, body: any, createdAt?: any | null, publishedAt?: any | null, slug: string, subtitle?: string | null, Tag?: Enum_Article_Tag | null, author?: { __typename?: 'AuthorEntityResponse', data?: { __typename?: 'AuthorEntity', attributes?: { __typename?: 'Author', name: string, avatar?: { __typename?: 'UploadFileEntityResponse', data?: { __typename?: 'UploadFileEntity', attributes?: { __typename?: 'UploadFile', url: string } | null } | null } | null } | null } | null } | null, coverImage?: { __typename?: 'UploadFileEntityResponse', data?: { __typename?: 'UploadFileEntity', attributes?: { __typename?: 'UploadFile', url: string } | null } | null } | null } | null }> } | null }; +export type Get_ArticlesQuery = { __typename?: 'Query', articles?: { __typename?: 'ArticleEntityResponseCollection', data: Array<{ __typename?: 'ArticleEntity', id?: string | null, attributes?: { __typename?: 'Article', title: string, datePublished: any, body: any, createdAt?: any | null, publishedAt?: any | null, slug: string, subtitle?: string | null, Tag?: Enum_Article_Tag | null, author?: { __typename?: 'AuthorEntityResponse', data?: { __typename?: 'AuthorEntity', attributes?: { __typename?: 'Author', name: string, avatar?: { __typename?: 'UploadFileEntityResponse', data?: { __typename?: 'UploadFileEntity', attributes?: { __typename?: 'UploadFile', url: string } | null } | null } | null } | null } | null } | null, coverImage?: { __typename?: 'UploadFileEntityResponse', data?: { __typename?: 'UploadFileEntity', attributes?: { __typename?: 'UploadFile', url: string } | null } | null } | null } | null }>, meta: { __typename?: 'ResponseCollectionMeta', pagination: { __typename?: 'Pagination', total: number } } } | null }; export type MostRecentImagesQueryVariables = Exact<{ [key: string]: never; }>; @@ -1452,6 +1452,6 @@ export const ProjectsDocument = {"kind":"Document","definitions":[{"kind":"Opera export const Get_ProjectsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GET_PROJECTS"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projects"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"ListValue","values":[{"kind":"StringValue","value":"publishedAt:desc","block":false}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"content"}},{"kind":"Field","name":{"kind":"Name","value":"satellites"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"catalogNumberNORAD"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"previewImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const Get_SatellitesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GET_SATELLITES"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"satellites"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"celestrakURL"}},{"kind":"Field","name":{"kind":"Name","value":"catalogNumberNORAD"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"previewImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"missionStatus"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const SatellitesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Satellites"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filters"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SatelliteFiltersInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"satellites"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"celestrakURL"}},{"kind":"Field","name":{"kind":"Name","value":"catalogNumberNORAD"}}]}}]}}]}}]}}]} as unknown as DocumentNode; -export const Get_ArticlesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GET_ARTICLES"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"PaginationArg"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filters"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ArticleFiltersInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"articles"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"ListValue","values":[{"kind":"StringValue","value":"datePublished:desc","block":false}]}},{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"author"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"datePublished"}},{"kind":"Field","name":{"kind":"Name","value":"body"}},{"kind":"Field","name":{"kind":"Name","value":"coverImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"publishedAt"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"subtitle"}},{"kind":"Field","name":{"kind":"Name","value":"Tag"}}]}}]}}]}}]}}]} as unknown as DocumentNode; +export const Get_ArticlesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GET_ARTICLES"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"PaginationArg"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filters"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ArticleFiltersInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"articles"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"ListValue","values":[{"kind":"StringValue","value":"datePublished:desc","block":false}]}},{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"author"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"datePublished"}},{"kind":"Field","name":{"kind":"Name","value":"body"}},{"kind":"Field","name":{"kind":"Name","value":"coverImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"publishedAt"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"subtitle"}},{"kind":"Field","name":{"kind":"Name","value":"Tag"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"meta"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"pagination"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const MostRecentImagesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"MostRecentImages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"mostRecentImages"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"ListValue","values":[{"kind":"StringValue","value":"publishedAt:desc","block":false}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"mostRecentImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"satellite"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"catalogNumberNORAD"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"publishedAt"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const Get_Satellite_InfoDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GET_SATELLITE_INFO"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filters"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SatelliteFiltersInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"satellites"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"celestrakURL"}},{"kind":"Field","name":{"kind":"Name","value":"catalogNumberNORAD"}},{"kind":"Field","name":{"kind":"Name","value":"content"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"projects"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"previewImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/frontend/src/app/blog/page.tsx b/frontend/src/app/blog/page.tsx index fc04674..9b5422b 100644 --- a/frontend/src/app/blog/page.tsx +++ b/frontend/src/app/blog/page.tsx @@ -27,17 +27,24 @@ export default async function BlogPage({ const currentPage = parseInt(page ?? "1", 10); const tag = searchParams?.tag ?? null; - const articles = (await fetchArticlePages({ + const result = await fetchArticlePages({ currentPage: currentPage, pageSize: 7, tag: tag, - })) as BlogPost[]; + }); + + if (!result) { + // Handle the case where fetchArticlePages returns null + return
Error fetching articles
; + } + + const { articleList, totalArticles } = result; return (
{/* */} - - + +
); } diff --git a/frontend/src/components/BlogPaginator.tsx b/frontend/src/components/BlogPaginator.tsx index b4358b8..87c317b 100644 --- a/frontend/src/components/BlogPaginator.tsx +++ b/frontend/src/components/BlogPaginator.tsx @@ -3,7 +3,6 @@ import { Pagination, PaginationContent, - PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, @@ -11,7 +10,11 @@ import { } from "./ui/pagination"; import { useRouter, useSearchParams } from "next/navigation"; -export default function BlogPaginator() { +export default function BlogPaginator({ + totalArticles, +}: { + totalArticles: Number; +}) { const searchParams = useSearchParams(); const router = useRouter(); const tag = useSearchParams().get("tag"); @@ -20,11 +23,17 @@ export default function BlogPaginator() { let currentPage = parseInt(page ?? "1", 10); currentPage = currentPage > 1 ? currentPage : 1; + const pageSize = 7; + const totalPages = Math.ceil(Number(totalArticles) / pageSize); + function handlePageChange(page: number) { console.log(page); if (page < 1) { return; } + if (page > totalPages) { + return; + } if (tag === null) { router.replace(`/blog?page=${page}`); } else { @@ -32,6 +41,29 @@ export default function BlogPaginator() { } } + let startPage: number; + let endPage: number; + + if (totalPages <= 3) { + startPage = 1; + endPage = totalPages; + } else { + startPage = Math.max(currentPage - 1, 1); + endPage = Math.min(currentPage + 1, totalPages); + if (endPage - startPage < 2) { + if (currentPage === 1) { + endPage = Math.min(endPage + 1, totalPages); + } else { + startPage = Math.max(startPage - 1, 1); + } + } + } + + const pages = Array.from( + { length: endPage - startPage + 1 }, + (_, index) => index + startPage, + ); + return ( @@ -43,42 +75,25 @@ export default function BlogPaginator() { href="#" /> - {currentPage > 1 ? ( - + + {pages.map((page, id) => ( + { - handlePageChange(currentPage - 1); + handlePageChange(page); }} href="#" > - {currentPage - 1} + {page} - ) : null} - - { - handlePageChange(currentPage); - }} - href="#" - isActive - > - {currentPage} - - - - { - handlePageChange(currentPage + 1); - }} - href="#" - > - {currentPage + 1} - - - - - + ))} + { diff --git a/frontend/src/lib/data/fetchArticleInfo.tsx b/frontend/src/lib/data/fetchArticleInfo.tsx index 1c718db..a8ee420 100644 --- a/frontend/src/lib/data/fetchArticleInfo.tsx +++ b/frontend/src/lib/data/fetchArticleInfo.tsx @@ -43,6 +43,11 @@ query GET_ARTICLES($pagination: PaginationArg, $filters: ArticleFiltersInput) { Tag } } + meta { + pagination { + total + } + } } } `); @@ -60,8 +65,6 @@ export default async function fetchArticlePages({ let graphqlData; - console.log(!tag); - if (!tag) { graphqlData = await getClient().query({ query: GET_ARTICLES, @@ -145,5 +148,7 @@ export default async function fetchArticlePages({ firstArticle = false; }); - return articleList; + const totalArticles = graphqlData.data?.articles?.meta?.pagination?.total; + + return { articleList, totalArticles }; }