import { memo, useRef, useState } from "react"; import AddImageModal from "../modals/AddImageModal"; import ConfirmBuyModal from "../modals/ConfirmBuyModal"; function GroceryListItem({ item, onClick, onImageAdded, onLongPress, allItems = [], compact = false }) { const [showAddImageModal, setShowAddImageModal] = useState(false); const [showConfirmBuyModal, setShowConfirmBuyModal] = useState(false); const [currentItem, setCurrentItem] = useState(item); const longPressTimer = useRef(null); const pressStartPos = useRef({ x: 0, y: 0 }); const handleTouchStart = (e) => { const touch = e.touches[0]; pressStartPos.current = { x: touch.clientX, y: touch.clientY }; longPressTimer.current = setTimeout(() => { if (onLongPress) { onLongPress(item); } }, 500); // 500ms for long press }; const handleTouchMove = (e) => { // Cancel long press if finger moves too much const touch = e.touches[0]; const moveDistance = Math.sqrt( Math.pow(touch.clientX - pressStartPos.current.x, 2) + Math.pow(touch.clientY - pressStartPos.current.y, 2) ); if (moveDistance > 10) { clearTimeout(longPressTimer.current); } }; const handleTouchEnd = () => { clearTimeout(longPressTimer.current); }; const handleMouseDown = () => { longPressTimer.current = setTimeout(() => { if (onLongPress) { onLongPress(item); } }, 500); }; const handleMouseUp = () => { clearTimeout(longPressTimer.current); }; const handleMouseLeave = () => { clearTimeout(longPressTimer.current); }; const handleItemClick = () => { if (onClick) { setCurrentItem(item); setShowConfirmBuyModal(true); } }; const handleConfirmBuy = (quantity) => { if (onClick) { onClick(currentItem.id, quantity); } setShowConfirmBuyModal(false); }; const handleCancelBuy = () => { setShowConfirmBuyModal(false); }; const handleNavigate = (newItem) => { setCurrentItem(newItem); }; const handleImageClick = (e) => { e.stopPropagation(); // Prevent triggering the bought action if (item.item_image) { // Open buy modal which now shows the image setCurrentItem(item); setShowConfirmBuyModal(true); } else { setShowAddImageModal(true); } }; const handleAddImage = async (imageFile) => { if (onImageAdded) { await onImageAdded(item.id, item.item_name, item.quantity, imageFile); } setShowAddImageModal(false); }; const imageUrl = item.item_image && item.image_mime_type ? `data:${item.image_mime_type};base64,${item.item_image}` : null; const addedByUsers = Array.isArray(item.added_by_users) ? item.added_by_users.filter( (name) => typeof name === "string" && name.trim().length > 0 ) : []; const getTimeAgo = (dateString) => { if (!dateString) return null; const addedDate = new Date(dateString); const now = new Date(); const diffMs = now - addedDate; const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); if (diffDays < 7) { return `${diffDays}d ago`; } else if (diffDays < 30) { const weeks = Math.floor(diffDays / 7); return `${weeks}w ago`; } else { const months = Math.floor(diffDays / 30); return `${months}m ago`; } }; return ( <>
  • {item.item_image ? ( {item.item_name} ) : ( 📦 )} x{item.quantity}
    {item.item_name}
    {addedByUsers.length > 0 && (
    {item.last_added_on && `${getTimeAgo(item.last_added_on)} -- `} {addedByUsers.join(" | ")}
    )}
  • {showAddImageModal && ( setShowAddImageModal(false)} onAddImage={handleAddImage} /> )} {showConfirmBuyModal && ( )} ); } // Memoize component to prevent re-renders when props haven't changed export default memo(GroceryListItem, (prevProps, nextProps) => { // Only re-render if the item data or handlers have changed return ( prevProps.item.id === nextProps.item.id && prevProps.item.item_name === nextProps.item.item_name && prevProps.item.quantity === nextProps.item.quantity && prevProps.item.item_image === nextProps.item.item_image && prevProps.item.bought === nextProps.item.bought && prevProps.item.last_added_on === nextProps.item.last_added_on && prevProps.item.zone === nextProps.item.zone && prevProps.item.added_by_users?.join(',') === nextProps.item.added_by_users?.join(',') && prevProps.onClick === nextProps.onClick && prevProps.onImageAdded === nextProps.onImageAdded && prevProps.onLongPress === nextProps.onLongPress && prevProps.allItems?.length === nextProps.allItems?.length ); });