diff --git a/framework/commerce/api/operations.ts b/framework/commerce/api/operations.ts index e240fa8c5..afd725081 100644 --- a/framework/commerce/api/operations.ts +++ b/framework/commerce/api/operations.ts @@ -1,7 +1,8 @@ +import { GetAllRecipePathsOperation, GetRecipeDetailOperation,GetAllRecipesOperation } from './../types/recipes'; import { GetAllFacetsOperation } from './../types/facet'; import type { ServerResponse } from 'http' import type { LoginOperation } from '../types/login' -import type { GetAllPagesOperation, GetPageOperation } from '../types/page' +import type { GetAllPagesOperation } from '../types/page' import type { GetSiteInfoOperation } from '../types/site' import type { GetCustomerWishlistOperation } from '../types/wishlist' import type { @@ -16,9 +17,7 @@ import type { GetBlogDetailOperation, GetRelevantBlogsOperation } from '../types/blogs' -import type { - GetAllRecipesOperation -} from '../types/recipes' + import type { APIProvider, CommerceAPI } from '.' import { GetAllCollectionsOperation } from '@commerce/types/collection'; @@ -43,7 +42,9 @@ export const OPERATIONS = [ 'getAllBlogPaths', 'getBlogDetail', 'getRelevantBlogs', - 'getAllRecipes' + 'getAllRecipes', + 'getAllRecipePaths', + 'getRecipeDetail' ] as const export const defaultOperations = OPERATIONS.reduce((ops, k) => { @@ -84,14 +85,14 @@ export type Operations

= { ): Promise } - getPage: { - (opts: { + getRecipeDetail: { + (opts: { variables: T['variables'] config?: P['config'] preview?: boolean }): Promise - ( + ( opts: { variables: T['variables'] config?: P['config'] @@ -159,6 +160,35 @@ export type Operations

= { ): Promise } + getAllRecipePaths: { + (opts: { + variables?: T['variables'] + config?: P['config'] + }): Promise + + ( + opts: { + variables?: T['variables'] + config?: P['config'] + } & OperationOptions + ): Promise + } + + getAllRecipe: { + (opts: { + variables?: T['variables'] + config?: P['config'] + }): Promise + + ( + opts: { + variables?: T['variables'] + config?: P['config'] + } & OperationOptions + ): Promise + } + + getAllProducts: { (opts: { variables?: T['variables'] diff --git a/framework/commerce/types/recipes.ts b/framework/commerce/types/recipes.ts index 820c7aac7..037855f32 100644 --- a/framework/commerce/types/recipes.ts +++ b/framework/commerce/types/recipes.ts @@ -29,4 +29,17 @@ export type GetAllRecipesOperation = { take?: number id?: SortRecipes } +} +export type GetAllRecipePathsOperation< +T extends RecipesType = RecipesType +> = { + data: { recipes: Pick[] } + variables: { first?: number } +} + +export type GetRecipeDetailOperation = { + data: T['items'], + variables: { + slug?: string + } } \ No newline at end of file diff --git a/framework/vendure/api/index.ts b/framework/vendure/api/index.ts index cb62f2dc0..3d9c9219f 100644 --- a/framework/vendure/api/index.ts +++ b/framework/vendure/api/index.ts @@ -15,6 +15,9 @@ import getSiteInfo from './operations/get-site-info' import getAllBlogPaths from './operations/get-all-blog-paths' import getRelevantBlogs from './operations/get-relevant-blogs' import getAllRecipes from './operations/get-all-recipes' +import getAllRecipePaths from './operations/get-all-recipe-paths' +import getRecipeDetail from './operations/get-recipe-detail' + import login from './operations/login' import fetchGraphqlApi from './utils/fetch-graphql-api' @@ -54,7 +57,9 @@ const operations = { getBlogDetail, getAllBlogPaths, getRelevantBlogs, - getAllRecipes + getAllRecipes, + getAllRecipePaths, + getRecipeDetail } export const provider = { config, operations } diff --git a/framework/vendure/api/operations/get-all-recipe-paths.ts b/framework/vendure/api/operations/get-all-recipe-paths.ts new file mode 100644 index 000000000..ac09dbd1c --- /dev/null +++ b/framework/vendure/api/operations/get-all-recipe-paths.ts @@ -0,0 +1,53 @@ +import { BlogList } from '../../schema'; +import { OperationContext,OperationOptions } from '@commerce/api/operations'; +import { BigcommerceConfig } from '../../../bigcommerce/api'; +import type { GetAllRecipePathsQuery,RecipeTranslation } from '../../schema'; +import { getAllBlogPathsQuery } from '../../utils/queries/get-all-blog-paths-query'; +import { Provider } from '../index'; +import { GetAllRecipesPathsOperation } from '../../../commerce/types/recipes'; + +export type GetAllBlogPathsResult = { + blogs: Array<{ node: { path: string } }> +} + +export default function getAllRecipePathsOperation({ + commerce, +}: OperationContext) { + async function getAllRecipePaths< + T extends GetAllRecipesPathsOperation + >(opts?: { + variables?: T['variables'] + config?: BigcommerceConfig + }): Promise + + async function getAllRecipePaths( + opts: { + variables?: T['variables'] + config?: BigcommerceConfig + } & OperationOptions + ): Promise + + async function getAllRecipePaths({ + query = getAllBlogPathsQuery, + variables, + config: cfg, + }: { + query?: string + variables?: T['variables'] + config?: BigcommerceConfig + } = {}): Promise { + const config = commerce.getConfig(cfg) + + const { data } = await config.fetch(query, { + variables, + }) + + const recipes = data.blogs.items; + + return { + recipes: recipes?.map(val=>val.translations.map((p:RecipeTranslation) => ({ path: `/${p.slug}` }))) + } + } + + return getAllRecipePaths +} diff --git a/framework/vendure/api/operations/get-all-recipes.ts b/framework/vendure/api/operations/get-all-recipes.ts index 3f9fcc90f..4998d793e 100644 --- a/framework/vendure/api/operations/get-all-recipes.ts +++ b/framework/vendure/api/operations/get-all-recipes.ts @@ -1,14 +1,13 @@ import { OperationContext } from '@commerce/api/operations' import { Provider, VendureConfig } from '..' -import { GetAllRecipesQuery,BlogList,SortRecipes } from '../../schema' +import { BlogList, GetAllRecipesQuery } from '../../schema' import { getAllBlogsQuery } from '../../utils/queries/get-all-blog-query' export type RecipesVariables = { excludeBlogIds?: string[], - take?: number, - sort?: { - id?: string - } + take?:number, + id?: string, + isPublish?:Boolean } export default function getAllRecipesOperation({ @@ -19,7 +18,7 @@ export default function getAllRecipesOperation({ config?: Partial preview?: boolean }): Promise<{ recipes: GetAllRecipesQuery[],totalItems:number }> - + async function getAllRecipes({ query = getAllBlogsQuery, variables: { ...vars } = {}, @@ -30,20 +29,27 @@ export default function getAllRecipesOperation({ config?: Partial preview?: boolean } = {}): Promise<{ recipes: GetAllRecipesQuery[] | any[] ,totalItems?:number }> { - + const config = commerce.getConfig(cfg) const variables = { excludeBlogIds: vars.excludeBlogIds, options: { take: vars.take, sort: { - id: vars.sort?.id + id: vars?.id + }, + filter:{ + isPublish: { + eq:vars.isPublish + } } }, } + const { data } = await config.fetch(query, { variables, }) + return { recipes: data?.blogs?.items?.map((val:BlogList)=>({ id: val.id, @@ -52,7 +58,6 @@ export default function getAllRecipesOperation({ slug: val.translations[0]?.slug, description: val.translations[0]?.description, isPublish: val.isPublish, - isFeatured: val.isFeatured, authorName: val.authorName, authorAvatarAsset : val.authorAvatarAsset?.preview ?? null, createdAt: val.createdAt diff --git a/framework/vendure/api/operations/get-recipe-detail.ts b/framework/vendure/api/operations/get-recipe-detail.ts new file mode 100644 index 000000000..e8b2b167f --- /dev/null +++ b/framework/vendure/api/operations/get-recipe-detail.ts @@ -0,0 +1,98 @@ +import { OperationContext } from '@commerce/api/operations' +import { Provider, VendureConfig } from '..' +import { GetRecipeQuery, RecipeList } from '../../schema' +import { getBlogDetailQuery } from '../../utils/queries/get-blog-detail' + + +export default function getRecipeDetailOperation({ + commerce, +}: OperationContext) { + + async function getRecipeDetail({ + query = getBlogDetailQuery, + variables, + config: cfg, + }: { + query?: string + variables: { slug: string } + config?: Partial + preview?: boolean + }): Promise<{recipeDetail: RecipeList | any }> { + const config = commerce.getConfig(cfg) + const { data } = await config.fetch(query, { + variables, + }) + const recipes = data.blog + + if (recipes) { + return { + recipeDetail: { + id: data?.blog?.id, + title: data?.blog?.translations[0].title, + imageSrc: data?.blog?.featuredAsset?.preview ?? null, + slug: data?.blog?.translations[0]?.slug, + description: data?.blog?.translations[0]?.description, + isPublish: data?.blog?.isPublish, + authorName: data?.blog?.authorName, + authorAvatarAsset : data?.blog?.authorAvatarAsset?.preview, + createdAt: data?.blog?.createdAt, + relevantProducts: data?.blog?.relevantProducts.map(val=>val.id) + } + } + }else{ + return {recipeDetail:null} + } + } + + return getRecipeDetail +} + + +// export type RecipeVariables = { +// slug?: string, +// } + +// export default function getRecipeDetailOperation({ +// commerce, +// }: OperationContext) { + +// async function getRecipeDetail(opts?: { +// variables?: RecipeVariables +// config?: Partial +// preview?: boolean +// }): Promise<{ recipeDetail: RecipeList}> + +// async function getRecipeDetail({ +// query = getBlogDetailQuery, +// variables: { ...vars } = {}, +// config: cfg, +// }: { +// query?: string +// variables?: RecipeVariables +// config?: Partial +// preview?: boolean +// } = {}): Promise<{ recipeDetail: RecipeList | any }> { + +// const config = commerce.getConfig(cfg) +// const variables = { +// slug: vars.slug +// } +// const { data } = await config.fetch(query, { +// variables, +// }) +// return { +// id: data?.blog?.id, +// title: data?.blog?.translations[0].title, +// imageSrc: data?.blog?.featuredAsset?.preview ?? null, +// slug: data?.blog?.translations[0]?.slug, +// description: data?.blog?.translations[0]?.description, +// isPublish: data?.blog?.isPublish, +// authorName: data?.blog?.authorName, +// authorAvatarAsset : data?.blog?.authorAvatarAsset?.preview, +// createdAt: data?.blog?.createdAt, +// relevantProducts: data?.blog?.relevantProducts.map(val=>val.id) +// } +// } + +// return getRecipeDetail +// } diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts index 4c69753e0..9817dae05 100644 --- a/framework/vendure/schema.d.ts +++ b/framework/vendure/schema.d.ts @@ -2433,6 +2433,12 @@ export type GetBlogQuery = { __typename?: 'Query' } & { > } +export type GetRecipeQuery = { __typename?: 'Query' } & { + recipeDetail?: Maybe< + { __typename?: 'Recipe' } & RecipeList + > +} + export type BlogTranslation = { __typename?: 'BlogTranslation' @@ -2445,6 +2451,18 @@ export type BlogTranslation = { description: Scalars['String'] content: Scalars['String'] } +export type RecipeTranslation = { + __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' } & { @@ -2481,6 +2499,20 @@ export type QueryBlogs = { options: BlogListOptions } +export type QueryRecipes = { + excludeBlogIds?:Maybe, + options: RecipeListOptions +} + +export type RecipeListOptions = { + skip?: Maybe + take?: Maybe + sort?: RecipesSort +} +export type RecipesSort = { + id?: Maybe +} + export type BlogListOptions = { skip?: Maybe take?: Maybe @@ -3455,6 +3487,13 @@ export type GetAllBlogPathsQuery = { __typename?: 'Query' } & { } } +export type GetAllRecipePathsQuery = { __typename?: 'Query' } & { + recipes: { __typename?: 'Recipes' } & { + items: Array<{ __typename?: 'Recipe' } & Pick> + } +} + + export type GetAllProductsQueryVariables = Exact<{ input: SearchInput }> diff --git a/framework/vendure/utils/normalize.ts b/framework/vendure/utils/normalize.ts index c095ec030..ccafdaf6d 100644 --- a/framework/vendure/utils/normalize.ts +++ b/framework/vendure/utils/normalize.ts @@ -1,6 +1,6 @@ import { Cart } from '@commerce/types/cart' import { ProductCard, Product } from '@commerce/types/product' -import { CartFragment, SearchResultFragment,Favorite, BlogList } from '../schema' +import { CartFragment, SearchResultFragment,Favorite, BlogList, RecipeList } from '../schema' export function normalizeSearchResult(item: SearchResultFragment): ProductCard { return { @@ -98,4 +98,18 @@ export function normalizeBlogList(blog: BlogList) { authorAvatarAsset : blog.authorAvatarAsset?.preview, createdAt: blog.createdAt } +} + +export function normalizeRecipeList(recipe: RecipeList) { + return { + id: recipe.id, + title: recipe.translations[0]?.title, + imageSrc: recipe.featuredAsset?.preview ?? null, + slug: recipe.translations[0]?.slug, + description: recipe.translations[0]?.description, + isPublish: recipe.isPublish, + authorName: recipe.authorName, + authorAvatarAsset : recipe.authorAvatarAsset?.preview, + createdAt: recipe.createdAt + } } \ No newline at end of file diff --git a/pages/blogs.tsx b/pages/blogs.tsx index 0fa7ad2c1..44a16a1e5 100644 --- a/pages/blogs.tsx +++ b/pages/blogs.tsx @@ -13,7 +13,7 @@ interface Props { totalItems: number } export default function BlogsPage({ blogs, featuredBlog, totalItems }:Props) { - console.log(blogs) + let date = new Date(featuredBlog?.[0]?.createdAt ?? '' ); let fullDate = date.toLocaleString('en-us', { month: 'long' }) + " " + date.getDate()+","+date.getFullYear(); diff --git a/pages/products.tsx b/pages/products.tsx index 9766ab37d..035ab87e6 100644 --- a/pages/products.tsx +++ b/pages/products.tsx @@ -14,7 +14,6 @@ interface Props { facets: Facet[], collections: Collection[], productsResult: { products: ProductCard[], totalItems: number }, - } export default function Products({ facets, collections, productsResult }: Props) { diff --git a/pages/recipe/[slug].tsx b/pages/recipe/[slug].tsx index 1f71ba5be..d05de7210 100644 --- a/pages/recipe/[slug].tsx +++ b/pages/recipe/[slug].tsx @@ -1,12 +1,98 @@ +import { useRouter } from 'next/router' import { Layout, RecipeDetail, RecommendedRecipes } from 'src/components/common' import { INGREDIENT_DATA_TEST, RECIPE_DATA_TEST } from 'src/utils/demo-data' +import commerce from '@lib/api/commerce'; +import { PromiseWithKey } from 'src/utils/types.utils'; +import { GetStaticPropsContext,GetStaticPathsContext } from 'next'; +import { getAllPromies } from 'src/utils/funtion.utils'; +import { REVALIDATE_TIME } from 'src/utils/constanst.utils' +import { RecipeCardProps } from 'src/components/common/RecipeCard/RecipeCard'; +interface Props { + recipe:{recipeDetail?: RecipeCardProps}, + relevant:{relevantBlogs?:RecipeCardProps[]} +} +export default function Slug({recipe,relevant}:Props) { -export default function Slug() { return

- - + +
} + +export async function getStaticProps({ + params, + locale, + locales, + preview, +}: GetStaticPropsContext<{ slug: string }> ) { + const config = { locale, locales } + let promisesWithKey = [] as PromiseWithKey[] + let props = {} as any + + // Blog detail + const recipesPromise = await commerce.getRecipeDetail({ + variables: { slug: params!.slug }, + config, + preview, + }) + props.recipe = recipesPromise; + + if (recipesPromise.recipeDetail === null) { + return { notFound: true }; + } + + // // Relevant Blogs + const relevantProductId = recipesPromise?.recipeDetail?.relevantProducts?.[0]; + if (relevantProductId && recipesPromise?.recipeDetail?.relevantProducts?.length > 0) { + + const relevantBlogs = commerce.getRelevantBlogs({ + variables: { productId: relevantProductId }, + config, + preview, + }) + promisesWithKey.push({ key: 'relevant', promise: relevantBlogs}) + + }else { + props.relevantBlogs = []; + } + + + 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: REVALIDATE_TIME, + } + } catch (err) { + + } +} + +export async function getStaticPaths({ locales }: GetStaticPathsContext) { + + const { recipes } = await commerce.getAllRecipePaths() + return { + paths: locales + ? locales.reduce((arr, locale) => { + recipes.forEach((blog: any) => { + arr.push(`/${locale}/recipe/${blog.slug}`) + }) + return arr + }, []) + : recipes.map((product: any) => `/recipe/${product.path}`), + fallback: 'blocking', + } +} + + Slug.Layout = Layout diff --git a/pages/recipes.tsx b/pages/recipes.tsx index e49b903cd..7df69a9da 100644 --- a/pages/recipes.tsx +++ b/pages/recipes.tsx @@ -9,14 +9,14 @@ import { getAllPromies } from 'src/utils/funtion.utils'; import { RecipeCardProps } from 'src/components/common/RecipeCard/RecipeCard'; interface Props { - recipesResult ?: {recipes: RecipeCardProps[],totalItems?: number} , // it will chang when have recipes Props + recipesResult: {recipes: RecipeCardProps[] ,totalItems?: number}, } export default function RecipeListPage({recipesResult}:Props) { return ( <> - + ) } @@ -32,13 +32,12 @@ export async function getStaticProps({ let props = {} as any; - const recipesPromise = commerce.getAllRecipes({ + const recipesPromise = commerce.getAllRecipes({ variables: { excludeBlogIds: [], take: DEFAULT_BLOG_PAGE_SIZE, - sort: { - id: "DESC" - } + id: 'DESC', + isPublish:true }, config, preview, @@ -46,6 +45,7 @@ export async function getStaticProps({ promisesWithKey.push({ key: 'recipesResult', promise: recipesPromise}) + try { const promises = getAllPromies(promisesWithKey) const rs = await Promise.all(promises) @@ -54,7 +54,7 @@ export async function getStaticProps({ props[item.key] = item.keyResult ? rs[index][item.keyResult] : rs[index] return null }) - + return { props, revalidate: 60 diff --git a/src/components/common/RecipeDetail/RecipeDetail.tsx b/src/components/common/RecipeDetail/RecipeDetail.tsx index cdec99994..84d3e4f0d 100644 --- a/src/components/common/RecipeDetail/RecipeDetail.tsx +++ b/src/components/common/RecipeDetail/RecipeDetail.tsx @@ -1,20 +1,21 @@ import React from 'react' +import { RecipeProps } from 'src/utils/types.utils' import { ProductCardProps } from '../ProductCard/ProductCard' import RecipeDetailInfo from './components/RecipeDetailInfo/RecipeDetailInfo' import RecipeIngredient from './components/RecipeIngredient/RecipeIngredient' import s from './RecipeDetail.module.scss' -interface Props { +interface Props extends RecipeProps { className?: string children?: any, - ingredients: ProductCardProps[], + ingredients: ProductCardProps[] } -const RecipeDetail = ({ ingredients }: Props) => { +const RecipeDetail = ({ ingredients,...rest }: Props) => { return (
- +
) diff --git a/src/components/common/RecipeDetail/components/RecipeDetailInfo/RecipeDetailInfo.tsx b/src/components/common/RecipeDetail/components/RecipeDetailInfo/RecipeDetailInfo.tsx index a853ad869..046fa2b55 100644 --- a/src/components/common/RecipeDetail/components/RecipeDetailInfo/RecipeDetailInfo.tsx +++ b/src/components/common/RecipeDetail/components/RecipeDetailInfo/RecipeDetailInfo.tsx @@ -1,24 +1,26 @@ import React from 'react' import { ImgWithLink } from 'src/components/common' +import { RecipeProps } from 'src/utils/types.utils' import RecipeBriefInfo from '../RecipeBriefInfo/RecipeBriefInfo' import s from './RecipeDetailInfo.module.scss' -interface Props { +interface Prop extends RecipeProps { className?: string children?: any } -const RecipeDetailInfo = ({ }: Props) => { +const RecipeDetailInfo = ({ ...rest}: Prop) => { + return (
- +

- Crispy Fried Calamari + {rest.title}

diff --git a/src/components/common/RecommendedRecipes/RecommendedRecipes.tsx b/src/components/common/RecommendedRecipes/RecommendedRecipes.tsx index aa1df57d4..1b8494eeb 100644 --- a/src/components/common/RecommendedRecipes/RecommendedRecipes.tsx +++ b/src/components/common/RecommendedRecipes/RecommendedRecipes.tsx @@ -30,10 +30,10 @@ const RESPONSIVE: ResponsiveType = { }, } interface Props { - data: RecipeCardProps[], + data?: RecipeCardProps[], } -const RecommendedRecipes = ({ data }: Props) => { +const RecommendedRecipes = ({ data=[] }: Props) => { return (
diff --git a/src/components/hooks/recipe/index.ts b/src/components/hooks/recipe/index.ts new file mode 100644 index 000000000..a702a9644 --- /dev/null +++ b/src/components/hooks/recipe/index.ts @@ -0,0 +1 @@ +export {default as useGetRecipeList } from "./useGetRecipeList" \ No newline at end of file diff --git a/src/components/hooks/recipe/useGetRecipeList.tsx b/src/components/hooks/recipe/useGetRecipeList.tsx new file mode 100644 index 000000000..1db9052da --- /dev/null +++ b/src/components/hooks/recipe/useGetRecipeList.tsx @@ -0,0 +1,18 @@ +import { GetAllRecipesQuery,QueryRecipes, RecipeList } from '@framework/schema' +import { normalizeRecipeList } from '@framework/utils/normalize' +import { getAllBlogsQuery } from '@framework/utils/queries/get-all-blog-query' +import gglFetcher from 'src/utils/gglFetcher' +import useSWR from 'swr' + +const useGetRecipeList = (options?: QueryRecipes) => { + const { data, isValidating, ...rest } = useSWR([getAllBlogsQuery, options], gglFetcher) + + return { + reicpes: data?.blogs?.items?.map((recipe:RecipeList)=>normalizeRecipeList(recipe)), + totalItems: data?.blogs?.totalItems || null, + loading: isValidating, + ...rest + } +} + +export default useGetRecipeList diff --git a/src/components/modules/blogs/BlogsList/BlogsList.tsx b/src/components/modules/blogs/BlogsList/BlogsList.tsx index 683b21132..245769b6e 100644 --- a/src/components/modules/blogs/BlogsList/BlogsList.tsx +++ b/src/components/modules/blogs/BlogsList/BlogsList.tsx @@ -18,7 +18,7 @@ interface BlogsListProps { const BlogsList = ({ blogList,total,idFeatured }:BlogsListProps) => { - console.log(blogList) + const DEFAULT_BLOGS_ARGS = useMemo(()=> ({ excludeBlogIds: [idFeatured], options:{ diff --git a/src/components/modules/recipes-list/RecipesList/RecipesList.tsx b/src/components/modules/recipes-list/RecipesList/RecipesList.tsx index 12ebed793..1499292f0 100644 --- a/src/components/modules/recipes-list/RecipesList/RecipesList.tsx +++ b/src/components/modules/recipes-list/RecipesList/RecipesList.tsx @@ -1,220 +1,303 @@ -import React from 'react'; -import { SelectCommon } from 'src/components/common'; -import BreadcrumbCommon from 'src/components/common/BreadcrumbCommon/BreadcrumbCommon'; -import MenuNavigation from 'src/components/common/MenuNavigation/MenuNavigation'; -import PaginationCommon from 'src/components/common/PaginationCommon/PaginationCommon'; -import { RecipeCardProps } from 'src/components/common/RecipeCard/RecipeCard'; -import { OPTION_ALL, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils'; -import HeadingCommon from "../../../common/HeadingCommon/HeadingCommon"; +import React, { useEffect, useState,useRef, useMemo } from 'react' +import { SelectCommon } from 'src/components/common' +import BreadcrumbCommon from 'src/components/common/BreadcrumbCommon/BreadcrumbCommon' +import MenuNavigation from 'src/components/common/MenuNavigation/MenuNavigation' +import PaginationCommon from 'src/components/common/PaginationCommon/PaginationCommon' +import { RecipeCardProps } from 'src/components/common/RecipeCard/RecipeCard' +import { OPTION_ALL, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils' +import HeadingCommon from '../../../common/HeadingCommon/HeadingCommon' import { RecipeCard } from 'src/components/common' +import { DEFAULT_BLOG_PAGE_SIZE } from 'src/utils/constanst.utils' +import s from './RecipesList.module.scss' +import { useRouter } from 'next/router' +import { QueryRecipes } from '@framework/schema' +import { useGetRecipeList } from 'src/components/hooks/recipe' +import { getPageFromQuery } from 'src/utils/funtion.utils' +import { ListBlogCardSkeleton } from 'src/components/common' -import s from './RecipesList.module.scss'; +const recipe: RecipeCardProps[] = [ + { + title: 'Special Recipe of Vietnamese Phở', + description: + 'Alright, before we get to the actual recipe, let’s chat for a sec about the ingredients. To make this pho soup recipe, you will need:', + imageSrc: + 'https://user-images.githubusercontent.com/76729908/132159257-f92574c7-d00d-4142-8ea7-0ca9515fb737.png', + slug: 'special-recipe-of-vietnamese-pho', + }, + { + title: 'Original Recipe of Curry', + description: + 'Chicken curry is common to several countries including India, countries in Asia and the Caribbean. My favorite of them though is this aromatic Indian...', + imageSrc: + 'https://user-images.githubusercontent.com/76729908/132159259-ae4c986d-ab53-4758-9137-d06bafdd15d0.png', + slug: 'original-recipe-of-curry', + }, + { + title: 'The Best Recipe of Beef Noodle Soup', + description: + 'The broth for Bun Bo Hue is prepared by slowly simmering various types of beef and pork bones (ox tail, beef shank, pork neck bones, pork feet,...', + imageSrc: + 'https://user-images.githubusercontent.com/76729908/132159262-f28a9fb9-4852-47e6-80b5-d600521b548a.png', + slug: 'the-best-recipe-of-beef-noodle-soup', + }, + { + title: 'Special Recipe of Vietnamese Phở', + description: + 'Alright, before we get to the actual recipe, let’s chat for a sec about the ingredients. To make this pho soup recipe, you will need:', + imageSrc: + 'https://user-images.githubusercontent.com/76729908/132159257-f92574c7-d00d-4142-8ea7-0ca9515fb737.png', + slug: 'special-recipe-of-vietnamese-pho', + }, + { + title: 'Original Recipe of Curry', + description: + 'Chicken curry is common to several countries including India, countries in Asia and the Caribbean. My favorite of them though is this aromatic Indian...', + imageSrc: + 'https://user-images.githubusercontent.com/76729908/132159259-ae4c986d-ab53-4758-9137-d06bafdd15d0.png', + slug: 'original-recipe-of-curry', + }, + { + title: 'The Best Recipe of Beef Noodle Soup', + description: + 'The broth for Bun Bo Hue is prepared by slowly simmering various types of beef and pork bones (ox tail, beef shank, pork neck bones, pork feet,...', + imageSrc: + 'https://user-images.githubusercontent.com/76729908/132159262-f28a9fb9-4852-47e6-80b5-d600521b548a.png', + slug: 'the-best-recipe-of-beef-noodle-soup', + }, +] -const recipe:RecipeCardProps[] = [ -{ - title: "Special Recipe of Vietnamese Phở", - description: "Alright, before we get to the actual recipe, let’s chat for a sec about the ingredients. To make this pho soup recipe, you will need:", - imageSrc: 'https://user-images.githubusercontent.com/76729908/132159257-f92574c7-d00d-4142-8ea7-0ca9515fb737.png', - slug: "special-recipe-of-vietnamese-pho" -}, -{ - title: "Original Recipe of Curry", - description: "Chicken curry is common to several countries including India, countries in Asia and the Caribbean. My favorite of them though is this aromatic Indian...", - imageSrc: 'https://user-images.githubusercontent.com/76729908/132159259-ae4c986d-ab53-4758-9137-d06bafdd15d0.png', - slug:"original-recipe-of-curry" -}, -{ - title: "The Best Recipe of Beef Noodle Soup", - description: "The broth for Bun Bo Hue is prepared by slowly simmering various types of beef and pork bones (ox tail, beef shank, pork neck bones, pork feet,...", - imageSrc: 'https://user-images.githubusercontent.com/76729908/132159262-f28a9fb9-4852-47e6-80b5-d600521b548a.png', - slug:"the-best-recipe-of-beef-noodle-soup" -}, -{ - title: "Special Recipe of Vietnamese Phở", - description: "Alright, before we get to the actual recipe, let’s chat for a sec about the ingredients. To make this pho soup recipe, you will need:", - imageSrc: 'https://user-images.githubusercontent.com/76729908/132159257-f92574c7-d00d-4142-8ea7-0ca9515fb737.png', - slug: "special-recipe-of-vietnamese-pho" -}, -{ - title: "Original Recipe of Curry", - description: "Chicken curry is common to several countries including India, countries in Asia and the Caribbean. My favorite of them though is this aromatic Indian...", - imageSrc: 'https://user-images.githubusercontent.com/76729908/132159259-ae4c986d-ab53-4758-9137-d06bafdd15d0.png', - slug:"original-recipe-of-curry" -}, -{ - title: "The Best Recipe of Beef Noodle Soup", - description: "The broth for Bun Bo Hue is prepared by slowly simmering various types of beef and pork bones (ox tail, beef shank, pork neck bones, pork feet,...", - imageSrc: 'https://user-images.githubusercontent.com/76729908/132159262-f28a9fb9-4852-47e6-80b5-d600521b548a.png', - slug:"the-best-recipe-of-beef-noodle-soup" -},]; - -const DEFAULT_PAGESIZE_RECIPELIST = 6; +const DEFAULT_PAGESIZE_RECIPELIST = 6 const BREADCRUMB = [ - { - name: 'Special Recipes', - link: `#`, - }, -]; + { + name: 'Special Recipes', + link: `#`, + }, +] const CATEGORY = [ - { - name: 'All', - link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=${OPTION_ALL}`, - }, - { - name: 'Malaysian', - link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=malaysia`, - }, - { - name: 'Vietnamese', - link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=vietnamese`, - }, - { - name: 'Thailand', - link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=thailand`, - }, - { - name: 'Indian', - link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=indian`, - }, - { - name: 'Lao', - link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=lao`, - }, - { - name: 'Chinese', - link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=chinese`, - }, - { - name: 'Korean', - link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=korean`, - }, - { - name: 'Japanese', - link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=japanese`, - }, - { - name: 'Western', - link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=western`, - }, - ]; + { + name: 'All', + link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=${OPTION_ALL}`, + }, + { + name: 'Malaysian', + link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=malaysia`, + }, + { + name: 'Vietnamese', + link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=vietnamese`, + }, + { + name: 'Thailand', + link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=thailand`, + }, + { + name: 'Indian', + link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=indian`, + }, + { + name: 'Lao', + link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=lao`, + }, + { + name: 'Chinese', + link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=chinese`, + }, + { + name: 'Korean', + link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=korean`, + }, + { + name: 'Japanese', + link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=japanese`, + }, + { + name: 'Western', + link: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=western`, + }, +] const CATEGORYSELECT = [ -{ + { name: 'All', value: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=${OPTION_ALL}`, -}, -{ + }, + { name: 'Malaysian', value: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=malaysia`, -}, -{ + }, + { name: 'Vietnamese', value: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=vietnamese`, -}, -{ + }, + { name: 'Thailand', value: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=thailand`, -}, -{ + }, + { name: 'Indian', value: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=indian`, -}, -{ + }, + { name: 'Lao', value: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=lao`, -}, -{ + }, + { name: 'Chinese', value: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=chinese`, -}, -{ + }, + { name: 'Korean', value: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=korean`, -}, -{ + }, + { name: 'Japanese', value: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=japanese`, -}, -{ + }, + { name: 'Western', value: `${ROUTE.RECIPES}/?${QUERY_KEY.RECIPES}=western`, -}, -]; - -const OPTIONSLECT=[ - { - name:"Most Viewed", - value:"most-viewed" - }, - { - name:"Lastest Blogs", - value:"lastest-blogs" - }, - { - name:"Recent Blogs", - value:"recent-blogs" - }, -]; + }, +] -interface Props{ - recipes?: RecipeCardProps[], - total:number +const OPTIONSLECT = [ + { + name: 'Most Viewed', + value: 'most-viewed', + }, + { + name: 'Lastest Blogs', + value: 'lastest-blogs', + }, + { + name: 'Recent Blogs', + value: 'recent-blogs', + }, +] + +interface Props { + recipeList?: RecipeCardProps[] + total: number } +const RecipesList = ({ recipeList, total }: Props) => { + const DEFAULT_BLOGS_ARGS = useMemo( + () => ({ + excludeBlogIds: [], + options:{ + take: DEFAULT_BLOG_PAGE_SIZE, + sort: { + id: 'DESC', + }, + filter:{ + isPublish: { + eq:true + } + } + } + }), + [] + ) + const router = useRouter() + const [initialQueryFlag, setInitialQueryFlag] = useState(true) + const [optionQueryBlog, setOptionQueryBlog] = useState(DEFAULT_BLOGS_ARGS) + const { reicpes, totalItems, loading } = useGetRecipeList(optionQueryBlog) + -const RecipesList = ({ recipes,total }:Props) => { - console.log(recipes) - return ( - <> -
-
- -
-
- -
- -
- -
- SPECIAL RECIPES - -
-
- -
- -
-
-
- -
- -
-
-
- -
-
- {recipes?.map((item,index) => ( -
- -
- ))} -
-
-
- -
-
- -
- -
- + const onPageChange = (page: number) => { + router.push( + { + pathname: ROUTE.RECIPES, + query: { + ...router.query, + [QUERY_KEY.PAGE]: page, + }, + }, + undefined, + { shallow: true } ) + } + + // skip + const firstRender = useRef(true); + + useEffect(() => { + firstRender.current = false + const query = { ...DEFAULT_BLOGS_ARGS } as QueryRecipes + const page = getPageFromQuery(router.query[QUERY_KEY.PAGE] as string) + query.options.skip = page * DEFAULT_BLOG_PAGE_SIZE + setOptionQueryBlog(query) + setInitialQueryFlag(false) + }, [router.query]) + + + let data; + if(initialQueryFlag == true){ + data = recipeList; + }else{ + data = reicpes + } + + return ( + <> +
+
+ +
+
+
+ +
+ +
+ SPECIAL RECIPES + +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
+ {(!initialQueryFlag && loading && !data) && } + {data?.map((item, index) => ( +
+ +
+ ))} +
+
+
+ +
+
+
+
+ + ) } export default RecipesList diff --git a/src/utils/types.utils.ts b/src/utils/types.utils.ts index 1b600b551..fee4cf2b1 100644 --- a/src/utils/types.utils.ts +++ b/src/utils/types.utils.ts @@ -24,6 +24,10 @@ export interface RecipeProps { slug: string description: string imageSrc: string + content?: string, + imgAuthor?: string, + date?: string, + authorName?: string, } export interface BlogProps {