home page strapi integration

This commit is contained in:
tmshv committed 2021-02-16 20:04:32 +03:00
1 parent 91982b8c99
commit 87f4f6a1b8
8 files changed
+101 -136

No files matched your search

+11 -7
View File
@@ -4,9 +4,10 @@ import { Meta } from 'src/components/Meta'
import { PageGrid } from 'src/components/PageGrid'
import { HudozkaTitle } from 'src/components/HudozkaTitle'
import { MetaBuilder } from 'src/lib/meta'
import { getPagesCardsByTags } from 'src/rest'
import { NextPage } from 'next'
import { IMeta, PageCardData, PageCardDto } from 'src/types'
import { apiGet } from '@/next-lib'
import { createHomeCards } from '@/remote/factory'
type Props = {
title: string
@@ -16,11 +17,16 @@ type Props = {
const Index: NextPage<Props> = props => {
const items = props.items.map<PageCardData>(item => ({
id: item.id,
url: item.url,
title: item.title,
featured: item.featured,
date: new Date(item.date),
coverSrc: item.cover?.src,
cover: {
src: item.cover.src,
width: item.cover.width,
height: item.cover.height,
}
}))
return (
@@ -47,11 +53,9 @@ const Index: NextPage<Props> = props => {
}
export const getStaticProps = async () => {
const items = await getPagesCardsByTags([
'event',
'album',
'post',
])
const url = 'https://hudozka.tmshv.com/home'
const items = await apiGet(createHomeCards)(url, [])
const title = 'Шлиссельбургская ДХШ'
const meta = (new MetaBuilder())
.setTitle(title)
+2 -11
View File
@@ -2,7 +2,6 @@ import s from './styles.module.css'
import cx from 'classnames'
import Link from 'next/link'
import { Image } from '../Image'
const layoutClass = {
simple: s.simple,
@@ -13,11 +12,7 @@ export type CardLayout = 'simple' | 'featured'
export type CardProps = {
style?: React.CSSProperties
href: string
img: {
alt: string
src: string
srcSet: string
}
cover: React.ReactNode
layout: CardLayout
}
@@ -26,11 +21,7 @@ export const Card: React.FC<CardProps> = props => (
<Link href={props.href}>
<a>
<div className={s.image}>
<Image
alt={props.img.alt}
src={props.img.src}
srcSet={props.img.srcSet}
/>
{props.cover}
</div>
<div className={s.body}>
-12
View File
@@ -31,18 +31,6 @@
height: 100%;
}
.image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: all 150ms ease-out;
position: absolute;
top: 0;
left: 0;
}
.body {
background-color: var(--color-back);
padding: var(--size-m);
+43 -64
View File
@@ -1,3 +1,4 @@
import Image from 'next/image'
import { ImageSize, PageCardData } from 'src/types'
import { CardGrid } from '../CardGrid'
import { Card, CardLayout } from '../Card'
@@ -13,75 +14,53 @@ export type PageGridProps = {
}
export const PageGrid: React.FC<PageGridProps> = props => {
const [page, setPage] = useState(1)
const i = page * 24
const items = props.items.slice(0, i)
const onMore = useCallback(() => {
setPage(x => x + 1)
}, [])
const hasMore = i < props.items.length
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 cover = item.coverSrc ?? process.env.APP_CARD_DEFAULT_IMAGE
const src = cover
const srcSet = imageSrcSet(src, [ImageSize.large, ImageSize.medium, ImageSize.small])
<CardGrid
style={{
marginBottom: 'var(--size-m)',
}}
>
{props.items.map(item => {
const gridColumn = item.featured ? 'span 2' : 'auto'
const layout: CardLayout = item.featured ? 'featured' : 'simple'
const content = !item.featured
? (
<Block
direction={'vertical'}
>
{item.title}
<Spacer />
const content = !item.featured
? (
<Block
direction={'vertical'}
>
{item.title}
<Spacer />
{!item.date ? null : (
<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,
}}
>
{content}
</Card>
)}
</Block>
) : (
item.title
)
})}
</CardGrid>
<Block direction={'horizontal'} style={{
marginTop: 'var(--size-l)'
}}>
<Spacer />
<Button
disabled={!hasMore}
onClick={onMore}
style={{
flex: 2,
}}
>Загрузить ещё</Button>
<Spacer />
</Block>
</>
return (
<Card
key={item.id}
href={item.url}
cover={(
<Image
layout={'fill'}
objectFit={'cover'}
src={item.cover.src}
/>
)}
layout={layout}
style={{
gridColumn,
}}
>
{content}
</Card>
)
})}
</CardGrid>
)
}
+27 -2
View File
@@ -1,7 +1,7 @@
import { getResizedUrl, imageSrc } from "@/lib/image";
import { IPage, Token } from "@/types";
import { IPage, PageCardDto, Token } from "@/types";
import { asItem } from "./lib";
import { StrapiComponent, StrapiPage } from "./types";
import { StrapiComponent, StrapiHome, StrapiPage, StrapiPageCard } from "./types";
export function createPageTokens(components: StrapiComponent[]): Token[] {
return components.map(component => {
@@ -86,4 +86,29 @@ export function createPage(res: StrapiPage | StrapiPage[]): IPage {
// breadcrumb?: [],
featured: false,
}
}
function isCardFeatured(card: StrapiPageCard): boolean {
return card.layout === 'big' || card.layout === 'medium'
}
export function createHomeCards(data: StrapiHome): PageCardDto[] {
// const cover = item.coverSrc ?? process.env.APP_CARD_DEFAULT_IMAGE
return data.cards.map(card => {
return {
id: card.id,
// id: card.page.id,
url: card.page.slug,
title: card.page.title,
featured: isCardFeatured(card),
date: card.page.date,
cover: {
src: card.page.cover.url,
width: card.page.cover.width,
height: card.page.cover.height,
alt: '',
}
}
})
}
+15
View File
@@ -110,4 +110,19 @@ export type StrapiPage = {
// ],
// "breadcrumbs": [],
// "breadcrumbRelations": []
}
export type StrapiHome = {
id: number,
title: string
cards: StrapiPageCard[]
// "created_at": "2021-02-04T04:12:38.291Z",
// "updated_at": "2021-02-04T16:28:30.961Z",
}
export type StrapiPageCard = {
__component: 'hudozka.page-card',
id: number,
page: StrapiPage,
layout: 'small' | 'medium' | 'big',
}
-39
View File
@@ -1,39 +0,0 @@
import { createApiUrl, requestGet, IResponseItems } from './next-lib'
import { IPage, PageCardData, PageCardDto } from './types'
import { queryList } from './lib/url'
export type QuerySlice = {
skip: number
limit: number
sortBy: string
fields?: string[]
}
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?${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[]): Promise<PageCardDto[]> {
const skip = 0
const limit = 1000
const fields = [
'url',
'title',
'featured',
'date',
'cover'
]
const items = await getPagesByTags<PageCardDto>(tags, { fields, skip, limit, sortBy: '-date' })
if (!Array.isArray(items)) {
return []
}
return items
}
+3 -1
View File
@@ -9,14 +9,16 @@ export interface IBreadcumbsPart {
}
export type PageCardData = {
id: number
url: string
title: string
date: Date
featured?: boolean
coverSrc?: string
cover?: ImageDefinition
}
export type PageCardDto = {
id: number
url: string
title: string
featured: boolean