This commit is contained in:
amirhouieh 2023-05-13 12:23:52 +02:00 committed by Jinho Jang
parent 428a66638f
commit 3e5e136be5
6 changed files with 106 additions and 62 deletions

View File

@ -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<PostDataProps[]>(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 (
<Grid>
{posts.map((post, index) => (
<GridItem className="w-4" key={index}>
<PostLink href={`/article/${post.slug}`}>
<PostWrapper>
<Post data={post} />
</PostWrapper>
</PostLink>
</GridItem>
))}
</Grid>
<div>
<Grid style={{ minHeight: '500px' }}>
{postsToShow.length > 0 ? (
postsToShow.map((post, index) => (
<GridItem className="w-4" key={index}>
<PostLink href={`/article/${post.slug}`}>
<PostWrapper>
<Post data={post} />
</PostWrapper>
</PostLink>
</GridItem>
))
) : (
<GridItem className="w-12">
<Typography variant="body1">No related articles found.</Typography>
</GridItem>
)}
</Grid>
<Button onClick={() => handleMoreOrLess()}>
{page * pageSize < posts.length ? 'Load More' : 'Show Less'}
</Button>
</div>
)
}

View File

@ -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<UnbodyGoogleDoc>[]
data: SearchHook<UnbodyGoogleDoc>
}
export default function RelatedArticles({ articles }: Props) {
export default function RelatedArticles({ data }: Props) {
if (!data.loading && !data.data) return null
return (
<Container>
<Section title={'Related Articles'} matches={articles?.length}>
<PostsList
posts={articles.map((article) => ({
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),
}))}
/>
<Section
title={data.loading ? 'Loading...' : 'Related Articles'}
matches={data.loading ? undefined : data.data.length}
>
{
<PostsList
posts={
data.loading
? []
: data.data.map((article) => ({
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}
/>
}
</Section>
</Container>
)

View File

@ -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) => {

View File

@ -72,16 +72,8 @@ export default function SearchPage({
return (
<div>
{articles.data?.length ? (
<RelatedArticles articles={articles.data} />
) : (
<Section title={'No Related Articles'} />
)}
{blocks.data?.length ? (
<RelatedContent blocks={blocks.data} />
) : (
<Section title={'No Related Content'} />
)}
<RelatedArticles data={articles} />
{blocks.data?.length && <RelatedContent blocks={blocks.data} />}
</div>
)
}

View File

@ -22,5 +22,6 @@ export const getSearchArticlesQuery = (args: UnbodyGetFilters = defaultArgs) =>
}
_additional{
certainty
score
}
`)

View File

@ -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<SearchResultItem<UnbodyImageBlock | UnbodyTextBlock>[]>
> => {
let whereFilters: any = []
const query = getSearchBlocksQuery({
...(q.trim().length > 0
? {
@ -401,6 +406,8 @@ class UnbodyService extends UnbodyClient {
published: boolean = true,
): Promise<ApiResponse<SearchResultItem<GoogleDocEnhanced>[]>> => {
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),
})),
)
})