From 9ad0f0ef6b49674fd8128907a9336b70b05a0446 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Tue, 27 Oct 2020 03:13:25 -0500 Subject: [PATCH] Added actions and more stuff to the wishlist page --- .../product/ProductView/ProductView.tsx | 4 +- .../wishlist/WishlistCard/WishlistCard.tsx | 97 ++++++++++++++++--- .../api/operations/get-customer-wishlist.ts | 10 +- lib/bigcommerce/api/wishlist/index.ts | 7 +- lib/bigcommerce/wishlist/use-add-item.tsx | 10 +- lib/bigcommerce/wishlist/use-remove-item.tsx | 10 +- lib/bigcommerce/wishlist/use-wishlist.tsx | 2 +- pages/wishlist.tsx | 71 ++++++-------- 8 files changed, 137 insertions(+), 74 deletions(-) diff --git a/components/product/ProductView/ProductView.tsx b/components/product/ProductView/ProductView.tsx index a57d88a2d..98b7bde53 100644 --- a/components/product/ProductView/ProductView.tsx +++ b/components/product/ProductView/ProductView.tsx @@ -14,7 +14,7 @@ import type { ProductNode } from '@lib/bigcommerce/api/operations/get-product' import { getCurrentVariant, getProductOptions, - ProductOptions, + SelectedOptions, } from '../helpers' import WishlistButton from '@components/wishlist/WishlistButton' @@ -29,7 +29,7 @@ const ProductView: FC = ({ product }) => { const { openSidebar } = useUI() const options = getProductOptions(product) const [loading, setLoading] = useState(false) - const [choices, setChoices] = useState({ + const [choices, setChoices] = useState({ size: null, color: null, }) diff --git a/components/wishlist/WishlistCard/WishlistCard.tsx b/components/wishlist/WishlistCard/WishlistCard.tsx index eeacfa779..5addca493 100644 --- a/components/wishlist/WishlistCard/WishlistCard.tsx +++ b/components/wishlist/WishlistCard/WishlistCard.tsx @@ -1,4 +1,14 @@ -import { FC } from 'react' +import { FC, useState } from 'react' +import cn from 'classnames' +import Link from 'next/link' +import Image from 'next/image' +import type { WishlistItem } from '@lib/bigcommerce/api/wishlist' +import usePrice from '@lib/commerce/use-price' +import useRemoveItem from '@lib/bigcommerce/wishlist/use-remove-item' +import useAddItem from '@lib/bigcommerce/cart/use-add-item' +import { useUI } from '@components/ui/context' +import { Button } from '@components/ui' +import { HTMLContent } from '@components/core' import { Trash } from '@components/icons' import s from './WishlistCard.module.css' @@ -6,6 +16,7 @@ interface Props { className?: string children?: any data?: ProductData + item: WishlistItem } interface ProductData { @@ -15,23 +26,83 @@ interface ProductData { path: string } -const WishlistCard: FC = ({ className, data }) => { +const WishlistCard: FC = ({ className, item }) => { + const product = item.product! + const { price } = usePrice({ + amount: product.prices?.price?.value, + baseAmount: product.prices?.retailPrice?.value, + currencyCode: product.prices?.price?.currencyCode!, + }) + const removeItem = useRemoveItem({ includeProducts: true }) + const [loading, setLoading] = useState(false) + const [removing, setRemoving] = useState(false) + const addItem = useAddItem() + const { openSidebar } = useUI() + + const handleRemove = async () => { + setRemoving(true) + + try { + // If this action succeeds then there's no need to do `setRemoving(true)` + // because the component will be removed from the view + await removeItem({ id: item.id! }) + } catch (error) { + setRemoving(false) + } + } + const addToCart = async () => { + setLoading(true) + try { + await addItem({ + productId: product.entityId, + variantId: product.variants.edges?.[0]?.node.entityId!, + }) + openSidebar() + setLoading(false) + } catch (err) { + setLoading(false) + } + } + return ( -
-
+
+
+ {product.images.edges?.[0]?.node.altText +
+
-

Jacket

-

- Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake. -

- +

+ + {product.name} + +

+
+ +
+
-
$ 50.00
+
{price}
- +
diff --git a/lib/bigcommerce/api/operations/get-customer-wishlist.ts b/lib/bigcommerce/api/operations/get-customer-wishlist.ts index 48e9e9c4d..2c1299b46 100644 --- a/lib/bigcommerce/api/operations/get-customer-wishlist.ts +++ b/lib/bigcommerce/api/operations/get-customer-wishlist.ts @@ -4,9 +4,13 @@ import { BigcommerceConfig, getConfig } from '..' import getAllProducts, { ProductEdge } from './get-all-products' export type Wishlist = Omit & { - items?: (NonNullable[0] & { - product?: ProductEdge['node'] - })[] + items?: WishlistItem[] +} + +export type WishlistItem = NonNullable< + definitions['wishlist_Full']['items'] +>[0] & { + product?: ProductEdge['node'] } export type GetCustomerWishlistResult< diff --git a/lib/bigcommerce/api/wishlist/index.ts b/lib/bigcommerce/api/wishlist/index.ts index 9be4e7d5f..94194dd41 100644 --- a/lib/bigcommerce/api/wishlist/index.ts +++ b/lib/bigcommerce/api/wishlist/index.ts @@ -4,12 +4,15 @@ import createApiHandler, { BigcommerceHandler, } from '../utils/create-api-handler' import { BigcommerceApiError } from '../utils/errors' -import type { Wishlist } from '../operations/get-customer-wishlist' +import type { + Wishlist, + WishlistItem, +} from '../operations/get-customer-wishlist' import getWishlist from './handlers/get-wishlist' import addItem from './handlers/add-item' import removeItem from './handlers/remove-item' -export type { Wishlist } +export type { Wishlist, WishlistItem } export type ItemBody = { productId: number diff --git a/lib/bigcommerce/wishlist/use-add-item.tsx b/lib/bigcommerce/wishlist/use-add-item.tsx index c5f608579..8815ca72d 100644 --- a/lib/bigcommerce/wishlist/use-add-item.tsx +++ b/lib/bigcommerce/wishlist/use-add-item.tsx @@ -4,7 +4,7 @@ import { CommerceError } from '../../commerce/utils/errors' import useWishlistAddItem from '../../commerce/wishlist/use-add-item' import type { ItemBody, AddItemBody } from '../api/wishlist' import useCustomer from '../use-customer' -import useWishlist, { Wishlist } from './use-wishlist' +import useWishlist, { UseWishlistOptions, Wishlist } from './use-wishlist' const defaultOpts = { url: '/api/bigcommerce/wishlist', @@ -27,9 +27,9 @@ export const fetcher: HookFetcher = ( } export function extendHook(customFetcher: typeof fetcher) { - const useAddItem = () => { + const useAddItem = (opts?: UseWishlistOptions) => { const { data: customer } = useCustomer() - const { mutate } = useWishlist() + const { revalidate } = useWishlist(opts) const fn = useWishlistAddItem(defaultOpts, customFetcher) return useCallback( @@ -42,10 +42,10 @@ export function extendHook(customFetcher: typeof fetcher) { } const data = await fn({ item: input }) - await mutate(data, false) + await revalidate() return data }, - [fn, mutate, customer] + [fn, revalidate, customer] ) } diff --git a/lib/bigcommerce/wishlist/use-remove-item.tsx b/lib/bigcommerce/wishlist/use-remove-item.tsx index f8a4ddba9..133c6d9ff 100644 --- a/lib/bigcommerce/wishlist/use-remove-item.tsx +++ b/lib/bigcommerce/wishlist/use-remove-item.tsx @@ -4,7 +4,7 @@ import { CommerceError } from '../../commerce/utils/errors' import useWishlistRemoveItem from '../../commerce/wishlist/use-remove-item' import type { RemoveItemBody } from '../api/wishlist' import useCustomer from '../use-customer' -import useWishlist, { Wishlist } from './use-wishlist' +import useWishlist, { UseWishlistOptions, Wishlist } from './use-wishlist' const defaultOpts = { url: '/api/bigcommerce/wishlist', @@ -28,9 +28,9 @@ export const fetcher: HookFetcher = ( } export function extendHook(customFetcher: typeof fetcher) { - const useRemoveItem = () => { + const useRemoveItem = (opts?: UseWishlistOptions) => { const { data: customer } = useCustomer() - const { mutate } = useWishlist() + const { revalidate } = useWishlist(opts) const fn = useWishlistRemoveItem( defaultOpts, customFetcher @@ -46,10 +46,10 @@ export function extendHook(customFetcher: typeof fetcher) { } const data = await fn({ itemId: String(input.id) }) - await mutate(data, false) + await revalidate() return data }, - [fn, mutate, customer] + [fn, revalidate, customer] ) } diff --git a/lib/bigcommerce/wishlist/use-wishlist.tsx b/lib/bigcommerce/wishlist/use-wishlist.tsx index c3f8b6100..0d4c843b8 100644 --- a/lib/bigcommerce/wishlist/use-wishlist.tsx +++ b/lib/bigcommerce/wishlist/use-wishlist.tsx @@ -60,7 +60,7 @@ export function extendHook( // response.data is also a getter and it's better to not trigger it early Object.defineProperty(response, 'isEmpty', { get() { - return (response.data?.items?.length || 0) > 0 + return (response.data?.items?.length || 0) <= 0 }, set: (x) => x, }) diff --git a/pages/wishlist.tsx b/pages/wishlist.tsx index 2cc61cb6e..a27e26312 100644 --- a/pages/wishlist.tsx +++ b/pages/wishlist.tsx @@ -1,64 +1,49 @@ -import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next' +import type { GetStaticPropsContext } from 'next' import getAllPages from '@lib/bigcommerce/api/operations/get-all-pages' import useWishlist from '@lib/bigcommerce/wishlist/use-wishlist' import { Layout } from '@components/core' +import { Heart } from '@components/icons' import { Container, Text } from '@components/ui' import { WishlistCard } from '@components/wishlist' -import getSiteInfo from '@lib/bigcommerce/api/operations/get-site-info' - export async function getStaticProps({ preview }: GetStaticPropsContext) { const { pages } = await getAllPages({ preview }) - const { categories, brands } = await getSiteInfo({ preview }) return { - props: { pages, categories, brands }, + props: { pages }, } } -export default function Home({ - categories, - brands, -}: InferGetStaticPropsType) { - const { data } = useWishlist({ includeProducts: true }) - console.log(data) +export default function Wishlist() { + const { data, isEmpty } = useWishlist({ includeProducts: true }) + return ( -
-
-
    -
  • - All Categories -
  • - {categories.map((cat) => ( -
  • - {cat.name} -
  • - ))} -
-
-
- My Wishlist -
- {[1, 2, 3, 4, 5, 6].map((i) => ( - - ))} -
-
-
-
    -
  • - Relevance -
  • -
  • Latest arrivals
  • -
  • Trending
  • -
  • Price: Low to high
  • -
  • Price: High to low
  • -
+
+ My Wishlist +
+ {isEmpty ? ( +
+ + + +

+ Your wishlist is empty +

+

+ Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake. +

+
+ ) : ( + data && + data.items?.map((item) => ( + + )) + )}
) } -Home.Layout = Layout +Wishlist.Layout = Layout