161 lines
5.6 KiB
TypeScript
161 lines
5.6 KiB
TypeScript
'use client';
|
|
|
|
import { Button } from '@/components/ui/Button';
|
|
import { Heading } from '@/components/ui/Typography';
|
|
import { useTranslation } from '@/lib/hooks/useTranslation';
|
|
import { useAppDispatch } from '@/lib/redux/hooks';
|
|
import { loadBoxForEditing } from '@/lib/redux/slices/boxSlice';
|
|
import Price from 'components/price';
|
|
import { CartItem } from 'lib/shopify/types';
|
|
import { ChevronDown, ChevronUp, Pencil, Trash2 } from 'lucide-react';
|
|
import Image from 'next/image';
|
|
import { useRouter } from 'next/navigation';
|
|
import { useState } from 'react';
|
|
import { CartProductItem } from './CartProductItem';
|
|
import { getUniqueItemKey } from './processCartItems';
|
|
|
|
interface CartBoxItemProps {
|
|
boxItem: CartItem;
|
|
boxProducts: CartItem[];
|
|
onUpdate: (merchandiseId: string, updateType: 'plus' | 'minus' | 'delete', itemId?: string) => void;
|
|
isPending: boolean;
|
|
}
|
|
|
|
export function CartBoxItem({ boxItem, boxProducts, onUpdate, isPending }: CartBoxItemProps) {
|
|
const { t } = useTranslation();
|
|
const [isExpanded, setIsExpanded] = useState(true);
|
|
const router = useRouter();
|
|
const dispatch = useAppDispatch();
|
|
|
|
// Get box attributes if any
|
|
const boxGroupId = boxItem.attributes?.find(attr => attr.key === '_box_group_id')?.value || 'box';
|
|
|
|
// Handle box deletion - delete box and all products inside it
|
|
const handleBoxDelete = () => {
|
|
// First update localStorage to reflect the box deletion
|
|
try {
|
|
const boxStateString = localStorage.getItem('lastBoxState');
|
|
if (boxStateString) {
|
|
const boxState = JSON.parse(boxStateString);
|
|
|
|
// Check if this is the box that's currently saved for editing
|
|
if (boxState.originalBoxGroupId === boxGroupId) {
|
|
// Remove the box from localStorage
|
|
localStorage.removeItem('lastBoxState');
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Error updating box state in localStorage on delete', error);
|
|
}
|
|
|
|
// First delete the box container
|
|
onUpdate(boxItem.merchandise.id, 'delete', boxItem.id);
|
|
|
|
// Then delete all products inside the box
|
|
boxProducts.forEach(product => {
|
|
if (product.id) {
|
|
onUpdate(product.merchandise.id, 'delete', product.id);
|
|
}
|
|
});
|
|
};
|
|
|
|
// Handle box editing
|
|
const handleEditBox = () => {
|
|
// Prvo pokušaj direktno spremiti trenutni boxGroupId u lokalno stanje
|
|
try {
|
|
const currentBoxState = localStorage.getItem('lastBoxState');
|
|
let boxStateObject = currentBoxState ? JSON.parse(currentBoxState) : {};
|
|
|
|
// Dodaj originalni boxGroupId da kasnije znamo što trebamo obrisati
|
|
boxStateObject.originalBoxGroupId = boxGroupId;
|
|
localStorage.setItem('lastBoxState', JSON.stringify(boxStateObject));
|
|
} catch (error) {
|
|
console.error('Failed to save original box group ID', error);
|
|
}
|
|
|
|
// Attempt to load box state for editing from localStorage
|
|
dispatch(loadBoxForEditing());
|
|
|
|
// Redirect to build-box page
|
|
router.push('/build-box');
|
|
};
|
|
|
|
return (
|
|
<div className="mb-6 border-b border-gray-200">
|
|
{/* Box Header */}
|
|
<div className="flex items-center justify-between py-4">
|
|
<div className="flex items-center">
|
|
{/* Box Image */}
|
|
<div className="relative h-24 w-24 flex-shrink-0 overflow-hidden">
|
|
<Image
|
|
src={boxItem.merchandise.product.featuredImage?.url || ''}
|
|
alt={boxItem.merchandise.product.title}
|
|
fill
|
|
className="object-cover"
|
|
/>
|
|
</div>
|
|
|
|
{/* Box Details */}
|
|
<div className="pl-4">
|
|
<Heading level={4}>
|
|
{boxItem.merchandise.product.title}
|
|
</Heading>
|
|
<Price
|
|
amount={boxItem.cost.totalAmount.amount}
|
|
currencyCode={boxItem.cost.totalAmount.currencyCode}
|
|
className="text-sm mt-1 font-bold"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Box Actions */}
|
|
<div className="flex items-center gap-6">
|
|
<Button
|
|
onClick={handleBoxDelete}
|
|
variant="default"
|
|
className="p-0 h-auto border-0 bg-transparent hover:bg-transparent text-gray-500 hover:text-red-500"
|
|
disabled={isPending}
|
|
aria-label={t('cart.remove')}
|
|
>
|
|
<Trash2 size={20} />
|
|
</Button>
|
|
|
|
<Button
|
|
onClick={handleEditBox}
|
|
variant="default"
|
|
className="p-0 h-auto border-0 bg-transparent hover:bg-transparent text-gray-500 hover:text-gray-700"
|
|
aria-label={t('cart.editBox')}
|
|
>
|
|
<Pencil size={20} />
|
|
</Button>
|
|
|
|
<Button
|
|
onClick={() => setIsExpanded(!isExpanded)}
|
|
variant="default"
|
|
className="p-0 h-auto border-0 bg-transparent hover:bg-transparent text-gray-500 hover:text-gray-700"
|
|
aria-label={isExpanded ? t('cart.collapseBox') : t('cart.expandBox')}
|
|
>
|
|
{isExpanded ? <ChevronUp size={20} /> : <ChevronDown size={20} />}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Box Products */}
|
|
{isExpanded && boxProducts.length > 0 && (
|
|
<div className="space-y-4 py-2 pb-4">
|
|
<h4 className="text-sm font-medium text-gray-500 mb-2">{t('cart.customBoxContents')}</h4>
|
|
{boxProducts.map((item, index) => (
|
|
<CartProductItem
|
|
key={getUniqueItemKey(item, boxGroupId, index)}
|
|
item={item}
|
|
onUpdate={onUpdate}
|
|
isPending={isPending}
|
|
isInBox={true}
|
|
boxGroupId={boxGroupId}
|
|
/>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|