page grid update: load less data
This commit is contained in:
1 parent
1318328fe7
commit
e800de1f92
5 files changed
+100
-89
No files matched your search
+2
-4
@@ -6,12 +6,12 @@ import { HudozkaTitle } from 'src/components/HudozkaTitle'
|
||||
import { MetaBuilder } from 'src/lib/meta'
|
||||
import { getPagesCardsByTags } from 'src/rest'
|
||||
import { NextPage } from 'next'
|
||||
import { IPage, IMeta } from 'src/types'
|
||||
import { IMeta, PageCardData } from 'src/types'
|
||||
|
||||
interface IProps {
|
||||
title: string
|
||||
meta: IMeta
|
||||
items: IPage[]
|
||||
items: PageCardData[]
|
||||
}
|
||||
|
||||
const Index: NextPage<IProps> = props => (
|
||||
@@ -32,8 +32,6 @@ const Index: NextPage<IProps> = props => (
|
||||
|
||||
<PageGrid
|
||||
items={props.items}
|
||||
prevPage={null}
|
||||
nextPage={null}
|
||||
/>
|
||||
</App>
|
||||
)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { ImageDefinition, IPage, ImageSize } from 'src/types'
|
||||
import { Pager } from '../Pager'
|
||||
import { ImageSize, PageCardData } from 'src/types'
|
||||
import { CardGrid } from '../CardGrid'
|
||||
import { Card, CardLayout } from '../Card'
|
||||
import { Date } from './Date'
|
||||
@@ -7,87 +6,56 @@ import { Block } from '../Block'
|
||||
import { Spacer } from '../Spacer'
|
||||
import { imageSrcSet } from 'src/lib/image'
|
||||
|
||||
function getImage(image?: ImageDefinition) {
|
||||
const sizes = [ImageSize.large, ImageSize.medium, ImageSize.small]
|
||||
if (!image) {
|
||||
const defaultSrc = process.env.APP_CARD_DEFAULT_IMAGE
|
||||
return {
|
||||
src: defaultSrc,
|
||||
srcSet: imageSrcSet(defaultSrc, sizes)
|
||||
}
|
||||
}
|
||||
|
||||
const src = image.artifacts.large.src
|
||||
return {
|
||||
src,
|
||||
srcSet: imageSrcSet(src, sizes)
|
||||
}
|
||||
}
|
||||
|
||||
export type PageGridProps = {
|
||||
items: IPage[]
|
||||
nextPage: number | null
|
||||
prevPage: number | null
|
||||
items: PageCardData[]
|
||||
}
|
||||
|
||||
export const PageGrid: React.FC<PageGridProps> = ({ items, nextPage, prevPage, ...props }) => {
|
||||
const nextHref = nextPage ? `/articles/${nextPage}` : null
|
||||
let prevHref = prevPage ? `/articles/${prevPage}` : null
|
||||
if (prevPage === 1) {
|
||||
prevHref = '/'
|
||||
}
|
||||
|
||||
export const PageGrid: React.FC<PageGridProps> = props => {
|
||||
return (
|
||||
<>
|
||||
<CardGrid
|
||||
style={{
|
||||
marginBottom: 'var(--size-m)',
|
||||
}}
|
||||
>
|
||||
{items.map((item, i) => {
|
||||
const gridColumn = item.featured ? 'span 2' : 'auto'
|
||||
const layout: CardLayout = item.featured ? 'featured' : 'simple'
|
||||
const { src, srcSet } = getImage(item.preview)
|
||||
<CardGrid
|
||||
style={{
|
||||
marginBottom: 'var(--size-m)',
|
||||
}}
|
||||
>
|
||||
{props.items.map((item, i) => {
|
||||
const gridColumn = item.featured ? 'span 2' : 'auto'
|
||||
const layout: CardLayout = item.featured ? 'featured' : 'simple'
|
||||
const src = item.coverSrc
|
||||
const srcSet = imageSrcSet(item.coverSrc, [ImageSize.large, ImageSize.medium, ImageSize.small])
|
||||
|
||||
const content = !item.featured
|
||||
? (
|
||||
<Block
|
||||
direction={'vertical'}
|
||||
>
|
||||
{item.title}
|
||||
<Spacer />
|
||||
<Date style={{
|
||||
marginTop: 'var(--size-m)',
|
||||
}}>{item.date}</Date>
|
||||
</Block>
|
||||
) : (
|
||||
item.title
|
||||
)
|
||||
|
||||
return (
|
||||
<Card
|
||||
key={i}
|
||||
href={item.url}
|
||||
img={{
|
||||
alt: item.title,
|
||||
src,
|
||||
srcSet,
|
||||
}}
|
||||
layout={layout}
|
||||
style={{
|
||||
gridColumn,
|
||||
}}
|
||||
const content = !item.featured
|
||||
? (
|
||||
<Block
|
||||
direction={'vertical'}
|
||||
>
|
||||
{content}
|
||||
</Card>
|
||||
{item.title}
|
||||
<Spacer />
|
||||
<Date style={{
|
||||
marginTop: 'var(--size-m)',
|
||||
}}>{item.date}</Date>
|
||||
</Block>
|
||||
) : (
|
||||
item.title
|
||||
)
|
||||
})}
|
||||
</CardGrid>
|
||||
|
||||
<Pager
|
||||
nextHref={nextHref}
|
||||
prevHref={prevHref}
|
||||
/>
|
||||
</>
|
||||
return (
|
||||
<Card
|
||||
key={i}
|
||||
href={item.url}
|
||||
img={{
|
||||
alt: item.title,
|
||||
src,
|
||||
srcSet,
|
||||
}}
|
||||
layout={layout}
|
||||
style={{
|
||||
gridColumn,
|
||||
}}
|
||||
>
|
||||
{content}
|
||||
</Card>
|
||||
)
|
||||
})}
|
||||
</CardGrid>
|
||||
)
|
||||
}
|
||||
@@ -1,3 +1,13 @@
|
||||
export function isPartOfPath(part: string, path: string): boolean {
|
||||
return path.startsWith(part)
|
||||
}
|
||||
|
||||
export function queryList(key: string, values: string[]): string {
|
||||
if (values.length === 0) {
|
||||
return ''
|
||||
}
|
||||
|
||||
return values
|
||||
.map(value => `${key}=${value}`)
|
||||
.join('&')
|
||||
}
|
||||
+36
-9
@@ -1,26 +1,53 @@
|
||||
import { createApiUrl, requestGet, IResponseItems } from './next-lib'
|
||||
import { IPage } from './types'
|
||||
import { IPage, PageCardData } from './types'
|
||||
import { queryList } from './lib/url'
|
||||
|
||||
export type QuerySlice = {
|
||||
skip: number
|
||||
limit: number
|
||||
sortBy: string
|
||||
fields?: string[]
|
||||
}
|
||||
|
||||
export async function getPagesByTags(tags: string[], { skip, limit, sortBy }: QuerySlice) {
|
||||
const tagQuery = tags
|
||||
.map(x => `tag=${x}`)
|
||||
.join('&')
|
||||
export async function getPagesByTags<T = IPage>(tags: string[], { skip, limit, sortBy, fields }: QuerySlice) {
|
||||
const tag = queryList('tag', tags)
|
||||
const field = queryList('field', fields ?? [])
|
||||
|
||||
const url = `/api/pages/tags?${tagQuery}&skip=${skip}&limit=${limit}&sortBy=${sortBy}`
|
||||
const res = await requestGet<IResponseItems<IPage>>(createApiUrl(url), null)
|
||||
const url = `/api/pages/tags?${tag}&${field}&skip=${skip}&limit=${limit}&sortBy=${sortBy}`
|
||||
const res = await requestGet<IResponseItems<T>>(createApiUrl(url), null)
|
||||
|
||||
return res?.items
|
||||
}
|
||||
|
||||
export async function getPagesCardsByTags(tags: string[]) {
|
||||
export async function getPagesCardsByTags(tags: string[]): Promise<PageCardData[]> {
|
||||
type ResponseItem = {
|
||||
url: string
|
||||
title: string
|
||||
featured: boolean
|
||||
date: string
|
||||
coverSrc: string
|
||||
}
|
||||
|
||||
const skip = 0
|
||||
const limit = 1000
|
||||
const fields = [
|
||||
'url',
|
||||
'title',
|
||||
'featured',
|
||||
'date',
|
||||
'coverSrc'
|
||||
]
|
||||
|
||||
return getPagesByTags(tags, { skip, limit, sortBy: '-date' })
|
||||
const items = await getPagesByTags<ResponseItem>(tags, { fields, skip, limit, sortBy: '-date' })
|
||||
if (!Array.isArray(items)) {
|
||||
return []
|
||||
}
|
||||
|
||||
return items.map(item => ({
|
||||
url: item.url,
|
||||
title: item.title,
|
||||
featured: item.featured,
|
||||
date: new Date(item.date),
|
||||
coverSrc: item.coverSrc,
|
||||
}))
|
||||
}
|
||||
@@ -8,6 +8,14 @@ export interface IBreadcumbsPart {
|
||||
href: string
|
||||
}
|
||||
|
||||
export type PageCardData = {
|
||||
url: string
|
||||
title: string
|
||||
featured: boolean
|
||||
date: Date
|
||||
coverSrc: string
|
||||
}
|
||||
|
||||
export interface IPage {
|
||||
id: string
|
||||
title: string
|
||||
|
||||
Reference in new issue
Block a user