chore: transfer repo
This commit is contained in:
161
components/cart/CartBoxItem.tsx
Normal file
161
components/cart/CartBoxItem.tsx
Normal file
@@ -0,0 +1,161 @@
|
||||
'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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user