diff --git a/framework/commerce/api/operations.ts b/framework/commerce/api/operations.ts index 1065653bd..898c322e3 100644 --- a/framework/commerce/api/operations.ts +++ b/framework/commerce/api/operations.ts @@ -10,7 +10,8 @@ import type { GetProductOperation, } from '../types/product' import type { - GetAllBlogsOperation + GetAllBlogsOperation, + GetFeaturedOperation } from '../types/blogs' import type { APIProvider, CommerceAPI } from '.' import { GetAllCollectionsOperation } from '@commerce/types/collection'; @@ -30,7 +31,8 @@ export const OPERATIONS = [ 'getProduct', 'getAllFacets', 'getAllCollections', - 'getAllBlogs' + 'getAllBlogs', + 'getFeaturedBlog' ] as const export const defaultOperations = OPERATIONS.reduce((ops, k) => { @@ -149,6 +151,22 @@ export type Operations

= { getAllBlogs: { + (opts: { + variables?: T['variables'] + config?: P['config'] + preview?: boolean + }): Promise + + ( + opts: { + variables?: T['variables'] + config?: P['config'] + preview?: boolean + } & OperationOptions + ): Promise + } + + getFeaturedBlog: { (opts: { variables?: T['variables'] config?: P['config'] @@ -165,6 +183,7 @@ export type Operations

= { } + getProduct: { (opts: { variables: T['variables'] diff --git a/framework/commerce/types/blogs.ts b/framework/commerce/types/blogs.ts index f138b964e..9b6ce14c1 100644 --- a/framework/commerce/types/blogs.ts +++ b/framework/commerce/types/blogs.ts @@ -19,8 +19,14 @@ export type GetAllBlogsOperation = { variables: { take?: number skip?: number - sort?: SearchResultSortParameter } - } +} - \ No newline at end of file + +export type GetFeaturedOperation = { + data: { items: T['items'][] } + variables: { + take?: number + skip?: number + } +} \ No newline at end of file diff --git a/framework/vendure/api/index.ts b/framework/vendure/api/index.ts index 6f73c680e..edf67d14f 100644 --- a/framework/vendure/api/index.ts +++ b/framework/vendure/api/index.ts @@ -12,6 +12,7 @@ import getSiteInfo from './operations/get-site-info' import login from './operations/login' import fetchGraphqlApi from './utils/fetch-graphql-api' import getAllBlogs from './operations/get-all-blogs' +import getFeaturedBlog from './operations/get-featured-blog' export interface VendureConfig extends CommerceAPIConfig {} @@ -44,7 +45,8 @@ const operations = { getProduct, getAllFacets, getAllCollections, - getAllBlogs + getAllBlogs, + getFeaturedBlog } export const provider = { config, operations } diff --git a/framework/vendure/api/operations/get-all-blogs.ts b/framework/vendure/api/operations/get-all-blogs.ts index 3612a751d..3a1d01399 100644 --- a/framework/vendure/api/operations/get-all-blogs.ts +++ b/framework/vendure/api/operations/get-all-blogs.ts @@ -3,7 +3,11 @@ 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 type BlogVariables = { + excludeBlogIds?: string[], + take?: number, + skip?:number +} export default function getAllBlogsOperation({ commerce, @@ -24,8 +28,10 @@ export default function getAllBlogsOperation({ config?: Partial preview?: boolean } = {}): Promise<{ blogs: GetAllBlogsQuery | any[] ,totalItems?:number }> { + console.log(vars.excludeBlogIds) const config = commerce.getConfig(cfg) const variables = { + excludeBlogIds: vars.excludeBlogIds, options: { take: vars.take, skip: vars.skip, @@ -34,7 +40,6 @@ export default function getAllBlogsOperation({ const { data } = await config.fetch(query, { variables, }) - return { blogs: data?.blogs?.items?.map((val:BlogList)=>({ id: val.id, @@ -42,7 +47,11 @@ export default function getAllBlogsOperation({ imageSrc: val.featuredAsset?.preview ?? null, slug: val.translations[0]?.slug, description: val.translations[0]?.description, - isHidden: val.isHidden + isPublish: val.isPublish, + isFeatured: val.isFeatured, + authorName: val.authorName, + authorAvatarAsset : val.authorAvatarAsset?.preview, + createdAt: val.createdAt })), totalItems: data?.blogs?.totalItems || null } diff --git a/framework/vendure/api/operations/get-featured-blog.ts b/framework/vendure/api/operations/get-featured-blog.ts new file mode 100644 index 000000000..6dc05c1be --- /dev/null +++ b/framework/vendure/api/operations/get-featured-blog.ts @@ -0,0 +1,56 @@ +import { OperationContext } from '@commerce/api/operations' +import { Provider, VendureConfig } from '..' +import { GetFeaturedBlogQuery,BlogList } from '../../schema' +import { getFeatuedBlogQuery } from '../../utils/queries/get-featued-query' + +export type BlogVariables = { + take?: number, + skip?:number +} + +export default function getFeaturedBlogOperation({ + commerce, +}: OperationContext) { + async function getFeaturedBlog(opts?: { + variables?: BlogVariables + config?: Partial + preview?: boolean + }): Promise<{ featuredBlogs: GetFeaturedBlogQuery,totalItems:number }> + + async function getFeaturedBlog({ + query = getFeatuedBlogQuery, + variables: { ...vars } = {}, + config: cfg, + }: { + query?: string + variables?: BlogVariables + config?: Partial + preview?: boolean + } = {}): Promise<{ featuredBlogs: GetFeaturedBlogQuery | any[] ,totalItems?:number }> { + const config = commerce.getConfig(cfg) + const variables = { + options: { + take: vars.take, + }, + } + const { data } = await config.fetch(query, { + variables, + }) + return { + featuredBlogs: data?.featuredBlogs?.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 + })) + } + } + + return getFeaturedBlog +} diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts index 362436170..5b4b58757 100644 --- a/framework/vendure/schema.d.ts +++ b/framework/vendure/schema.d.ts @@ -2317,11 +2317,12 @@ export type BlogList = Node &{ createdAt: DateTime! updatedAt: DateTime! featuredAsset?: Maybe - isHidden:Boolean + isPublish:Boolean translations: Array authorName: Scalars['String'] - authorAvatarAsset:Array + authorAvatarAsset:Asset relevantProducts: Product + isFeatured: Boolean } export type BlogTranslation = { @@ -2342,8 +2343,15 @@ export type GetAllBlogsQuery = PaginatedList & { 'totalItems' } } +export type GetFeaturedBlogQuery = PaginatedList & { + featuredBlogs: { __typename?: 'BlogList' } & { + items: Array<{ __typename?: 'Blog' } & BlogList!>, + 'totalItems' + } +} export type QueryBlogs = { + excludeBlogIds:Array, options: BlogListOptions } diff --git a/framework/vendure/utils/queries/get-all-blog-query.ts b/framework/vendure/utils/queries/get-all-blog-query.ts index d7a4a294a..57c17ace7 100644 --- a/framework/vendure/utils/queries/get-all-blog-query.ts +++ b/framework/vendure/utils/queries/get-all-blog-query.ts @@ -1,20 +1,26 @@ export const getAllBlogsQuery = /* GraphQL */ ` -query GetBlogs ($options: BlogListOptions){ - blogs(options: $options){ - totalItems - items { - id - isHidden - featuredAsset { - preview - } - translations { - title - slug - description - content - } - } +query GetBlogs($excludeBlogIds: [ID]!, $options: BlogListOptions) { + blogs(excludeBlogIds: $excludeBlogIds, options: $options) { + totalItems + items { + id + isPublish + isFeatured + authorName + createdAt + authorAvatarAsset{ + preview + } + featuredAsset { + preview + } + translations { + title + slug + description + content + } } + } } ` diff --git a/framework/vendure/utils/queries/get-featued-query.ts b/framework/vendure/utils/queries/get-featued-query.ts new file mode 100644 index 000000000..63ed82736 --- /dev/null +++ b/framework/vendure/utils/queries/get-featued-query.ts @@ -0,0 +1,25 @@ +export const getFeatuedBlogQuery = /* GraphQL */ ` + query GetFeaturedBlog($options: BlogListOptions) { + featuredBlogs( options: $options){ + items { + id + isPublish + isFeatured + authorName + createdAt + authorAvatarAsset{ + preview + } + featuredAsset { + preview + } + translations { + title + slug + description + content + } + } + } + } +` \ No newline at end of file diff --git a/pages/blogs.tsx b/pages/blogs.tsx index f46a2214b..7e8a2b64a 100644 --- a/pages/blogs.tsx +++ b/pages/blogs.tsx @@ -3,26 +3,33 @@ import { GetStaticPropsContext } from 'next'; import { Layout } from 'src/components/common'; 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 { DEFAULT_BLOG_PAGE_SIZE,DEFAULT_FEATURED_BLOG_PAGE_SIZE } from "src/utils/constanst.utils"; import { getAllPromies } from 'src/utils/funtion.utils'; import { PromiseWithKey } from 'src/utils/types.utils'; - +import { getIdFeaturedBlog } from 'src/utils/funtion.utils'; interface Props { - blogsResult: { blogs: BlogCardProps[] }, + blogsResult: { blogs?: BlogCardProps[],featuredBlogs?: BlogCardProps[] }, totalItems: number } export default function BlogsPage({blogsResult,totalItems}:Props) { + + // let date = new Date(blogsResult?.featuredBlogs[0]?.createdAt ?? '' ); + // let fullDate = date.toLocaleString('en-us', { month: 'long' }) + " " + date.getDate()+","+date.getFullYear(); + return( <> - + {/* */} ) @@ -39,16 +46,32 @@ export async function getStaticProps({ let props = {} as any; + const {featuredBlogs} = await commerce.getFeaturedBlog({ + variables: { + take: DEFAULT_BLOG_PAGE_SIZE + }, + config, + preview, + }) + + + // console.log(featuredBlogs[0].id); + // promisesWithKey.push({ key: 'blogsResult', promise: FeaturedBlogPromise }) + + // Blogs + const idBlog = featuredBlogs[0].id; const blogsPromise = commerce.getAllBlogs({ variables: { - take: DEFAULT_BLOG_PAGE_SIZE + excludeBlogIds: [idBlog], + take: DEFAULT_BLOG_PAGE_SIZE }, config, preview, }) promisesWithKey.push({ key: 'blogsResult', promise: blogsPromise }) + try { const promises = getAllPromies(promisesWithKey) @@ -58,7 +81,8 @@ export async function getStaticProps({ props[item.key] = item.keyResult ? rs[index][item.keyResult] : rs[index] return null }) - + props['blogsResult']['featuredBlog'] = featuredBlogs; + return { props, revalidate: 60 diff --git a/pages/index.tsx b/pages/index.tsx index f4619a195..d1c5c39f8 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -56,7 +56,7 @@ export async function getStaticProps({ preview, }) props.featuredAndDiscountFacetsValue = getAllFacetValuesForFeatuedProducts(facets) - + // fresh products const freshProductvariables: ProductVariables = {} const freshFacetId = getFreshFacetId(facets) diff --git a/src/components/common/CardBlog/CardBlog.tsx b/src/components/common/CardBlog/CardBlog.tsx index c5c87ba12..27a6c32b5 100644 --- a/src/components/common/CardBlog/CardBlog.tsx +++ b/src/components/common/CardBlog/CardBlog.tsx @@ -6,8 +6,11 @@ import { ImgWithLink } from '..' import s from './CardBlog.module.scss' export interface BlogCardProps extends BlogProps { - // todo: edit when intergrate API - isHidden:Boolean + isPublish?:Boolean, + isFeatured?:Boolean, + authorAvatarAsset?:string, + authorName?:string, + createdAt?:string } const CardBlog = ({ imageSrc, title, description, slug }: BlogCardProps) => { diff --git a/src/components/common/ListProductCardSkeleton/ListProductCardSkeleton.module.scss b/src/components/common/ListProductCardSkeleton/ListProductCardSkeleton.module.scss index 5503dccf7..9ce1dfb77 100644 --- a/src/components/common/ListProductCardSkeleton/ListProductCardSkeleton.module.scss +++ b/src/components/common/ListProductCardSkeleton/ListProductCardSkeleton.module.scss @@ -9,4 +9,11 @@ margin-bottom: 1.6rem; } } + &.isBlog{ + width: 90%; + justify-content: space-between; + div{ + min-width: 32rem; + } + } } diff --git a/src/components/common/ListProductCardSkeleton/ListProductCardSkeleton.tsx b/src/components/common/ListProductCardSkeleton/ListProductCardSkeleton.tsx index 9ab255477..9063f1968 100644 --- a/src/components/common/ListProductCardSkeleton/ListProductCardSkeleton.tsx +++ b/src/components/common/ListProductCardSkeleton/ListProductCardSkeleton.tsx @@ -4,14 +4,15 @@ import s from './ListProductCardSkeleton.module.scss' type Props = { count?: number - isWrap?: boolean + isWrap?: boolean, + isBlog?:boolean } -const ListProductCardSkeleton = ({ count = 3, isWrap }: Props) => { +const ListProductCardSkeleton = ({ count = 3, isWrap,isBlog=false }: Props) => { return ( -

+
{ - Array.from(Array(count).keys()).map(item => ) + Array.from(Array(count).keys()).map(item => ) }
diff --git a/src/components/common/ProductCardSkeleton/ProductCardSkeleton.tsx b/src/components/common/ProductCardSkeleton/ProductCardSkeleton.tsx index 52c4b0fea..373099314 100644 --- a/src/components/common/ProductCardSkeleton/ProductCardSkeleton.tsx +++ b/src/components/common/ProductCardSkeleton/ProductCardSkeleton.tsx @@ -1,14 +1,16 @@ import SkeletonImage from "../SkeletonCommon/SkeletonImage/SkeletonImage" import SkeletonParagraph from "../SkeletonCommon/SkeletonParagraph/SkeletonParagraph" import s from './ProductCardSkeleton.module.scss' - -const ProductCardSkeleton = ({ }) => { +type Props = { + isBlog?:boolean +} +const ProductCardSkeleton = ({isBlog=false }) => { return (
- +
) diff --git a/src/components/hooks/blog/useGetBlogList.tsx b/src/components/hooks/blog/useGetBlogList.tsx index ebbe6162b..d844ae911 100644 --- a/src/components/hooks/blog/useGetBlogList.tsx +++ b/src/components/hooks/blog/useGetBlogList.tsx @@ -5,7 +5,7 @@ import useSWR from 'swr' const useGetBlogList = (options?: QueryBlogs) => { const { data, isValidating, ...rest } = useSWR([getAllBlogsQuery, options], gglFetcher) - console.log(isValidating); + return { blogs: data?.blogs?.items?.map((val:BlogList)=>({ id: val.id, @@ -13,7 +13,11 @@ const useGetBlogList = (options?: QueryBlogs) => { imageSrc: val.featuredAsset?.preview ?? null, slug: val.translations[0]?.slug, description: val.translations[0]?.description, - isHidden: val.isHidden + isPublish: val.isPublish, + isFeatured:val.isFeatured, + authorName: val.authorName, + authorAvatarAsset : val.authorAvatarAsset?.preview, + createdAt: val.createdAt })), totalItems: data?.blogs?.totalItems || null, loading: isValidating, diff --git a/src/components/modules/blogs/BlogsList/BlogsList.tsx b/src/components/modules/blogs/BlogsList/BlogsList.tsx index 4586f5acd..28c2ee729 100644 --- a/src/components/modules/blogs/BlogsList/BlogsList.tsx +++ b/src/components/modules/blogs/BlogsList/BlogsList.tsx @@ -15,19 +15,20 @@ interface BlogsListProps { } const DEFAULT_BLOGS_ARGS = { + excludeBlogIds: ["28"], options:{ skip: 1, take: DEFAULT_BLOG_PAGE_SIZE } } const BlogsList = ({ blogList,total }:BlogsListProps) => { + const router = useRouter(); const [initialQueryFlag, setInitialQueryFlag] = useState(true) const [optionQueryBlog, setOptionQueryBlog] = useState(DEFAULT_BLOGS_ARGS) const { blogs, totalItems, loading } = useGetBlogList(optionQueryBlog); - // console.log(blogs); const onPageChange = (page:number) => { @@ -49,7 +50,7 @@ const BlogsList = ({ blogList,total }:BlogsListProps) => { query.options.skip = page * DEFAULT_BLOG_PAGE_SIZE; setOptionQueryBlog(query); setInitialQueryFlag(false); - console.log(query) + },[router.query]) @@ -59,18 +60,19 @@ const BlogsList = ({ blogList,total }:BlogsListProps) => { }else{ data = blogs } + console.log(blogList); return (
- {(!initialQueryFlag && loading && !blogs) && } + {(!initialQueryFlag && loading && !blogs) && }
{ data?.map((product,index)=> { return(
- {!product.isHidden && } + {product.isPublish && }
) }) diff --git a/src/utils/constanst.utils.ts b/src/utils/constanst.utils.ts index 7d0cf9ba5..9d1fb6b66 100644 --- a/src/utils/constanst.utils.ts +++ b/src/utils/constanst.utils.ts @@ -171,6 +171,8 @@ export const FEATURED = [ export const DEFAULT_BLOG_PAGE_SIZE = 6; +export const DEFAULT_FEATURED_BLOG_PAGE_SIZE = 1; + export const FILTER_PAGE = [ROUTE.HOME, ROUTE.PRODUCTS] export const STATE_OPTIONS = [ diff --git a/src/utils/funtion.utils.ts b/src/utils/funtion.utils.ts index 408d9d0fd..2b473c9e2 100644 --- a/src/utils/funtion.utils.ts +++ b/src/utils/funtion.utils.ts @@ -1,3 +1,4 @@ +import { BlogList } from '@framework/schema'; import { Facet } from "@commerce/types/facet"; import { Collection, FacetValue, SearchResultSortParameter } from './../../framework/vendure/schema.d'; import { CODE_FACET_DISCOUNT, CODE_FACET_FEATURED, CODE_FACET_FEATURED_VARIANT, PRODUCT_SORT_OPTION_VALUE } from "./constanst.utils"; @@ -127,4 +128,9 @@ export const getCategoryNameFromCollectionId = (colelctions: Collection[], colle export function getAllPromies(promies: PromiseWithKey[]) { return promies.map(item => item.promise) -} \ No newline at end of file +} + +export function getIdFeaturedBlog(blog: BlogList) { + return blog?.id +} +