mirror of
https://github.com/vercel/commerce.git
synced 2025-07-23 04:36:49 +00:00
feat: get-blog-list
This commit is contained in:
@@ -9,6 +9,9 @@ import type {
|
|||||||
GetAllProductsOperation,
|
GetAllProductsOperation,
|
||||||
GetProductOperation,
|
GetProductOperation,
|
||||||
} from '../types/product'
|
} from '../types/product'
|
||||||
|
import type {
|
||||||
|
GetAllBlogsOperation
|
||||||
|
} from '../types/blogs'
|
||||||
import type { APIProvider, CommerceAPI } from '.'
|
import type { APIProvider, CommerceAPI } from '.'
|
||||||
import { GetAllCollectionsOperation } from '@commerce/types/collection';
|
import { GetAllCollectionsOperation } from '@commerce/types/collection';
|
||||||
|
|
||||||
@@ -27,7 +30,7 @@ export const OPERATIONS = [
|
|||||||
'getProduct',
|
'getProduct',
|
||||||
'getAllFacets',
|
'getAllFacets',
|
||||||
'getAllCollections',
|
'getAllCollections',
|
||||||
|
'getAllBlogs'
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
export const defaultOperations = OPERATIONS.reduce((ops, k) => {
|
export const defaultOperations = OPERATIONS.reduce((ops, k) => {
|
||||||
@@ -144,6 +147,24 @@ export type Operations<P extends APIProvider> = {
|
|||||||
): Promise<T['data']>
|
): Promise<T['data']>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getAllBlogs: {
|
||||||
|
<T extends GetAllBlogsOperation>(opts: {
|
||||||
|
variables?: T['variables']
|
||||||
|
config?: P['config']
|
||||||
|
preview?: boolean
|
||||||
|
}): Promise<T['data']>
|
||||||
|
|
||||||
|
<T extends GetAllBlogsOperation>(
|
||||||
|
opts: {
|
||||||
|
variables?: T['variables']
|
||||||
|
config?: P['config']
|
||||||
|
preview?: boolean
|
||||||
|
} & OperationOptions
|
||||||
|
): Promise<T['data']>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
getProduct: {
|
getProduct: {
|
||||||
<T extends GetProductOperation>(opts: {
|
<T extends GetProductOperation>(opts: {
|
||||||
variables: T['variables']
|
variables: T['variables']
|
||||||
|
26
framework/commerce/types/blogs.ts
Normal file
26
framework/commerce/types/blogs.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { SearchResultSortParameter } from "@framework/schema";
|
||||||
|
import { Asset, BlogTranslation, Maybe, Product } from './../../vendure/schema.d';
|
||||||
|
|
||||||
|
export type BlogList = Node &{
|
||||||
|
id: string
|
||||||
|
featuredAsset?: Maybe<Asset>
|
||||||
|
isHidden:Boolean
|
||||||
|
translations: Array<BlogTranslation>
|
||||||
|
authorName: string
|
||||||
|
authorAvatarAsset:Array<Asset>
|
||||||
|
relevantProducts: Product
|
||||||
|
}
|
||||||
|
export type BlogsType = {
|
||||||
|
items: BlogList
|
||||||
|
totalItems: number
|
||||||
|
}
|
||||||
|
export type GetAllBlogsOperation<T extends BlogsType = BlogsType> = {
|
||||||
|
data: { items: T['items'][] }
|
||||||
|
variables: {
|
||||||
|
take?: number
|
||||||
|
skip?: number
|
||||||
|
sort?: SearchResultSortParameter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@@ -11,7 +11,7 @@ import getProduct from './operations/get-product'
|
|||||||
import getSiteInfo from './operations/get-site-info'
|
import getSiteInfo from './operations/get-site-info'
|
||||||
import login from './operations/login'
|
import login from './operations/login'
|
||||||
import fetchGraphqlApi from './utils/fetch-graphql-api'
|
import fetchGraphqlApi from './utils/fetch-graphql-api'
|
||||||
|
import getAllBlogs from './operations/get-all-blogs'
|
||||||
|
|
||||||
export interface VendureConfig extends CommerceAPIConfig {}
|
export interface VendureConfig extends CommerceAPIConfig {}
|
||||||
|
|
||||||
@@ -44,6 +44,7 @@ const operations = {
|
|||||||
getProduct,
|
getProduct,
|
||||||
getAllFacets,
|
getAllFacets,
|
||||||
getAllCollections,
|
getAllCollections,
|
||||||
|
getAllBlogs
|
||||||
}
|
}
|
||||||
|
|
||||||
export const provider = { config, operations }
|
export const provider = { config, operations }
|
||||||
|
52
framework/vendure/api/operations/get-all-blogs.ts
Normal file
52
framework/vendure/api/operations/get-all-blogs.ts
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import { OperationContext } from '@commerce/api/operations'
|
||||||
|
import { Provider, VendureConfig } from '..'
|
||||||
|
import { GetAllBlogsQuery,BlogList } from '../../schema'
|
||||||
|
import { getAllBlogsQuery } from '../../utils/queries/get-all-blog-query'
|
||||||
|
|
||||||
|
export type BlogVariables = { take?: number,skip?:number }
|
||||||
|
|
||||||
|
export default function getAllBlogsOperation({
|
||||||
|
commerce,
|
||||||
|
}: OperationContext<Provider>) {
|
||||||
|
async function getAllBlogs(opts?: {
|
||||||
|
variables?: BlogVariables
|
||||||
|
config?: Partial<VendureConfig>
|
||||||
|
preview?: boolean
|
||||||
|
}): Promise<{ blogs: GetAllBlogsQuery,totalItems:number }>
|
||||||
|
|
||||||
|
async function getAllBlogs({
|
||||||
|
query = getAllBlogsQuery,
|
||||||
|
variables: { ...vars } = {},
|
||||||
|
config: cfg,
|
||||||
|
}: {
|
||||||
|
query?: string
|
||||||
|
variables?: BlogVariables
|
||||||
|
config?: Partial<VendureConfig>
|
||||||
|
preview?: boolean
|
||||||
|
} = {}): Promise<{ blogs: GetAllBlogsQuery | any[] ,totalItems?:number }> {
|
||||||
|
const config = commerce.getConfig(cfg)
|
||||||
|
const variables = {
|
||||||
|
options: {
|
||||||
|
take: vars.take,
|
||||||
|
skip: vars.skip,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const { data } = await config.fetch<GetAllBlogsQuery>(query, {
|
||||||
|
variables,
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
blogs: data?.blogs?.items?.map((val:BlogList)=>({
|
||||||
|
id: val.id,
|
||||||
|
title: val.translations[0]?.title,
|
||||||
|
imageSrc: val.featuredAsset?.preview ?? null,
|
||||||
|
slug: val.translations[0]?.slug,
|
||||||
|
description: val.translations[0]?.description,
|
||||||
|
isHidden: val.isHidden
|
||||||
|
})),
|
||||||
|
totalItems: data?.blogs?.totalItems || null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return getAllBlogs
|
||||||
|
}
|
41
framework/vendure/schema.d.ts
vendored
41
framework/vendure/schema.d.ts
vendored
@@ -2312,6 +2312,46 @@ export type Product = Node & {
|
|||||||
customFields?: Maybe<Scalars['JSON']>
|
customFields?: Maybe<Scalars['JSON']>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type BlogList = Node &{
|
||||||
|
id: ID!
|
||||||
|
createdAt: DateTime!
|
||||||
|
updatedAt: DateTime!
|
||||||
|
featuredAsset?: Maybe<Asset>
|
||||||
|
isHidden:Boolean
|
||||||
|
translations: Array<BlogTranslation>
|
||||||
|
authorName: Scalars['String']
|
||||||
|
authorAvatarAsset:Array<Asset>
|
||||||
|
relevantProducts: Product
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BlogTranslation = {
|
||||||
|
__typename?: 'BlogTranslation'
|
||||||
|
id: Scalars['ID']
|
||||||
|
createdAt: Scalars['DateTime']
|
||||||
|
updatedAt: Scalars['DateTime']
|
||||||
|
languageCode: LanguageCode
|
||||||
|
title: Scalars['String']
|
||||||
|
slug: Scalars['String']
|
||||||
|
description: Scalars['String']
|
||||||
|
content: Scalars['String']
|
||||||
|
}
|
||||||
|
|
||||||
|
export type GetAllBlogsQuery = PaginatedList & {
|
||||||
|
blogs: { __typename?: 'BlogList' } & {
|
||||||
|
items: Array<{ __typename?: 'Blog' } & BlogList!>,
|
||||||
|
'totalItems'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type QueryBlogs = {
|
||||||
|
options: BlogListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BlogListOptions = {
|
||||||
|
skip?: Maybe<Scalars['Int']>
|
||||||
|
take?: Maybe<Scalars['Int']>
|
||||||
|
}
|
||||||
|
|
||||||
export type ProductTranslation = {
|
export type ProductTranslation = {
|
||||||
__typename?: 'ProductTranslation'
|
__typename?: 'ProductTranslation'
|
||||||
id: Scalars['ID']
|
id: Scalars['ID']
|
||||||
@@ -3364,3 +3404,4 @@ export type SearchQuery = { __typename?: 'Query' } & {
|
|||||||
'totalItems'
|
'totalItems'
|
||||||
> & { items: Array<{ __typename?: 'SearchResult' } & SearchResultFragment> }
|
> & { items: Array<{ __typename?: 'SearchResult' } & SearchResultFragment> }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
framework/vendure/utils/queries/get-all-blog-query.ts
Normal file
20
framework/vendure/utils/queries/get-all-blog-query.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
export const getAllBlogsQuery = /* GraphQL */ `
|
||||||
|
query GetBlogs ($options: BlogListOptions){
|
||||||
|
blogs(options: $options){
|
||||||
|
totalItems
|
||||||
|
items {
|
||||||
|
id
|
||||||
|
isHidden
|
||||||
|
featuredAsset {
|
||||||
|
preview
|
||||||
|
}
|
||||||
|
translations {
|
||||||
|
title
|
||||||
|
slug
|
||||||
|
description
|
||||||
|
content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
@@ -1,14 +1,72 @@
|
|||||||
|
import commerce from '@lib/api/commerce';
|
||||||
|
import { GetStaticPropsContext } from 'next';
|
||||||
import { Layout } from 'src/components/common';
|
import { Layout } from 'src/components/common';
|
||||||
import { BlogsList, FeaturedCardBlog, BlogHeading, BlogBreadCrumb } from 'src/components/modules/blogs';
|
import { BlogCardProps } from 'src/components/common/CardBlog/CardBlog';
|
||||||
|
import { BlogBreadCrumb, BlogHeading, BlogsList, FeaturedCardBlog } from 'src/components/modules/blogs';
|
||||||
|
import { DEFAULT_BLOG_PAGE_SIZE } from "src/utils/constanst.utils";
|
||||||
|
import { getAllPromies } from 'src/utils/funtion.utils';
|
||||||
|
import { PromiseWithKey } from 'src/utils/types.utils';
|
||||||
|
|
||||||
export default function BlogsPage() {
|
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
blogsResult: { blogs: BlogCardProps[] },
|
||||||
|
totalItems: number
|
||||||
|
}
|
||||||
|
export default function BlogsPage({blogsResult,totalItems}:Props) {
|
||||||
return(
|
return(
|
||||||
<>
|
<>
|
||||||
<BlogBreadCrumb />
|
<BlogBreadCrumb />
|
||||||
<BlogHeading />
|
<BlogHeading />
|
||||||
<FeaturedCardBlog />
|
<FeaturedCardBlog
|
||||||
<BlogsList />
|
title={blogsResult.blogs[0].title}
|
||||||
|
imgSrc={blogsResult.blogs[0].imageSrc ?? ''}
|
||||||
|
content={blogsResult.blogs[0].description}
|
||||||
|
/>
|
||||||
|
<BlogsList blogList={blogsResult.blogs} total={totalItems} />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
BlogsPage.Layout = Layout
|
|
||||||
|
|
||||||
|
export async function getStaticProps({
|
||||||
|
preview,
|
||||||
|
locale,
|
||||||
|
locales,
|
||||||
|
}: GetStaticPropsContext) {
|
||||||
|
const config = { locale, locales }
|
||||||
|
let promisesWithKey = [] as PromiseWithKey[]
|
||||||
|
let props = {} as any;
|
||||||
|
|
||||||
|
|
||||||
|
// Blogs
|
||||||
|
const blogsPromise = commerce.getAllBlogs({
|
||||||
|
variables: {
|
||||||
|
take: DEFAULT_BLOG_PAGE_SIZE
|
||||||
|
},
|
||||||
|
config,
|
||||||
|
preview,
|
||||||
|
})
|
||||||
|
promisesWithKey.push({ key: 'blogsResult', promise: blogsPromise })
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
const promises = getAllPromies(promisesWithKey)
|
||||||
|
const rs = await Promise.all(promises)
|
||||||
|
|
||||||
|
promisesWithKey.map((item, index) => {
|
||||||
|
props[item.key] = item.keyResult ? rs[index][item.keyResult] : rs[index]
|
||||||
|
return null
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
props,
|
||||||
|
revalidate: 60
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BlogsPage.Layout = Layout
|
||||||
|
@@ -10,12 +10,12 @@ import { CODE_FACET_DISCOUNT, CODE_FACET_FEATURED } from 'src/utils/constanst.ut
|
|||||||
import { getAllFacetValueIdsByParentCode, getAllFacetValuesForFeatuedProducts, getAllPromies, getFreshFacetId } from 'src/utils/funtion.utils';
|
import { getAllFacetValueIdsByParentCode, getAllFacetValuesForFeatuedProducts, getAllPromies, getFreshFacetId } from 'src/utils/funtion.utils';
|
||||||
import { PromiseWithKey } from 'src/utils/types.utils';
|
import { PromiseWithKey } from 'src/utils/types.utils';
|
||||||
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
featuredAndDiscountFacetsValue: FacetValue[],
|
featuredAndDiscountFacetsValue: FacetValue[],
|
||||||
freshProducts: ProductCard[],
|
freshProducts: ProductCard[],
|
||||||
featuredProducts: ProductCard[],
|
featuredProducts: ProductCard[],
|
||||||
collections: Collection[]
|
collections: Collection[]
|
||||||
|
|
||||||
}
|
}
|
||||||
export default function Home({ featuredAndDiscountFacetsValue,
|
export default function Home({ featuredAndDiscountFacetsValue,
|
||||||
freshProducts, featuredProducts,
|
freshProducts, featuredProducts,
|
||||||
@@ -99,7 +99,6 @@ export async function getStaticProps({
|
|||||||
})
|
})
|
||||||
promisesWithKey.push({ key: 'collections', promise: collectionsPromise, keyResult: 'collections' })
|
promisesWithKey.push({ key: 'collections', promise: collectionsPromise, keyResult: 'collections' })
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const promises = getAllPromies(promisesWithKey)
|
const promises = getAllPromies(promisesWithKey)
|
||||||
const rs = await Promise.all(promises)
|
const rs = await Promise.all(promises)
|
||||||
|
@@ -7,16 +7,16 @@ import s from './CardBlog.module.scss'
|
|||||||
|
|
||||||
export interface BlogCardProps extends BlogProps {
|
export interface BlogCardProps extends BlogProps {
|
||||||
// todo: edit when intergrate API
|
// todo: edit when intergrate API
|
||||||
|
isHidden:Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const CardBlog = ({ imageSrc, title, description, slug }: BlogCardProps) => {
|
const CardBlog = ({ imageSrc, title, description, slug }: BlogCardProps) => {
|
||||||
return (
|
return (
|
||||||
<div className={s.cardBlogWarpper}>
|
<div className={s.cardBlogWarpper}>
|
||||||
<Link href={`${ROUTE.BLOG_DETAIL}/${slug}`}>
|
<Link href={`${ROUTE.BLOG_DETAIL}/${slug}`}>
|
||||||
<a>
|
<a>
|
||||||
<div className={s.image}>
|
<div className={s.image}>
|
||||||
<ImgWithLink src={imageSrc} alt="image cardblog" />
|
<ImgWithLink src={imageSrc ?? ''} alt="image cardblog" />
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
.listProductCardSkeleton {
|
.listProductCardSkeleton {
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&.wrap {
|
&.wrap {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
overflow: unset;
|
overflow: unset;
|
||||||
|
@@ -6,7 +6,7 @@ type Props = {
|
|||||||
count?: number
|
count?: number
|
||||||
isWrap?: boolean
|
isWrap?: boolean
|
||||||
}
|
}
|
||||||
const ListProductCardSkeleton = ({ count = 5, isWrap }: Props) => {
|
const ListProductCardSkeleton = ({ count = 3, isWrap }: Props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classNames(s.listProductCardSkeleton, { [s.wrap]: isWrap })}>
|
<div className={classNames(s.listProductCardSkeleton, { [s.wrap]: isWrap })}>
|
||||||
|
1
src/components/hooks/blog/index.ts
Normal file
1
src/components/hooks/blog/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export {default as useGetBlogList }from "./useGetBlogList"
|
24
src/components/hooks/blog/useGetBlogList.tsx
Normal file
24
src/components/hooks/blog/useGetBlogList.tsx
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { GetAllBlogsQuery, QueryBlogs,BlogList } from '@framework/schema'
|
||||||
|
import { getAllBlogsQuery } from '@framework/utils/queries/get-all-blog-query'
|
||||||
|
import gglFetcher from 'src/utils/gglFetcher'
|
||||||
|
import useSWR from 'swr'
|
||||||
|
|
||||||
|
const useGetBlogList = (options?: QueryBlogs) => {
|
||||||
|
const { data, isValidating, ...rest } = useSWR<GetAllBlogsQuery>([getAllBlogsQuery, options], gglFetcher)
|
||||||
|
console.log(isValidating);
|
||||||
|
return {
|
||||||
|
blogs: data?.blogs?.items?.map((val:BlogList)=>({
|
||||||
|
id: val.id,
|
||||||
|
title: val.translations[0]?.title,
|
||||||
|
imageSrc: val.featuredAsset?.preview ?? null,
|
||||||
|
slug: val.translations[0]?.slug,
|
||||||
|
description: val.translations[0]?.description,
|
||||||
|
isHidden: val.isHidden
|
||||||
|
})),
|
||||||
|
totalItems: data?.blogs?.totalItems || null,
|
||||||
|
loading: isValidating,
|
||||||
|
...rest
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useGetBlogList
|
@@ -1,151 +1,89 @@
|
|||||||
import React, { useState } from 'react'
|
import { useRouter } from 'next/router'
|
||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
import CardBlog, { BlogCardProps } from 'src/components/common/CardBlog/CardBlog'
|
import CardBlog, { BlogCardProps } from 'src/components/common/CardBlog/CardBlog'
|
||||||
import PaginationCommon from 'src/components/common/PaginationCommon/PaginationCommon'
|
import PaginationCommon from 'src/components/common/PaginationCommon/PaginationCommon'
|
||||||
|
import { DEFAULT_BLOG_PAGE_SIZE, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils'
|
||||||
import s from "./BlogsList.module.scss"
|
import s from "./BlogsList.module.scss"
|
||||||
import { DEFAULT_BLOG_PAGE_SIZE } from 'src/utils/constanst.utils'
|
import { QueryBlogs } from '@framework/schema'
|
||||||
|
import { useGetBlogList } from 'src/components/hooks/blog'
|
||||||
|
import { getPageFromQuery } from 'src/utils/funtion.utils'
|
||||||
|
import { ListProductCardSkeleton } from 'src/components/common'
|
||||||
|
|
||||||
interface BlogsListProps {
|
interface BlogsListProps {
|
||||||
data?: BlogCardProps[],
|
blogList?: BlogCardProps[],
|
||||||
|
total?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
const BLOGSLIST_DATA = [
|
const DEFAULT_BLOGS_ARGS = {
|
||||||
{
|
options:{
|
||||||
imageSrc: "https://user-images.githubusercontent.com/46085455/133185783-8100ef4e-7a72-4dc1-bb12-2ca46b56b393.png",
|
skip: 1, take: DEFAULT_BLOG_PAGE_SIZE
|
||||||
title: "1",
|
|
||||||
description: "The DEBM diet stands for "+"Delicious Happy Fun Diet"+". This diet was popularized by Robert...",
|
|
||||||
slug: "happy-diet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageSrc: "https://user-images.githubusercontent.com/46085455/133185911-df505d10-fdcd-4312-add3-7c62ad8af71e.png",
|
|
||||||
title: "2",
|
|
||||||
description: "Aloe vera or aloe vera is a green plant, has thorns on the side of the skin with yellowish patches and...",
|
|
||||||
slug: "happy-diet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageSrc: "https://user-images.githubusercontent.com/46085455/133185959-7ad75580-ca6d-4684-83d9-3f64500bbc97.png",
|
|
||||||
title: "3",
|
|
||||||
description: "Dragon fruit is a type of fruit that is a favorite for many people because of its delicious and fresh...",
|
|
||||||
slug: "happy-diet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageSrc: "https://user-images.githubusercontent.com/46085455/133186410-d8718d90-82fb-46cb-a0f2-0ec96356ae89.png",
|
|
||||||
title: "4",
|
|
||||||
description: "The DEBM diet stands for "+"Delicious Happy Fun Diet"+". This diet was popularized by Robert...",
|
|
||||||
slug: "happy-diet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageSrc: "https://user-images.githubusercontent.com/46085455/133186474-b2d89bbc-32ed-4174-a05e-3d388c0a39ff.png",
|
|
||||||
title: "5",
|
|
||||||
description: "Aloe vera or aloe vera is a green plant, has thorns on the side of the skin with yellowish patches and...",
|
|
||||||
slug: "happy-diet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageSrc: "https://user-images.githubusercontent.com/46085455/133186545-d860f4ee-222c-4d72-a876-808af0f397a0.png",
|
|
||||||
title: "6",
|
|
||||||
description: "Dragon fruit is a type of fruit that is a favorite for many people because of its delicious and fresh...",
|
|
||||||
slug: "happy-diet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageSrc: "https://user-images.githubusercontent.com/46085455/133185783-8100ef4e-7a72-4dc1-bb12-2ca46b56b393.png",
|
|
||||||
title: "7",
|
|
||||||
description: "The DEBM diet stands for "+"Delicious Happy Fun Diet"+". This diet was popularized by Robert...",
|
|
||||||
slug: "happy-diet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageSrc: "https://user-images.githubusercontent.com/46085455/133185911-df505d10-fdcd-4312-add3-7c62ad8af71e.png",
|
|
||||||
title: "8",
|
|
||||||
description: "Aloe vera or aloe vera is a green plant, has thorns on the side of the skin with yellowish patches and...",
|
|
||||||
slug: "happy-diet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageSrc: "https://user-images.githubusercontent.com/46085455/133185959-7ad75580-ca6d-4684-83d9-3f64500bbc97.png",
|
|
||||||
title: "9",
|
|
||||||
description: "Dragon fruit is a type of fruit that is a favorite for many people because of its delicious and fresh...",
|
|
||||||
slug: "happy-diet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageSrc: "https://user-images.githubusercontent.com/46085455/133186545-d860f4ee-222c-4d72-a876-808af0f397a0.png",
|
|
||||||
title: "10",
|
|
||||||
description: "Dragon fruit is a type of fruit that is a favorite for many people because of its delicious and fresh...",
|
|
||||||
slug: "happy-diet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageSrc: "https://user-images.githubusercontent.com/46085455/133186410-d8718d90-82fb-46cb-a0f2-0ec96356ae89.png",
|
|
||||||
title: "11",
|
|
||||||
description: "The DEBM diet stands for "+"Delicious Happy Fun Diet"+". This diet was popularized by Robert...",
|
|
||||||
slug: "happy-diet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageSrc: "https://user-images.githubusercontent.com/46085455/133186474-b2d89bbc-32ed-4174-a05e-3d388c0a39ff.png",
|
|
||||||
title: "12",
|
|
||||||
description: "Aloe vera or aloe vera is a green plant, has thorns on the side of the skin with yellowish patches and...",
|
|
||||||
slug: "happy-diet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageSrc: "https://user-images.githubusercontent.com/46085455/133185783-8100ef4e-7a72-4dc1-bb12-2ca46b56b393.png",
|
|
||||||
title: "13",
|
|
||||||
description: "The DEBM diet stands for "+"Delicious Happy Fun Diet"+". This diet was popularized by Robert...",
|
|
||||||
slug: "happy-diet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageSrc: "https://user-images.githubusercontent.com/46085455/133185911-df505d10-fdcd-4312-add3-7c62ad8af71e.png",
|
|
||||||
title: "14",
|
|
||||||
description: "Aloe vera or aloe vera is a green plant, has thorns on the side of the skin with yellowish patches and...",
|
|
||||||
slug: "happy-diet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageSrc: "https://user-images.githubusercontent.com/46085455/133185959-7ad75580-ca6d-4684-83d9-3f64500bbc97.png",
|
|
||||||
title: "15",
|
|
||||||
description: "Dragon fruit is a type of fruit that is a favorite for many people because of its delicious and fresh...",
|
|
||||||
slug: "happy-diet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageSrc: "https://user-images.githubusercontent.com/46085455/133186410-d8718d90-82fb-46cb-a0f2-0ec96356ae89.png",
|
|
||||||
title: "16",
|
|
||||||
description: "The DEBM diet stands for "+"Delicious Happy Fun Diet"+". This diet was popularized by Robert...",
|
|
||||||
slug: "happy-diet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageSrc: "https://user-images.githubusercontent.com/46085455/133186545-d860f4ee-222c-4d72-a876-808af0f397a0.png",
|
|
||||||
title: "17",
|
|
||||||
description: "Dragon fruit is a type of fruit that is a favorite for many people because of its delicious and fresh...",
|
|
||||||
slug: "happy-diet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageSrc: "https://user-images.githubusercontent.com/46085455/133186474-b2d89bbc-32ed-4174-a05e-3d388c0a39ff.png",
|
|
||||||
title: "18",
|
|
||||||
description: "Aloe vera or aloe vera is a green plant, has thorns on the side of the skin with yellowish patches and...",
|
|
||||||
slug: "happy-diet"
|
|
||||||
},
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
const BlogsList = ({ data = BLOGSLIST_DATA }:BlogsListProps) => {
|
|
||||||
const [currentPage, setCurrentPage] = useState(0)
|
|
||||||
const onPageChange = (page:number) => {
|
|
||||||
setCurrentPage(page)
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const BlogsList = ({ blogList,total }:BlogsListProps) => {
|
||||||
|
const router = useRouter();
|
||||||
|
const [initialQueryFlag, setInitialQueryFlag] = useState<boolean>(true)
|
||||||
|
|
||||||
|
const [optionQueryBlog, setOptionQueryBlog] = useState<QueryBlogs>(DEFAULT_BLOGS_ARGS)
|
||||||
|
const { blogs, totalItems, loading } = useGetBlogList(optionQueryBlog);
|
||||||
|
|
||||||
|
// console.log(blogs);
|
||||||
|
|
||||||
|
|
||||||
|
const onPageChange = (page:number) => {
|
||||||
|
router.push({
|
||||||
|
pathname: ROUTE.BLOGS,
|
||||||
|
query: {
|
||||||
|
...router.query,
|
||||||
|
[QUERY_KEY.PAGE]: page
|
||||||
|
}
|
||||||
|
},
|
||||||
|
undefined, { shallow: true }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip
|
||||||
|
useEffect(() => {
|
||||||
|
const query = { ...DEFAULT_BLOGS_ARGS } as QueryBlogs;
|
||||||
|
const page = getPageFromQuery(router.query[QUERY_KEY.PAGE] as string);
|
||||||
|
query.options.skip = page * DEFAULT_BLOG_PAGE_SIZE;
|
||||||
|
setOptionQueryBlog(query);
|
||||||
|
setInitialQueryFlag(false);
|
||||||
|
console.log(query)
|
||||||
|
},[router.query])
|
||||||
|
|
||||||
|
|
||||||
|
let data;
|
||||||
|
if(initialQueryFlag == true){
|
||||||
|
data = blogList;
|
||||||
|
}else{
|
||||||
|
data = blogs
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<div className={s.wrapper}>
|
<div className={s.wrapper}>
|
||||||
|
{(!initialQueryFlag && loading && !blogs) && <ListProductCardSkeleton count={DEFAULT_BLOG_PAGE_SIZE} isWrap />}
|
||||||
<div className={s.list}>
|
<div className={s.list}>
|
||||||
|
|
||||||
{
|
{
|
||||||
data.slice(currentPage*DEFAULT_BLOG_PAGE_SIZE,(currentPage+1)*DEFAULT_BLOG_PAGE_SIZE).map((product,index)=> {
|
data?.map((product,index)=> {
|
||||||
return(
|
return(
|
||||||
<div className={s.card} key={`${product.title}-${index}`}>
|
<div className={s.card} key={`${product.title}-${index}`}>
|
||||||
<CardBlog {...product} />
|
{!product.isHidden && <CardBlog {...product} /> }
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className={s.pagination}>
|
<div className={s.pagination}>
|
||||||
<PaginationCommon total={data.length} pageSize={DEFAULT_BLOG_PAGE_SIZE} onChange={onPageChange}/>
|
<PaginationCommon total={totalItems !== undefined ? totalItems : total} pageSize={DEFAULT_BLOG_PAGE_SIZE} onChange={onPageChange}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default BlogsList
|
export default BlogsList
|
||||||
|
|
||||||
|
|
||||||
|
@@ -29,7 +29,7 @@ export interface BlogProps {
|
|||||||
title: string
|
title: string
|
||||||
slug: string
|
slug: string
|
||||||
description: string
|
description: string
|
||||||
imageSrc: string
|
imageSrc: string | null,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CheckOutForm {
|
export interface CheckOutForm {
|
||||||
|
Reference in New Issue
Block a user