diff --git a/src/components/PostList/PostList.tsx b/src/components/PostList/PostList.tsx index 0227f77..855b58b 100644 --- a/src/components/PostList/PostList.tsx +++ b/src/components/PostList/PostList.tsx @@ -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} > - + @@ -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)` diff --git a/src/components/RelatedArticles/RelatedArticles.tsx b/src/components/RelatedArticles/RelatedArticles.tsx index 19aa434..b2d5a4c 100644 --- a/src/components/RelatedArticles/RelatedArticles.tsx +++ b/src/components/RelatedArticles/RelatedArticles.tsx @@ -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 @@ -12,32 +11,29 @@ type 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), - })) - } + 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} /> } -
+
) } diff --git a/src/components/RelatedContent/RelatedContent.tsx b/src/components/RelatedContent/RelatedContent.tsx index bd4af88..449a938 100644 --- a/src/components/RelatedContent/RelatedContent.tsx +++ b/src/components/RelatedContent/RelatedContent.tsx @@ -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[] + data: SearchHook } - -export default function RelatedContent({ blocks }: Props) { +export default function RelatedContent({ data }: Props) { return ( -
+ - {blocks.map( + {data.data.map( (block: SearchResultItem) => { 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 @@ -34,7 +36,7 @@ export default function RelatedContent({ blocks }: Props) { }, )} -
+
) } diff --git a/src/components/SearchResultsSection/SearchResultsSection.tsx b/src/components/SearchResultsSection/SearchResultsSection.tsx new file mode 100644 index 0000000..950ad0f --- /dev/null +++ b/src/components/SearchResultsSection/SearchResultsSection.tsx @@ -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) => ( +
+ Loading... + + ) : ( + <> + + {resultSize} matches + + + ) + } + > + {children} +
+) diff --git a/src/components/Section/Section.tsx b/src/components/Section/Section.tsx index abd0ff2..5e6d98b 100644 --- a/src/components/Section/Section.tsx +++ b/src/components/Section/Section.tsx @@ -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 (
{title} - {matches && ( + {subtitle && ( <> - - {matches} matches - + {typeof subtitle === 'string' ? ( + + subtitle + + ) : ( + subtitle + )} )} diff --git a/src/pages/search.tsx b/src/pages/search.tsx index 5e13863..351f4f3 100644 --- a/src/pages/search.tsx +++ b/src/pages/search.tsx @@ -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 ( -
+
- {blocks.data?.length && } +
) }