import React, { useMemo, useState } from 'react'; import type { FlyerItem, MasterGroceryItem, ShoppingList } from '../types'; import { formatUnitPrice } from '../utils/unitConverter'; import { Session } from '@supabase/supabase-js'; import { PlusCircleIcon } from './icons/PlusCircleIcon'; interface ExtractedDataTableProps { items: FlyerItem[]; totalActiveItems?: number; watchedItems?: MasterGroceryItem[]; masterItems: MasterGroceryItem[]; unitSystem: 'metric' | 'imperial'; session: Session | null; onAddItem: (itemName: string, category: string) => Promise; shoppingLists: ShoppingList[]; activeListId: number | null; onAddItemToList: (masterItemId: number) => void; } export const ExtractedDataTable: React.FC = ({ items, totalActiveItems, watchedItems = [], masterItems, unitSystem, session, onAddItem, shoppingLists, activeListId, onAddItemToList }) => { const [categoryFilter, setCategoryFilter] = useState('all'); const watchedItemIds = useMemo(() => new Set(watchedItems.map(item => item.id)), [watchedItems]); const masterItemsMap = useMemo(() => new Map(masterItems.map(item => [item.id, item.name])), [masterItems]); const activeShoppingListItems = useMemo(() => { if (!activeListId) return new Set(); const activeList = shoppingLists.find(list => list.id === activeListId); return new Set(activeList?.items.map(item => item.master_item_id)); }, [shoppingLists, activeListId]); const availableCategories = useMemo(() => { const cats = new Set(items.map(i => i.category_name).filter((c): c is string => !!c)); return Array.from(cats).sort(); }, [items]); const itemsWithCanonicalNames = useMemo(() => { return items.map(item => ({ ...item, resolved_canonical_name: item.master_item_id ? masterItemsMap.get(item.master_item_id) : null, })); }, [items, masterItemsMap]); const sortedItems = useMemo(() => { const filtered = categoryFilter === 'all' ? itemsWithCanonicalNames : itemsWithCanonicalNames.filter(item => item.category_name === categoryFilter); if (watchedItemIds.size === 0) { return filtered; } const watched = []; const others = []; for (const item of filtered) { const isWatched = item.master_item_id && watchedItemIds.has(item.master_item_id); if (isWatched) { watched.push(item); } else { others.push(item); } } return [...watched, ...others]; }, [itemsWithCanonicalNames, watchedItemIds, categoryFilter]); if (items.length === 0) { return (

No items extracted yet.

); } const title = (totalActiveItems && totalActiveItems > 0) ? `Item List (${items.length} in flyer / ${totalActiveItems} total active deals)` : `Item List (${items.length})`; return (

{title}

{availableCategories.length > 1 && ( )}
{sortedItems.length === 0 ? (
No items found for the selected category.
) : ( {sortedItems.map((item, index) => { const canonicalName = item.resolved_canonical_name; const isWatched = item.master_item_id && watchedItemIds.has(item.master_item_id); const isInList = !!(item.master_item_id && activeShoppingListItems.has(item.master_item_id)); const itemNameClass = isWatched ? 'text-sm font-bold text-green-600 dark:text-green-400' : 'text-sm font-semibold text-gray-900 dark:text-white'; const shouldShowCanonical = canonicalName && canonicalName.toLowerCase() !== item.item.toLowerCase(); const formattedUnitPrice = formatUnitPrice(item.unit_price, unitSystem); return ( ); })}
{item.item}
{session && canonicalName && !isInList && ( )} {session && !isWatched && canonicalName && ( )}
Price: {item.price_display}
Deal:
{item.quantity} {item.quantity_num && ({item.quantity_num})}
Unit Price:
{formattedUnitPrice.price} {formattedUnitPrice.unit && ( {formattedUnitPrice.unit} )}
Category: {item.category_name} {shouldShowCanonical && ( (Canonical: {canonicalName}) )}
)}
); };