import React from "react";
import {
useCheckoutAction,
useCheckoutSession,
useMessages,
type CheckoutSession
} from "@ollie-shop/sdk";
import styles from "./styles.module.css";
export default function CartItem({
item = {
id: "1",
name: "Product Name",
quantity: 1,
price: 10000,
originalPrice: 12000,
available: true,
index: 0,
image: "https://example.com/image.jpg",
url: "/product-name/p",
},
} : {
item: CheckoutSession['cartItems'][number];
}) {
const { session } = useCheckoutSession();
const { addMessage } = useMessages();
const { currency, language } = session.locale;
const hasDiscount = item.originalPrice && item.price !== item.originalPrice;
// Add actions with success and error messages
const { execute: executeActionRemoveItems } =
useCheckoutAction("REMOVE_ITEMS", {
onSuccess() {
addMessage({
type: "success",
content: "Item removed successfully.",
});
},
onError({ serverError }) {
addMessage({
type: "error",
content:
serverError?.message ??
"Failed to remove item. Please try again later or contact support.",
});
},
});
// Add actions for updating item quantity with messages
const { execute: executeActionUpdateItemsQuantity } = useCheckoutAction(
"UPDATE_ITEMS_QUANTITY", {
onSuccess() {
addMessage({
type: "success",
content: "Quantity updated successfully.",
});
},
onError({ serverError }) {
addMessage({
type: "error",
content:
serverError?.message ??
"Failed to update quantity. Please try again later or contact support.",
});
},
}
);
// Handler for quantity changes
const handleQuantityChange = async (index: number, newQuantity: number) => {
if (newQuantity <= 0) return;
executeActionUpdateItemsQuantity([
{ index, quantity: newQuantity },
]);
};
// Handler for removing an item
const handleRemoveItem = async (index: number) => {
executeActionRemoveItems([index]);
};
// Format price utility function
const formatPrice = (price: number) => {
return new Intl.NumberFormat(language, {
style: "currency",
currency: currency,
}).format(price / 100);
};
return (
<div className={styles.cartItem}>
{/* Product Image */}
<div className={styles.imageContainer}>
{item.image ? (
<img src={item.image} alt={item.name} className={styles.itemImage} />
) : (
<div className={styles.placeholderImage} />
)}
</div>
{/* Product Details */}
<div className={styles.itemDetails}>
<h3 className={styles.itemName}>{item.name}</h3>
{/* Price Display with Discount Logic */}
{hasDiscount ? (
<div className={styles.priceContainer}>
<p className={styles.originalPrice}>
{formatPrice(item.originalPrice)}
</p>
<p className={styles.itemPrice}>{formatPrice(item.price)}</p>
</div>
) : (
<p className={styles.itemPrice}>{formatPrice(item.price)}</p>
)}
</div>
{/* Quantity Controls */}
<div className={styles.itemActions}>
<div className={styles.quantityControl}>
<button
type="button"
className={styles.quantityButton}
onClick={() => handleQuantityChange(item.index, item.quantity - 1)}
disabled={item.quantity <= 1}
aria-label="Decrease quantity"
>
-
</button>
<span className={styles.quantity}>{item.quantity}</span>
<button
className={styles.quantityButton}
type="button"
onClick={() => handleQuantityChange(item.index, item.quantity + 1)}
aria-label="Increase quantity"
>
+
</button>
</div>
{/* Remove Button */}
<button
className={styles.removeButton}
type="button"
onClick={() => handleRemoveItem(item.index)}
aria-label="Remove item"
>
<span>Remove</span>
</button>
</div>
{/* Total Price */}
<b className={styles.itemTotal}>
{formatPrice(item.price * item.quantity)}
</b>
</div>
);
}