@@ -49,6 +49,7 @@ function SubmitButton({
className={clsx(buttonClasses, {
'hover:opacity-90': true
})}
+ data-test="add-to-cart"
>
@@ -62,27 +63,37 @@ export function AddToCart({ product }: { product: Product }) {
const { variants, availableForSale } = product;
const { addCartItem } = useCart();
const { state } = useProduct();
- const [message, formAction] = useFormState(addItem, null);
+ // Trouver le variant correspondant à l'état actuel du produit
const variant = variants.find((variant: ProductVariant) =>
variant.selectedOptions.every((option) => option.value === state[option.name.toLowerCase()])
);
- const defaultVariantId = variants.length === 1 ? variants[0]?.id : undefined;
- const selectedVariantId = variant?.id || defaultVariantId;
- const actionWithVariant = formAction.bind(null, selectedVariantId);
- const finalVariant = variants.find((variant) => variant.id === selectedVariantId)!;
+ const defaultVariant = variants.length === 1 ? variants[0] : undefined;
+ const selectedVariant = variant || defaultVariant;
+ const handleSubmit = async (event: React.FormEvent) => {
+ event.preventDefault();
+ event.stopPropagation(); // Assure-toi d'arrêter la propagation des événements
+
+ if (selectedVariant) {
+ addCartItem(selectedVariant, product); // Appel avec l'objet ProductVariant
+
+ // Appel côté serveur pour ajouter au panier via Shopify
+ try {
+ await addItem(null, selectedVariant.id); // Appel côté serveur
+ } catch (error) {
+ console.error('Error adding item to server cart:', error);
+ }
+ } else {
+ console.error('No variant selected');
+ }
+ };
return (
-
);
}
diff --git a/components/cart/cart-context.tsx b/components/cart/cart-context.tsx
index 2d8ddd42f..0783a11d1 100644
--- a/components/cart/cart-context.tsx
+++ b/components/cart/cart-context.tsx
@@ -1,7 +1,14 @@
'use client';
import type { Cart, CartItem, Product, ProductVariant } from 'lib/shopify/types';
-import React, { createContext, use, useContext, useMemo, useOptimistic } from 'react';
+import React, {
+ createContext,
+ startTransition,
+ use,
+ useContext,
+ useMemo,
+ useOptimistic
+} from 'react';
type UpdateType = 'plus' | 'minus' | 'delete';
@@ -50,9 +57,10 @@ function createOrUpdateCartItem(
): CartItem {
const quantity = existingItem ? existingItem.quantity + 1 : 1;
const totalAmount = calculateItemCost(quantity, variant.price.amount);
+ const itemId = variant.id ?? existingItem?.id;
return {
- id: existingItem?.id,
+ id: itemId,
quantity,
cost: {
totalAmount: {
@@ -131,6 +139,10 @@ function cartReducer(state: Cart | undefined, action: CartAction): Cart {
}
case 'ADD_ITEM': {
const { variant, product } = action.payload;
+ if (!variant.id) {
+ return currentCart; // Ne pas ajouter l'article si l'ID est manquant
+ }
+
const existingItem = currentCart.lines.find((item) => item.merchandise.id === variant.id);
const updatedItem = createOrUpdateCartItem(existingItem, variant, product);
@@ -156,11 +168,15 @@ export function CartProvider({
const [optimisticCart, updateOptimisticCart] = useOptimistic(initialCart, cartReducer);
const updateCartItem = (merchandiseId: string, updateType: UpdateType) => {
- updateOptimisticCart({ type: 'UPDATE_ITEM', payload: { merchandiseId, updateType } });
+ startTransition(() => {
+ updateOptimisticCart({ type: 'UPDATE_ITEM', payload: { merchandiseId, updateType } });
+ });
};
const addCartItem = (variant: ProductVariant, product: Product) => {
- updateOptimisticCart({ type: 'ADD_ITEM', payload: { variant, product } });
+ startTransition(() => {
+ updateOptimisticCart({ type: 'ADD_ITEM', payload: { variant, product } });
+ });
};
const value = useMemo(
diff --git a/components/cart/delete-item-button.tsx b/components/cart/delete-item-button.tsx
index fb2aa310b..94b0f3552 100644
--- a/components/cart/delete-item-button.tsx
+++ b/components/cart/delete-item-button.tsx
@@ -3,7 +3,7 @@
import { XMarkIcon } from '@heroicons/react/24/outline';
import { removeItem } from 'components/cart/actions';
import type { CartItem } from 'lib/shopify/types';
-import { useFormState } from 'react-dom';
+import { useActionState } from 'react';
export function DeleteItemButton({
item,
@@ -12,7 +12,7 @@ export function DeleteItemButton({
item: CartItem;
optimisticUpdate: any;
}) {
- const [message, formAction] = useFormState(removeItem, null);
+ const [message, formAction] = useActionState(removeItem, null);
const merchandiseId = item.merchandise.id;
const actionWithVariant = formAction.bind(null, merchandiseId);
diff --git a/components/cart/edit-item-quantity-button.tsx b/components/cart/edit-item-quantity-button.tsx
index 28ac78ba5..c2daf0be6 100644
--- a/components/cart/edit-item-quantity-button.tsx
+++ b/components/cart/edit-item-quantity-button.tsx
@@ -4,7 +4,7 @@ import { MinusIcon, PlusIcon } from '@heroicons/react/24/outline';
import clsx from 'clsx';
import { updateItemQuantity } from 'components/cart/actions';
import type { CartItem } from 'lib/shopify/types';
-import { useFormState } from 'react-dom';
+import { useActionState } from 'react';
function SubmitButton({ type }: { type: 'plus' | 'minus' }) {
return (
@@ -17,6 +17,7 @@ function SubmitButton({ type }: { type: 'plus' | 'minus' }) {
'ml-auto': type === 'minus'
}
)}
+ data-test={`cart-quantity-${type}-button`}
>
{type === 'plus' ? (
@@ -36,7 +37,7 @@ export function EditItemQuantityButton({
type: 'plus' | 'minus';
optimisticUpdate: any;
}) {
- const [message, formAction] = useFormState(updateItemQuantity, null);
+ const [message, formAction] = useActionState(updateItemQuantity, null);
const payload = {
merchandiseId: item.merchandise.id,
quantity: type === 'plus' ? item.quantity + 1 : item.quantity - 1
diff --git a/components/cart/modal.tsx b/components/cart/modal.tsx
index ca1e34652..96e428ac6 100644
--- a/components/cart/modal.tsx
+++ b/components/cart/modal.tsx
@@ -49,7 +49,7 @@ export default function CartModal() {
return (
<>
-