Files
sent-shop/components/build-box/AddBoxToCartClient.tsx
2026-01-19 20:21:14 +01:00

173 lines
5.9 KiB
TypeScript

'use client';
import { Button } from "@/components/ui/Button";
import { useAppDispatch, useAppSelector } from "@/lib/redux/hooks";
import { clearBox, selectBoxItems, selectEditingBoxGroupId } from "@/lib/redux/slices/boxSlice";
import { addItem, removeItem } from "components/cart/actions";
import { useCart } from "components/cart/cart-context";
import { Product, ProductVariant } from "lib/shopify/types";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
export function AddBoxToCartClient() {
const [isLoading, setIsLoading] = useState(false);
const [isLoadingProducts, setIsLoadingProducts] = useState(true);
const [allProducts, setAllProducts] = useState<Product[]>([]);
const [boxProducts, setBoxProducts] = useState<Product[]>([]);
const items = useAppSelector(selectBoxItems);
const editingBoxGroupId = useAppSelector(selectEditingBoxGroupId);
const { addCartItem, cart } = useCart();
const dispatch = useAppDispatch();
const router = useRouter();
// Fetch products on mount
useEffect(() => {
async function fetchProducts() {
setIsLoadingProducts(true);
try {
// Fetch regular products
const regularResponse = await fetch('/api/products');
const regularData = await regularResponse.json();
// Fetch box products
const boxesResponse = await fetch('/api/products?type=boxes');
const boxesData = await boxesResponse.json();
if (regularData.products) setAllProducts(regularData.products);
if (boxesData.products) setBoxProducts(boxesData.products);
} catch (error) {
console.error("Failed to fetch products:", error);
} finally {
setIsLoadingProducts(false);
}
}
fetchProducts();
}, []);
// Check if we have a box
const boxItems = items.filter(item => item.variantId === 'box-container');
const productItems = items.filter(item => item.variantId !== 'box-container');
const isEnabled = boxItems.length > 0 && !isLoadingProducts;
const handleAddToCart = async () => {
if (isLoading || !isEnabled) return;
setIsLoading(true);
try {
// Save the current box state to localStorage for potential editing later
try {
const boxState = {
boxItems: boxItems,
productItems: productItems,
boxGroupId: `box-${Date.now()}`
};
localStorage.setItem('lastBoxState', JSON.stringify(boxState));
} catch (error) {
console.error("Failed to save box state:", error);
}
// Generate a unique box ID to group all items together
const boxGroupId = `box-${Date.now()}`;
// Ako je ovo uređivanje postojećeg boxa, prvo ukloni stari box i sve njegove proizvode
if (editingBoxGroupId && cart) {
// Pronađi sve proizvode i kontejner koji pripadaju ovom boxu
const itemsToRemove = cart.lines.filter(line => {
const attrs = line.attributes || [];
const itemBoxGroupId = attrs.find(attr => attr.key === 'box_group_id')?.value;
return itemBoxGroupId === editingBoxGroupId;
});
// Ukloni sve pronađene proizvode
for (const item of itemsToRemove) {
if (item.id && item.merchandise.id) {
await removeItem(null, item.merchandise.id, item.id);
}
}
}
// Add box items first
for (const boxItem of boxItems) {
// Find the actual box product from our pre-loaded products
const boxProduct = boxProducts.find(p => p.id === boxItem.id);
if (boxProduct) {
// Get the variant to use
const boxVariant = boxProduct.variants[0];
if (boxVariant) {
// Add box with attribute marking it as a box container and the box group ID
await addItem(
null,
boxVariant.id,
boxItem.quantity,
[
{ key: "_box_type", value: "container" },
{ key: "_box_group_id", value: boxGroupId }
]
);
// Update local cart state
addCartItem(boxVariant, boxProduct, boxItem.quantity);
}
}
}
// Add product items
for (const productItem of productItems) {
// Find the actual product from our pre-loaded products
const product = allProducts.find(p => p.id === productItem.id);
if (product) {
// Find the variant
let selectedVariant: ProductVariant | undefined;
if (productItem.variantId && productItem.variantId !== 'undefined') {
selectedVariant = product.variants.find(v => v.id === productItem.variantId);
}
// If no variant found, use the first one (exactly like AddToCartButton.tsx)
if (!selectedVariant) {
selectedVariant = product.variants[0];
}
if (selectedVariant && selectedVariant.id) {
// Add product with attribute marking it as a box item and the box group ID
await addItem(
null,
selectedVariant.id,
productItem.quantity,
[
{ key: "_box_type", value: "item" },
{ key: "_box_group_id", value: boxGroupId }
]
);
// Update local cart state
addCartItem(selectedVariant, product, productItem.quantity);
}
}
}
dispatch(clearBox());
} catch (error) {
console.error("Failed to add box to cart:", error);
} finally {
setIsLoading(false);
}
};
return (
<Button
onClick={handleAddToCart}
disabled={isLoading || !isEnabled}
variant="primary"
className="w-full py-3"
>
{isLoading ? "Dodaje se..." : isLoadingProducts ? "Učitavanje..." : "Dodaj u košaricu"}
</Button>
);
}