mirror of
https://github.com/vercel/commerce.git
synced 2025-07-22 12:24:18 +00:00
🐛 bug: fix code follow by review Ly Tran
:%s
This commit is contained in:
@@ -11,7 +11,7 @@ import type {
|
||||
} from '../types/product'
|
||||
import type {
|
||||
GetAllBlogsOperation,
|
||||
GetFeaturedOperation
|
||||
GetFeaturedBlogsOperation
|
||||
} from '../types/blogs'
|
||||
import type { APIProvider, CommerceAPI } from '.'
|
||||
import { GetAllCollectionsOperation } from '@commerce/types/collection';
|
||||
@@ -167,13 +167,13 @@ export type Operations<P extends APIProvider> = {
|
||||
}
|
||||
|
||||
getFeaturedBlog: {
|
||||
<T extends GetFeaturedOperation>(opts: {
|
||||
<T extends GetFeaturedBlogsOperation>(opts: {
|
||||
variables?: T['variables']
|
||||
config?: P['config']
|
||||
preview?: boolean
|
||||
}): Promise<T['data']>
|
||||
|
||||
<T extends GetFeaturedOperation>(
|
||||
<T extends GetFeaturedBlogsOperation>(
|
||||
opts: {
|
||||
variables?: T['variables']
|
||||
config?: P['config']
|
||||
|
@@ -1,13 +1,12 @@
|
||||
import { SearchResultSortParameter } from "@framework/schema";
|
||||
import { Asset, BlogTranslation, Maybe, Product } from './../../vendure/schema.d';
|
||||
|
||||
export type BlogList = Node &{
|
||||
id: string
|
||||
featuredAsset?: Maybe<Asset>
|
||||
isPublic:Boolean
|
||||
translations: Array<BlogTranslation>
|
||||
translations: BlogTranslation[]
|
||||
authorName: string
|
||||
authorAvatarAsset:Array<Asset>
|
||||
authorAvatarAsset:Asset[]
|
||||
relevantProducts: Product
|
||||
}
|
||||
export type BlogsType = {
|
||||
@@ -23,7 +22,7 @@ export type GetAllBlogsOperation<T extends BlogsType = BlogsType> = {
|
||||
}
|
||||
|
||||
|
||||
export type GetFeaturedOperation<T extends BlogsType = BlogsType> = {
|
||||
export type GetFeaturedBlogsOperation<T extends BlogsType = BlogsType> = {
|
||||
data: { items: T['items'][] }
|
||||
variables: {
|
||||
take?: number
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { OperationContext } from '@commerce/api/operations'
|
||||
import { Provider, VendureConfig } from '..'
|
||||
import { GetFeaturedBlogQuery,BlogList } from '../../schema'
|
||||
import { getFeatuedBlogQuery } from '../../utils/queries/get-featued-query'
|
||||
import { getFeatuedBlogsQuery } from '../../utils/queries/get-featued-query'
|
||||
|
||||
export type BlogVariables = {
|
||||
take?: number,
|
||||
@@ -18,7 +18,7 @@ export default function getFeaturedBlogOperation({
|
||||
}): Promise<{ featuredBlogs: GetFeaturedBlogQuery[],totalItems:number }>
|
||||
|
||||
async function getFeaturedBlog({
|
||||
query = getFeatuedBlogQuery,
|
||||
query = getFeatuedBlogsQuery,
|
||||
variables: { ...vars } = {},
|
||||
config: cfg,
|
||||
}: {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { Cart } from '@commerce/types/cart'
|
||||
import { ProductCard, Product } from '@commerce/types/product'
|
||||
import { CartFragment, SearchResultFragment,Favorite } from '../schema'
|
||||
import { CartFragment, SearchResultFragment,Favorite, BlogList } from '../schema'
|
||||
|
||||
export function normalizeSearchResult(item: SearchResultFragment): ProductCard {
|
||||
return {
|
||||
@@ -83,4 +83,19 @@ export function normalizeProductCard(product: Product): ProductCard {
|
||||
facetValueIds: product.facetValueIds,
|
||||
collectionIds: product.collectionIds,
|
||||
}
|
||||
}
|
||||
|
||||
export function normalizeBlogList(blog: BlogList) {
|
||||
return {
|
||||
id: blog.id,
|
||||
title: blog.translations[0]?.title,
|
||||
imageSrc: blog.featuredAsset?.preview ?? null,
|
||||
slug: blog.translations[0]?.slug,
|
||||
description: blog.translations[0]?.description,
|
||||
isPublish: blog.isPublish,
|
||||
isFeatured:blog.isFeatured,
|
||||
authorName: blog.authorName,
|
||||
authorAvatarAsset : blog.authorAvatarAsset?.preview,
|
||||
createdAt: blog.createdAt
|
||||
}
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
export const getFeatuedBlogQuery = /* GraphQL */ `
|
||||
query GetFeaturedBlog($options: BlogListOptions) {
|
||||
export const getFeatuedBlogsQuery = /* GraphQL */ `
|
||||
query GetFeaturedBlogs($options: BlogListOptions) {
|
||||
featuredBlogs( options: $options){
|
||||
items {
|
||||
id
|
||||
|
@@ -8,27 +8,29 @@ import { getAllPromies } from 'src/utils/funtion.utils';
|
||||
import { PromiseWithKey } from 'src/utils/types.utils';
|
||||
|
||||
interface Props {
|
||||
blogsResult: { blogs?: BlogCardProps[],featuredBlog?: BlogCardProps[] },
|
||||
blogs?: BlogCardProps[],
|
||||
featuredBlog?: BlogCardProps[],
|
||||
totalItems: number
|
||||
}
|
||||
export default function BlogsPage({blogsResult,totalItems}:Props) {
|
||||
let date = new Date(blogsResult.featuredBlog?.[0]?.createdAt ?? '' );
|
||||
export default function BlogsPage({ blogs, featuredBlog, totalItems }:Props) {
|
||||
|
||||
let date = new Date(featuredBlog?.[0]?.createdAt ?? '' );
|
||||
let fullDate = date.toLocaleString('en-us', { month: 'long' }) + " " + date.getDate()+","+date.getFullYear();
|
||||
|
||||
|
||||
return(
|
||||
<>
|
||||
<BlogBreadCrumb />
|
||||
<BlogHeading />
|
||||
<FeaturedCardBlog
|
||||
title={blogsResult.featuredBlog?.[0]?.title}
|
||||
slug={blogsResult.featuredBlog?.[0]?.slug}
|
||||
imgSrc={blogsResult.featuredBlog?.[0]?.imageSrc ?? ''}
|
||||
content={blogsResult.featuredBlog?.[0]?.description}
|
||||
imgAuthor={blogsResult.featuredBlog?.[0]?.authorAvatarAsset}
|
||||
authorName={blogsResult.featuredBlog?.[0]?.authorName}
|
||||
title={featuredBlog?.[0]?.title}
|
||||
slug={featuredBlog?.[0]?.slug}
|
||||
imgSrc={featuredBlog?.[0]?.imageSrc ?? ''}
|
||||
content={featuredBlog?.[0]?.description}
|
||||
imgAuthor={featuredBlog?.[0]?.authorAvatarAsset}
|
||||
authorName={featuredBlog?.[0]?.authorName}
|
||||
date={fullDate}
|
||||
/>
|
||||
<BlogsList blogList={blogsResult.blogs} total={totalItems} idFeatured={blogsResult.featuredBlog?.[0]?.id} />
|
||||
<BlogsList blogList={blogs} total={totalItems} idFeatured={featuredBlog?.[0]?.id} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -43,17 +45,16 @@ export async function getStaticProps({
|
||||
let promisesWithKey = [] as PromiseWithKey[]
|
||||
let props = {} as any;
|
||||
|
||||
|
||||
const {featuredBlogs} = await commerce.getFeaturedBlog({
|
||||
variables: {
|
||||
take: DEFAULT_BLOG_PAGE_SIZE
|
||||
take: 1
|
||||
},
|
||||
config,
|
||||
preview,
|
||||
})
|
||||
|
||||
// Blogs
|
||||
const idFeaturedBlog = featuredBlogs[0].id;
|
||||
const idFeaturedBlog = featuredBlogs?.[0]?.id;
|
||||
const blogsPromise = commerce.getAllBlogs({
|
||||
variables: {
|
||||
excludeBlogIds: [idFeaturedBlog],
|
||||
@@ -74,8 +75,9 @@ export async function getStaticProps({
|
||||
return null
|
||||
})
|
||||
|
||||
props['blogsResult']['featuredBlog'] = featuredBlogs;
|
||||
props.featuredBlog = featuredBlogs;
|
||||
|
||||
console.log(props)
|
||||
return {
|
||||
props,
|
||||
revalidate: 60
|
||||
|
@@ -19,7 +19,7 @@ const CardBlog = ({ imageSrc, title, description, slug }: BlogCardProps) => {
|
||||
<Link href={`${ROUTE.BLOG_DETAIL}/${slug}`}>
|
||||
<a>
|
||||
<div className={s.image}>
|
||||
<ImgWithLink src={imageSrc ?? ''} alt="image cardblog" />
|
||||
<ImgWithLink src={imageSrc ?? ''} alt={title} />
|
||||
</div>
|
||||
</a>
|
||||
</Link>
|
||||
|
@@ -0,0 +1,18 @@
|
||||
.listBlogCardSkeleton {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
width: 90%;
|
||||
justify-content: space-between;
|
||||
div{
|
||||
min-width: 32rem;
|
||||
}
|
||||
|
||||
&.wrap {
|
||||
flex-wrap: wrap;
|
||||
overflow: unset;
|
||||
> div {
|
||||
margin-bottom: 1.6rem;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
import classNames from 'classnames'
|
||||
import { ProductCardSkeleton } from '..'
|
||||
import s from './ListBlogCardSkeleton.module.scss'
|
||||
|
||||
type Props = {
|
||||
count?: number
|
||||
isWrap?: boolean,
|
||||
}
|
||||
const ListBlogCardSkeleton = ({ count = 3, isWrap }: Props) => {
|
||||
|
||||
return (
|
||||
<div className={classNames(s.listBlogCardSkeleton, { [s.wrap]: isWrap })}>
|
||||
{
|
||||
Array.from(Array(count).keys()).map(item => <ProductCardSkeleton key={item} />)
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ListBlogCardSkeleton
|
@@ -5,15 +5,13 @@ import s from './ListProductCardSkeleton.module.scss'
|
||||
type Props = {
|
||||
count?: number
|
||||
isWrap?: boolean,
|
||||
isBlog?:boolean
|
||||
}
|
||||
const ListProductCardSkeleton = ({ count = 3, isWrap,isBlog=false }: Props) => {
|
||||
const ListProductCardSkeleton = ({ count = 3, isWrap }: Props) => {
|
||||
|
||||
return (
|
||||
<div className={classNames(s.listProductCardSkeleton, { [s.wrap]: isWrap }, { [s.isBlog]: isBlog })}>
|
||||
<div className={classNames(s.listProductCardSkeleton, { [s.wrap]: isWrap })}>
|
||||
{
|
||||
Array.from(Array(count).keys()).map(item => <ProductCardSkeleton key={item} isBlog={isBlog} />)
|
||||
|
||||
Array.from(Array(count).keys()).map(item => <ProductCardSkeleton key={item} />)
|
||||
}
|
||||
</div>
|
||||
)
|
||||
|
@@ -55,4 +55,5 @@ export { default as FormForgot} from './ForgotPassword/FormForgot/FormForgot'
|
||||
export { default as FormResetPassword} from './ForgotPassword/FormResetPassword/FormResetPassword'
|
||||
export { default as ProductCardSkeleton} from './ProductCardSkeleton/ProductCardSkeleton'
|
||||
export { default as ListProductCardSkeleton} from './ListProductCardSkeleton/ListProductCardSkeleton'
|
||||
export { default as ListBlogCardSkeleton} from './ListBlogCardSkeleton/ListBlogCardSkeleton'
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { GetAllBlogsQuery, QueryBlogs,BlogList } from '@framework/schema'
|
||||
import { normalizeBlogList } from '@framework/utils/normalize'
|
||||
import { getAllBlogsQuery } from '@framework/utils/queries/get-all-blog-query'
|
||||
import gglFetcher from 'src/utils/gglFetcher'
|
||||
import useSWR from 'swr'
|
||||
@@ -7,18 +8,7 @@ const useGetBlogList = (options?: QueryBlogs) => {
|
||||
const { data, isValidating, ...rest } = useSWR<GetAllBlogsQuery>([getAllBlogsQuery, options], gglFetcher)
|
||||
|
||||
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,
|
||||
isPublish: val.isPublish,
|
||||
isFeatured:val.isFeatured,
|
||||
authorName: val.authorName,
|
||||
authorAvatarAsset : val.authorAvatarAsset?.preview,
|
||||
createdAt: val.createdAt
|
||||
})),
|
||||
blogs: data?.blogs?.items?.map((blog:BlogList)=>normalizeBlogList(blog)),
|
||||
totalItems: data?.blogs?.totalItems || null,
|
||||
loading: isValidating,
|
||||
...rest
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { useRouter } from 'next/router'
|
||||
import React, { useEffect, useState,useRef } from 'react'
|
||||
import React, { useEffect, useState,useRef, useMemo } from 'react'
|
||||
import CardBlog, { BlogCardProps } from 'src/components/common/CardBlog/CardBlog'
|
||||
import PaginationCommon from 'src/components/common/PaginationCommon/PaginationCommon'
|
||||
import { DEFAULT_BLOG_PAGE_SIZE, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils'
|
||||
@@ -7,7 +7,7 @@ import s from "./BlogsList.module.scss"
|
||||
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'
|
||||
import { ListBlogCardSkeleton } from 'src/components/common'
|
||||
|
||||
interface BlogsListProps {
|
||||
blogList?: BlogCardProps[],
|
||||
@@ -19,12 +19,13 @@ interface BlogsListProps {
|
||||
|
||||
const BlogsList = ({ blogList,total,idFeatured }:BlogsListProps) => {
|
||||
|
||||
const DEFAULT_BLOGS_ARGS = {
|
||||
const DEFAULT_BLOGS_ARGS = useMemo(()=> ({
|
||||
excludeBlogIds: [idFeatured],
|
||||
options:{
|
||||
skip: 1, take: DEFAULT_BLOG_PAGE_SIZE
|
||||
}
|
||||
}
|
||||
}),[idFeatured]);
|
||||
|
||||
|
||||
const router = useRouter();
|
||||
const [initialQueryFlag, setInitialQueryFlag] = useState<boolean>(true)
|
||||
@@ -69,7 +70,7 @@ const BlogsList = ({ blogList,total,idFeatured }:BlogsListProps) => {
|
||||
return (
|
||||
<section>
|
||||
<div className={s.wrapper}>
|
||||
{(!initialQueryFlag && loading && !blogs) && <ListProductCardSkeleton count={DEFAULT_BLOG_PAGE_SIZE} isWrap isBlog={true} />}
|
||||
{(!initialQueryFlag && loading && !blogs) && <ListBlogCardSkeleton count={DEFAULT_BLOG_PAGE_SIZE} isWrap />}
|
||||
<div className={s.list}>
|
||||
|
||||
{
|
||||
|
Reference in New Issue
Block a user