diff --git a/app/product/[...handle]/page.tsx b/app/product/[...handle]/page.tsx index 573fe475b..4c54e2dfd 100644 --- a/app/product/[...handle]/page.tsx +++ b/app/product/[...handle]/page.tsx @@ -2,12 +2,12 @@ import type { Metadata } from 'next'; import { notFound } from 'next/navigation'; import { Suspense } from 'react'; +import { AddToCart } from 'components/cart/add-to-cart'; import Grid from 'components/grid'; import Footer from 'components/layout/footer'; -import ProductGridItems from 'components/layout/product-grid-items'; -import { AddToCart } from 'components/cart/add-to-cart'; -import { Gallery } from 'components/product/gallery'; import { VariantSelector } from 'components/product/variant-selector'; +import ProductGridItems from 'components/layout/product-grid-items'; +import { Gallery } from 'components/product/gallery'; import Prose from 'components/prose'; import { HIDDEN_PRODUCT_TAG } from 'lib/constants'; import { getProduct, getProductRecommendations } from 'lib/shopware'; @@ -104,7 +104,11 @@ export default async function ProductPage({ params }: { params: { handle: string ) : null} - + diff --git a/components/carousel.tsx b/components/carousel.tsx index e8a080c5b..38b403d2e 100644 --- a/components/carousel.tsx +++ b/components/carousel.tsx @@ -20,7 +20,7 @@ export async function Carousel() { {product.featuredImage ? ( => { - const cartId = cookies().get('cartId')?.value; - - if (!cartId || !variantId) { - return new Error('Missing cartId or variantId'); - } +export const fetchCart = async function (cartId?: string): Promise { try { - await addToCart(cartId, [{ merchandiseId: variantId, quantity: 1 }]); - } catch (e) { - return new Error('Error adding item', { cause: e }); + const apiClient = getApiClient(cartId); + const cart = await apiClient.invoke('readCart get /checkout/cart?name', {}); + + return cart; + } catch (error) { + if (error instanceof ApiClientError) { + console.error(error); + console.error('Details:', error.details); + } else { + console.error('==>', error); + } + } +}; + +export const addItem = async (variantId: string | undefined): Promise => { + const cartId = cookies().get('sw-context-token')?.value; + + if (!variantId) { + return new Error('Missing variantId'); + } + + try { + let quantity = 1; + const apiClient = getApiClient(cartId); + + // this part allows us to click multiple times on addToCart and increase the qty with that + const cart = await fetchCart(cartId); + const itemInCart = cart?.lineItems?.filter((item) => item.id === variantId) as + | ExtendedLineItem + | undefined; + if (itemInCart && itemInCart.quantity) { + quantity = itemInCart.quantity + 1; + } + + await apiClient.invoke('addLineItem post /checkout/cart/line-item', { + items: [ + { + id: variantId, + quantity: quantity, + referencedId: variantId, + type: 'product' + } + ] + }); + } catch (error) { + if (error instanceof ApiClientError) { + console.error(error); + console.error('Details:', error.details); + } else { + console.error('==>', error); + } } }; export const removeItem = async (lineId: string): Promise => { - const cartId = cookies().get('cartId')?.value; + const cartId = cookies().get('sw-context-token')?.value; if (!cartId) { return new Error('Missing cartId'); } + try { - await removeFromCart(cartId, [lineId]); - } catch (e) { - return new Error('Error removing item', { cause: e }); + const apiClient = getApiClient(cartId); + await apiClient.invoke('deleteLineItem delete /checkout/cart/line-item?id[]={ids}', { + ids: [lineId] + }); + } catch (error) { + if (error instanceof ApiClientError) { + console.error(error); + console.error('Details:', error.details); + } else { + console.error('==>', error); + } } }; @@ -38,20 +92,29 @@ export const updateItemQuantity = async ({ variantId: string; quantity: number; }): Promise => { - const cartId = cookies().get('cartId')?.value; + const cartId = cookies().get('sw-context-token')?.value; if (!cartId) { return new Error('Missing cartId'); } + try { - await updateCart(cartId, [ - { - id: lineId, - merchandiseId: variantId, - quantity - } - ]); - } catch (e) { - return new Error('Error updating item quantity', { cause: e }); + const apiClient = getApiClient(cartId); + await apiClient.invoke('updateLineItem patch /checkout/cart/line-item', { + items: [ + { + id: lineId, + referencedId: variantId, + quantity: quantity + } + ] + }); + } catch (error) { + if (error instanceof ApiClientError) { + console.error(error); + console.error('Details:', error.details); + } else { + console.error('==>', error); + } } }; diff --git a/components/cart/add-to-cart.tsx b/components/cart/add-to-cart.tsx index 3cc403315..0f532d784 100644 --- a/components/cart/add-to-cart.tsx +++ b/components/cart/add-to-cart.tsx @@ -6,16 +6,19 @@ import { useRouter, useSearchParams } from 'next/navigation'; import { useEffect, useState, useTransition } from 'react'; import LoadingDots from 'components/loading-dots'; +import { Product } from 'lib/shopware/types'; import { ProductVariant } from 'lib/shopware/types'; export function AddToCart({ + product, variants, availableForSale }: { variants: ProductVariant[]; availableForSale: boolean; + product: Product; }) { - const [selectedVariantId, setSelectedVariantId] = useState(variants[0]?.id); + const [selectedVariantId, setSelectedVariantId] = useState(product.id); const router = useRouter(); const searchParams = useSearchParams(); const [isPending, startTransition] = useTransition(); @@ -30,7 +33,7 @@ export function AddToCart({ if (variant) { setSelectedVariantId(variant.id); } - }, [searchParams, variants, setSelectedVariantId]); + }, [searchParams, variants, setSelectedVariantId, selectedVariantId]); return (