mirror of
https://github.com/acid-info/logos-press-engine.git
synced 2025-02-23 14:48:08 +00:00
enhance search view & close #41
This commit is contained in:
parent
1f41575d98
commit
bc2da5ebac
@ -10,6 +10,7 @@ type Props = {
|
||||
posts: PostDataProps[]
|
||||
pageSize?: number
|
||||
layout?: PostListLayout
|
||||
loading?: boolean
|
||||
}
|
||||
|
||||
const getGridItemWidth = (index: number) => {
|
||||
@ -56,7 +57,7 @@ export const PostsList = (props: Props) => {
|
||||
key={index}
|
||||
>
|
||||
<PostLink href={`/article/${post.slug}`}>
|
||||
<PostWrapper>
|
||||
<PostWrapper className={props.loading ? 'loading' : ''}>
|
||||
<Post data={post} />
|
||||
</PostWrapper>
|
||||
</PostLink>
|
||||
@ -82,6 +83,12 @@ const PostWrapper = styled.div`
|
||||
padding: 16px 0;
|
||||
border-top: 1px solid rgb(var(--lsd-theme-primary));
|
||||
width: 100%;
|
||||
|
||||
transition: opacity 0.3s ease-in-out;
|
||||
|
||||
&.loading {
|
||||
opacity: 0.5;
|
||||
}
|
||||
`
|
||||
|
||||
const PostLink = styled(Link)`
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { getArticleCover } from '@/utils/data.utils'
|
||||
import { Typography } from '@acid-info/lsd-react'
|
||||
import styled from '@emotion/styled'
|
||||
import { PostsList } from '../PostList/PostList'
|
||||
import { Section } from '../Section/Section'
|
||||
import { SearchHook, SearchResultItem } from '@/types/data.types'
|
||||
import { SearchHook } from '@/types/data.types'
|
||||
import { UnbodyGoogleDoc } from '@/lib/unbody/unbody.types'
|
||||
import { SearchResultsSection } from '@/components/SearchResultsSection/SearchResultsSection'
|
||||
|
||||
type Props = {
|
||||
data: SearchHook<UnbodyGoogleDoc>
|
||||
@ -12,32 +11,29 @@ type Props = {
|
||||
|
||||
export default function RelatedArticles({ data }: Props) {
|
||||
if (!data.loading && !data.data) return null
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Section
|
||||
title={data.loading ? 'Loading...' : 'Related Articles'}
|
||||
matches={data.loading ? undefined : data.data.length}
|
||||
<SearchResultsSection
|
||||
resultSize={data.data.length}
|
||||
loading={data.loading}
|
||||
title={'Related Articles'}
|
||||
>
|
||||
{
|
||||
<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),
|
||||
}))
|
||||
}
|
||||
posts={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}
|
||||
loading={data.loading}
|
||||
/>
|
||||
}
|
||||
</Section>
|
||||
</SearchResultsSection>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
@ -1,21 +1,24 @@
|
||||
import styled from '@emotion/styled'
|
||||
import { Section } from '../Section/Section'
|
||||
import { SearchResultItem } from '@/types/data.types'
|
||||
import { SearchHook, SearchResultItem } from '@/types/data.types'
|
||||
import { UnbodyImageBlock, UnbodyTextBlock } from '@/lib/unbody/unbody.types'
|
||||
import { Grid } from '../Grid/Grid'
|
||||
import { ImageBlock, TextBlock } from '../ContentBlock'
|
||||
import { UnbodyGraphQl } from '@/lib/unbody/unbody-content.types'
|
||||
import { SearchResultsSection } from '@/components/SearchResultsSection/SearchResultsSection'
|
||||
|
||||
type Props = {
|
||||
blocks: SearchResultItem<UnbodyImageBlock | UnbodyTextBlock>[]
|
||||
data: SearchHook<UnbodyTextBlock | UnbodyImageBlock>
|
||||
}
|
||||
|
||||
export default function RelatedContent({ blocks }: Props) {
|
||||
export default function RelatedContent({ data }: Props) {
|
||||
return (
|
||||
<Container>
|
||||
<Section title={'Related Content'} matches={blocks?.length}>
|
||||
<SearchResultsSection
|
||||
resultSize={data.data.length}
|
||||
loading={data.loading}
|
||||
title={'Related Content'}
|
||||
>
|
||||
<Grid>
|
||||
{blocks.map(
|
||||
{data.data.map(
|
||||
(block: SearchResultItem<UnbodyImageBlock | UnbodyTextBlock>) => {
|
||||
if (!block.doc.document || !block.doc.document[0]) return null
|
||||
|
||||
@ -23,7 +26,6 @@ export default function RelatedContent({ blocks }: Props) {
|
||||
if (UnbodyGraphQl.UnbodyDocumentTypeNames.GoogleDoc) {
|
||||
refArticle = block.doc.document[0]
|
||||
}
|
||||
|
||||
switch (block.doc.__typename) {
|
||||
case UnbodyGraphQl.UnbodyDocumentTypeNames.TextBlock:
|
||||
return <TextBlock doc={block.doc} />
|
||||
@ -34,7 +36,7 @@ export default function RelatedContent({ blocks }: Props) {
|
||||
},
|
||||
)}
|
||||
</Grid>
|
||||
</Section>
|
||||
</SearchResultsSection>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
35
src/components/SearchResultsSection/SearchResultsSection.tsx
Normal file
35
src/components/SearchResultsSection/SearchResultsSection.tsx
Normal file
@ -0,0 +1,35 @@
|
||||
import { Section } from '@/components/Section/Section'
|
||||
import React, { PropsWithChildren } from 'react'
|
||||
import { Typography } from '@acid-info/lsd-react'
|
||||
|
||||
type Props = PropsWithChildren<{
|
||||
resultSize: number
|
||||
loading: boolean
|
||||
title: string
|
||||
}>
|
||||
|
||||
export const SearchResultsSection = ({
|
||||
resultSize,
|
||||
loading,
|
||||
title,
|
||||
children,
|
||||
}: Props) => (
|
||||
<Section
|
||||
title={title}
|
||||
subtitle={
|
||||
loading ? (
|
||||
<Typography genericFontFamily="sans-serif" variant="body2">
|
||||
Loading...
|
||||
</Typography>
|
||||
) : (
|
||||
<>
|
||||
<Typography genericFontFamily="sans-serif" variant="body2">
|
||||
{resultSize} matches
|
||||
</Typography>
|
||||
</>
|
||||
)
|
||||
}
|
||||
>
|
||||
{children}
|
||||
</Section>
|
||||
)
|
@ -1,25 +1,29 @@
|
||||
import { Typography } from '@acid-info/lsd-react'
|
||||
import styled from '@emotion/styled'
|
||||
import { PropsWithChildren } from 'react'
|
||||
import React, { PropsWithChildren } from 'react'
|
||||
|
||||
type Props = PropsWithChildren<{
|
||||
title: string
|
||||
matches?: number | string
|
||||
subtitle?: string | React.ReactNode
|
||||
}>
|
||||
|
||||
export const Section = ({ title, matches, children, ...props }: Props) => {
|
||||
export const Section = ({ title, subtitle, children, ...props }: Props) => {
|
||||
return (
|
||||
<section style={{ width: '100%' }} {...props}>
|
||||
<Container>
|
||||
<Typography genericFontFamily="sans-serif" variant="body2">
|
||||
{title}
|
||||
</Typography>
|
||||
{matches && (
|
||||
{subtitle && (
|
||||
<>
|
||||
<Typography variant="body2">•</Typography>
|
||||
<Typography genericFontFamily="sans-serif" variant="body2">
|
||||
{matches} matches
|
||||
</Typography>
|
||||
{typeof subtitle === 'string' ? (
|
||||
<Typography genericFontFamily="sans-serif" variant="body2">
|
||||
subtitle
|
||||
</Typography>
|
||||
) : (
|
||||
subtitle
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Container>
|
||||
|
@ -54,26 +54,22 @@ export default function SearchPage({
|
||||
|
||||
useEffect(() => {
|
||||
if (mounted) {
|
||||
if (query.length > 0 || topics.length > 0) {
|
||||
const serchArgs = [
|
||||
extractQueryFromQuery(router.query),
|
||||
extractTopicsFromQuery(router.query),
|
||||
]
|
||||
articles.search(...(serchArgs as [string, string[]]))
|
||||
blocks.search(...(serchArgs as [string, string[]]))
|
||||
} else {
|
||||
articles.reset(initialArticles)
|
||||
blocks.reset(initialBlocks)
|
||||
}
|
||||
const serchArgs = [
|
||||
extractQueryFromQuery(router.query),
|
||||
extractTopicsFromQuery(router.query),
|
||||
]
|
||||
articles.search(...(serchArgs as [string, string[]]))
|
||||
blocks.search(...(serchArgs as [string, string[]]))
|
||||
} else {
|
||||
hasUpdated.current = true
|
||||
articles.reset(initialArticles)
|
||||
blocks.reset(initialBlocks)
|
||||
}
|
||||
}, [mounted, router.query])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={{ minHeight: '80vh' }}>
|
||||
<RelatedArticles data={articles} />
|
||||
{blocks.data?.length && <RelatedContent blocks={blocks.data} />}
|
||||
<RelatedContent data={blocks} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user