From 3e5e136be536b3b834532f7aa9dee72c29fd5b43 Mon Sep 17 00:00:00 2001 From: amirhouieh Date: Sat, 13 May 2023 12:23:52 +0200 Subject: [PATCH] close #35 --- src/components/PostList/PostList.tsx | 52 ++++++++++++---- .../RelatedArticles/RelatedArticles.tsx | 42 ++++++++----- src/components/Section/Section.tsx | 2 +- src/pages/search.tsx | 12 +--- src/queries/searchArticles.ts | 1 + src/services/unbody.service.ts | 59 +++++++++++-------- 6 files changed, 106 insertions(+), 62 deletions(-) diff --git a/src/components/PostList/PostList.tsx b/src/components/PostList/PostList.tsx index a1bf462..d3cda6c 100644 --- a/src/components/PostList/PostList.tsx +++ b/src/components/PostList/PostList.tsx @@ -1,11 +1,13 @@ import Link from 'next/link' -import { useState } from 'react' +import { useEffect, useState } from 'react' import { Grid, GridItem } from '../Grid/Grid' import styled from '@emotion/styled' import Post, { PostDataProps } from '../Post/Post' +import { Button, Typography } from '@acid-info/lsd-react' type Props = { posts: PostDataProps[] + pageSize?: number } const getGridItemWidth = (index: number) => { @@ -21,20 +23,46 @@ const getGridItemWidth = (index: number) => { } export const PostsList = (props: Props) => { + const { pageSize = 6 } = props const [posts, setPosts] = useState(props.posts) + const [page, setPage] = useState(1) + + useEffect(() => { + setPosts(props.posts) + }, [props.posts]) + + const handleMoreOrLess = () => { + const dir = page * pageSize < posts.length ? 1 : -1 + setPage( + Math.max(1, Math.min(page + dir, Math.ceil(posts.length / pageSize))), + ) + } + + const postsToShow = posts.slice(0, page * pageSize) return ( - - {posts.map((post, index) => ( - - - - - - - - ))} - +
+ + {postsToShow.length > 0 ? ( + postsToShow.map((post, index) => ( + + + + + + + + )) + ) : ( + + No related articles found. + + )} + + +
) } diff --git a/src/components/RelatedArticles/RelatedArticles.tsx b/src/components/RelatedArticles/RelatedArticles.tsx index 9dee882..19aa434 100644 --- a/src/components/RelatedArticles/RelatedArticles.tsx +++ b/src/components/RelatedArticles/RelatedArticles.tsx @@ -3,28 +3,40 @@ import { Typography } from '@acid-info/lsd-react' import styled from '@emotion/styled' import { PostsList } from '../PostList/PostList' import { Section } from '../Section/Section' -import { SearchResultItem } from '@/types/data.types' +import { SearchHook, SearchResultItem } from '@/types/data.types' import { UnbodyGoogleDoc } from '@/lib/unbody/unbody.types' type Props = { - articles: SearchResultItem[] + data: SearchHook } -export default function RelatedArticles({ articles }: Props) { +export default function RelatedArticles({ data }: Props) { + if (!data.loading && !data.data) return null + return ( -
- ({ - slug: article.doc.slug, - date: article.doc.modifiedAt, - title: article.doc.title, - description: article.doc.subtitle, // TODO: summary is not available - mentions: article.doc.mentions, - tags: article.doc.tags, - coverImage: getArticleCover(article.doc.blocks), - }))} - /> +
+ { + ({ + slug: article.doc.slug, + date: article.doc.modifiedAt, + title: article.doc.title, + description: article.doc.subtitle, // TODO: summary is not available + mentions: article.doc.mentions, + tags: article.doc.tags, + coverImage: getArticleCover(article.doc.blocks), + })) + } + pageSize={4} + /> + }
) diff --git a/src/components/Section/Section.tsx b/src/components/Section/Section.tsx index a6fe9fc..abd0ff2 100644 --- a/src/components/Section/Section.tsx +++ b/src/components/Section/Section.tsx @@ -4,7 +4,7 @@ import { PropsWithChildren } from 'react' type Props = PropsWithChildren<{ title: string - matches?: number + matches?: number | string }> export const Section = ({ title, matches, children, ...props }: Props) => { diff --git a/src/pages/search.tsx b/src/pages/search.tsx index e03d02f..5e13863 100644 --- a/src/pages/search.tsx +++ b/src/pages/search.tsx @@ -72,16 +72,8 @@ export default function SearchPage({ return (
- {articles.data?.length ? ( - - ) : ( -
- )} - {blocks.data?.length ? ( - - ) : ( -
- )} + + {blocks.data?.length && }
) } diff --git a/src/queries/searchArticles.ts b/src/queries/searchArticles.ts index 1b1dc47..9df9c29 100644 --- a/src/queries/searchArticles.ts +++ b/src/queries/searchArticles.ts @@ -22,5 +22,6 @@ export const getSearchArticlesQuery = (args: UnbodyGetFilters = defaultArgs) => } _additional{ certainty + score } `) diff --git a/src/services/unbody.service.ts b/src/services/unbody.service.ts index 8cb72f3..d365ba6 100644 --- a/src/services/unbody.service.ts +++ b/src/services/unbody.service.ts @@ -146,6 +146,13 @@ const enhanceGoogleDoc = (doc: UnbodyGoogleDoc): GoogleDocEnhanced => ({ : [], }) +const resolveScore = (_additional: any): number => { + if (!_additional) { + return 0 + } + return _additional.certainty || parseFloat(_additional.score) +} + const enhanceTextBlock = (block: UnbodyTextBlock): TextBlockEnhanced => ({ ...block, footnotes: @@ -357,8 +364,6 @@ class UnbodyService extends UnbodyClient { ): Promise< ApiResponse[]> > => { - let whereFilters: any = [] - const query = getSearchBlocksQuery({ ...(q.trim().length > 0 ? { @@ -401,6 +406,8 @@ class UnbodyService extends UnbodyClient { published: boolean = true, ): Promise[]>> => { let queryFilters = {} + let whereFilters: any = [] + if (q.trim().length > 0) { queryFilters = { nearText: { @@ -409,28 +416,32 @@ class UnbodyService extends UnbodyClient { } } - if (tags.length > 0) { - queryFilters = { - ...queryFilters, - where: { - operator: UnbodyGraphQl.Filters.WhereOperatorEnum.And, - operands: tags.map((tag) => ({ - path: ['tags'], - operator: UnbodyGraphQl.Filters.WhereOperatorEnum.Like, - valueString: tag, - })), - }, - } - } + // if publushed is true, we add the published filter + // if published is false, we don't add the published filter + // if tags empty, we don't add the tags filter + // if tags not empty, we add the tags filter if (published) { - queryFilters = { - ...queryFilters, - where: { - ...((queryFilters as any).where || {}), - ...Operands.WHERE_PUBLISHED(), - }, - } + whereFilters.push(Operands.WHERE_PUBLISHED()) + } + + if (tags.length > 0) { + whereFilters.push({ + operator: UnbodyGraphQl.Filters.WhereOperatorEnum.And, + operands: tags.map((tag) => ({ + path: ['tags'], + operator: UnbodyGraphQl.Filters.WhereOperatorEnum.Like, + valueString: tag.toLowerCase(), + })), + }) + } + + queryFilters = { + ...queryFilters, + where: { + operator: UnbodyGraphQl.Filters.WhereOperatorEnum.And, + operands: whereFilters, + }, } const query = getSearchArticlesQuery(queryFilters) @@ -439,11 +450,11 @@ class UnbodyService extends UnbodyClient { .then(({ data }) => { if (!data || !data.Get.GoogleDoc) return this.handleResponse([], 'No data') + return this.handleResponse( data.Get.GoogleDoc.map((item) => ({ doc: enhanceGoogleDoc(item), - score: - q.length > 0 || tags.length > 0 ? item._additional.certainty : 0, + score: resolveScore(item._additional), })), ) })