diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts index dad5fffed..d4fcc3847 100644 --- a/framework/vendure/schema.d.ts +++ b/framework/vendure/schema.d.ts @@ -3247,10 +3247,22 @@ export type ActiveCustomerQuery = { __typename?: 'Query' } & { activeCustomer?: Maybe< { __typename?: 'Customer' } & Pick< Customer, - 'id' | 'firstName' | 'lastName' | 'emailAddress' | 'addresses' | 'phoneNumber' + 'id' | 'firstName' | 'lastName' | 'emailAddress' | 'addresses' | 'phoneNumber'| 'favorites' > > } +export type FavoriteList = PaginatedList & { + items: [Favorite!]! + totalItems: Int! +} + +type Favorite = Node & { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + product: Product + customer: Customer! +} export type GetAllProductPathsQueryVariables = Exact<{ first?: Maybe diff --git a/framework/vendure/utils/mutations/toggle-wishlist-mutation.tsx b/framework/vendure/utils/mutations/toggle-wishlist-mutation.tsx new file mode 100644 index 000000000..d3dcb7c18 --- /dev/null +++ b/framework/vendure/utils/mutations/toggle-wishlist-mutation.tsx @@ -0,0 +1,9 @@ +export const toggleWishlistMutation = /* GraphQL */ ` + mutation toggleFavorite($productId:ID!){ + toggleFavorite(productId:$productId){ + items{ + id + } + } + } +` diff --git a/framework/vendure/utils/queries/active-customer-query.ts b/framework/vendure/utils/queries/active-customer-query.ts index b1598d8de..fb2579ff5 100644 --- a/framework/vendure/utils/queries/active-customer-query.ts +++ b/framework/vendure/utils/queries/active-customer-query.ts @@ -1,17 +1,35 @@ +import { searchResultFragment } from '../fragments/search-result-fragment' + export const activeCustomerQuery = /* GraphQL */ ` - query activeCustomer { - activeCustomer { - id - firstName - lastName - emailAddress - phoneNumber - addresses{ - streetLine1 - city - province - postalCode +query activeCustomer { + activeCustomer { + id + firstName + lastName + emailAddress + favorites{ + items{ + product{ + id + name + slug + assets{ + source + preview + } + variants{ + price + } + } } } + phoneNumber + addresses{ + streetLine1 + city + province + postalCode + } } +} ` diff --git a/src/components/common/ItemWishList/ItemWishList.tsx b/src/components/common/ItemWishList/ItemWishList.tsx index 74d0b3b04..ac72c6879 100644 --- a/src/components/common/ItemWishList/ItemWishList.tsx +++ b/src/components/common/ItemWishList/ItemWishList.tsx @@ -2,19 +2,38 @@ import classNames from 'classnames' import IconHeart from 'src/components/icons/IconHeart' import React, { memo } from 'react' import s from './ItemWishList.module.scss' - +import { useToggleProductWishlist } from '../../../../src/components/hooks/product' +import { useMessage } from 'src/components/contexts' +import { LANGUAGE } from 'src/utils/language.utils' interface Props { + id:string, isActive?: boolean, - onChange?: () => void + onChange?: () => string } -const ItemWishList = memo(({isActive=false, onChange}:Props) => { +const ItemWishList = memo(({id,isActive=false, onChange}:Props) => { + const {onToggleProductWishlist} = useToggleProductWishlist(); + const { showMessageSuccess, showMessageError } = useMessage(); + + function toggleWishlist(){ + onToggleProductWishlist({productId:id},onSignupCallBack) + } + + const onSignupCallBack = (isSuccess: boolean, message?: string) => { + if (isSuccess) { + // showMessageSuccess("Create account successfully. Please verify your email to login.", 15000) + } else { + showMessageError(message || LANGUAGE.MESSAGE.ERROR) + } + } + return(
diff --git a/src/components/common/ProductCard/ProductCard.tsx b/src/components/common/ProductCard/ProductCard.tsx index 4761aac92..51038c9d6 100644 --- a/src/components/common/ProductCard/ProductCard.tsx +++ b/src/components/common/ProductCard/ProductCard.tsx @@ -14,9 +14,11 @@ import ProductNotSell from './ProductNotSell/ProductNotSell' export interface ProductCardProps extends ProductCard { buttonText?: string isSingleButton?: boolean, + activeWishlist?:boolean } const ProductCardComponent = ({ + id, collection, name, slug, @@ -27,6 +29,7 @@ const ProductCardComponent = ({ imageSrc, isNotSell, isSingleButton, + activeWishlist }: ProductCardProps) => { if (isNotSell) { return
@@ -34,6 +37,7 @@ const ProductCardComponent = ({
} + return (
@@ -63,7 +67,7 @@ const ProductCardComponent = ({
{price} {currencyCode}
- +
diff --git a/src/components/common/ProductList/ProductList.tsx b/src/components/common/ProductList/ProductList.tsx index c901b4d46..de9cb94d5 100644 --- a/src/components/common/ProductList/ProductList.tsx +++ b/src/components/common/ProductList/ProductList.tsx @@ -1,12 +1,12 @@ import classNames from 'classnames' import { useRouter } from 'next/router' import React from 'react' +import { useActiveCustomer } from 'src/components/hooks/auth' import { DEFAULT_PAGE_SIZE, ROUTE } from 'src/utils/constanst.utils' import { ButtonCommon, EmptyCommon } from '..' import PaginationCommon from '../PaginationCommon/PaginationCommon' import ProductCard, { ProductCardProps } from '../ProductCard/ProductCard' import s from "./ProductList.module.scss" - interface ProductListProps { data: ProductCardProps[], total?: number, @@ -16,6 +16,8 @@ interface ProductListProps { const ProductList = ({ data, total = data.length, defaultCurrentPage, onPageChange }: ProductListProps) => { const router = useRouter() + const {wishlistId } = useActiveCustomer(); + const handlePageChange = (page: number) => { onPageChange && onPageChange(page) } @@ -33,7 +35,8 @@ const ProductList = ({ data, total = data.length, defaultCurrentPage, onPageChan
{ data.map((product, index) => { - return + let activeWishlist = wishlistId?.findIndex((val:string) => val == product.id) !== -1; + return }) } { diff --git a/src/components/hooks/auth/useActiveCustomer.tsx b/src/components/hooks/auth/useActiveCustomer.tsx index 353ce8ad9..7978ab367 100644 --- a/src/components/hooks/auth/useActiveCustomer.tsx +++ b/src/components/hooks/auth/useActiveCustomer.tsx @@ -1,20 +1,24 @@ -import { ActiveCustomerQuery } from '@framework/schema' +import { ActiveCustomerQuery,Favorite } from '@framework/schema' import { activeCustomerQuery } from '@framework/utils/queries/active-customer-query' import gglFetcher from 'src/utils/gglFetcher' import useSWR from 'swr' const useActiveCustomer = () => { const { data, ...rest } = useSWR([activeCustomerQuery], gglFetcher) - return { - customer: data?.activeCustomer, - userInfo:{ - firstName: data?.activeCustomer?.firstName, - lastName:data?.activeCustomer?.lastName, - email:data?.activeCustomer?.emailAddress, - phoneNumber: data?.activeCustomer?.phoneNumber, - address: data?.activeCustomer?.addresses?.[0] - }, - ...rest } + + return { + customer: data?.activeCustomer, + userInfo:{ + firstName: data?.activeCustomer?.firstName, + lastName:data?.activeCustomer?.lastName, + email:data?.activeCustomer?.emailAddress, + phoneNumber: data?.activeCustomer?.phoneNumber, + address: data?.activeCustomer?.addresses?.[0] + }, + itemWishlist:data?.activeCustomer?.favorites?.items, + wishlistId: data?.activeCustomer?.favorites?.items.map((val:Favorite)=>val.product.id), + ...rest + } } export default useActiveCustomer diff --git a/src/components/hooks/product/index.ts b/src/components/hooks/product/index.ts index 5fb85680c..58dc37f27 100644 --- a/src/components/hooks/product/index.ts +++ b/src/components/hooks/product/index.ts @@ -1,4 +1,5 @@ export { default as useSearchProducts } from './useSearchProducts' +export { default as useToggleProductWishlist } from './useToggleProductWishlist' export { default as useProductDetail } from './useProductDetail' diff --git a/src/components/hooks/product/useToggleProductWishlist.tsx b/src/components/hooks/product/useToggleProductWishlist.tsx new file mode 100644 index 000000000..452707f46 --- /dev/null +++ b/src/components/hooks/product/useToggleProductWishlist.tsx @@ -0,0 +1,44 @@ +import { useState } from 'react' +import useActiveCustomer from '../auth/useActiveCustomer' +import { FavoriteList } from '@framework/schema' +import fetcher from 'src/utils/fetcher' +import { CommonError } from 'src/domains/interfaces/CommonError' +import { toggleWishlistMutation } from '@framework/utils/mutations/toggle-wishlist-mutation' + +interface Props { + productId?:string +} + +const useToggleProductWishlist = () => { + const [loading, setLoading] = useState(false) + const [error, setError] = useState(null) + const { mutate } = useActiveCustomer() + + const onToggleProductWishlist = ( + { productId }:Props , + fCallBack: (isSuccess: boolean, message?: string) => void + ) => { + setError(null) + setLoading(true) + fetcher({ + query: toggleWishlistMutation, + variables: { + productId + }, + }) + .then((data) => { + mutate() + fCallBack(true) + return data + }) + .catch((error) => { + setError(error) + fCallBack(false, error.message) + }) + .finally(() => setLoading(false)) + } + + return { loading, onToggleProductWishlist, error } +} + +export default useToggleProductWishlist diff --git a/src/components/modules/account/AccountPage/AccountPage.tsx b/src/components/modules/account/AccountPage/AccountPage.tsx index d8c169647..39edeadfb 100644 --- a/src/components/modules/account/AccountPage/AccountPage.tsx +++ b/src/components/modules/account/AccountPage/AccountPage.tsx @@ -13,7 +13,6 @@ import { PRODUCT_CART_DATA_TEST } from 'src/utils/demo-data'; import { ACCOUNT_TAB, QUERY_KEY } from "src/utils/constanst.utils" import { useRouter } from "next/router" import { useActiveCustomer } from 'src/components/hooks/auth' -import { AccountProps } from "./components/AccountInfomation/AccountInfomation" const waiting = [ { id: "NO 123456", @@ -77,6 +76,8 @@ const AccountPage = ({ defaultActiveContent="orders" } : AccountPageProps) => { const [activeTab, setActiveTab] = useState(defaultActiveContent==="info" ? 0 : defaultActiveContent==="orders" ? 1 : 2) const [modalVisible, setModalVisible] = useState(false); + // const { itemWishlist } = useActiveCustomer(); + // console.log(itemWishlist) useEffect(() => { const query = router.query[QUERY_KEY.TAB] as string