product images added
This commit is contained in:
@@ -50,6 +50,7 @@ import {
|
||||
import { FIESTA_TENANT_ID, FIESTA_PRIMARY_LOCATION_ID, str as fstr } from '../services/fiestaApi';
|
||||
import { stockRowToProduct, stockRowToInventory } from '../services/fiestaMappers';
|
||||
import { useStoreCatalogue, usePriceEverywhere, isPublishedItem } from '../services/storeCatalogue';
|
||||
import { CardCarousel, ProductGallery } from './CatalogueGallery';
|
||||
import BulkCartDrawer from './BulkCartDrawer';
|
||||
import AwaitingApi from './AwaitingApi';
|
||||
import { SlideDrawer, Skeleton, TH_STYLE, SURFACE_ALT, TEXT, TEXT_2, TEXT_3, BORDER, BRAND, tint, edge, StatusChip } from './consoleUi';
|
||||
@@ -134,6 +135,21 @@ export default function InventoryView({
|
||||
const [hoveredAdminProduct, setHoveredAdminProduct] = useState<ProductMatrixItem | null>(null);
|
||||
const [localSearch, setLocalSearch] = useState('');
|
||||
const storeCat = useStoreCatalogue(tenantId, primaryLocationId);
|
||||
/**
|
||||
* productid → every photo, for the catalogue cards.
|
||||
*
|
||||
* Built once rather than searching storeCat.items inside each card's render:
|
||||
* the grid draws hundreds of cards and a linear scan per card is a scan per
|
||||
* card per keystroke in the search box.
|
||||
*/
|
||||
const imagesByProduct = useMemo(() => {
|
||||
const m = new Map<string, string[]>();
|
||||
storeCat.items.forEach((i) => {
|
||||
if (i.images?.length) m.set(i.productid, i.images);
|
||||
});
|
||||
return m;
|
||||
}, [storeCat.items]);
|
||||
|
||||
const { priceEverywhere, isPending: isPricing } = usePriceEverywhere(tenantId);
|
||||
const [importPrice, setImportPrice] = useState<string>('');
|
||||
const [isSettingPrice, setIsSettingPrice] = useState(false);
|
||||
@@ -589,11 +605,13 @@ export default function InventoryView({
|
||||
<div key={prod.id} onClick={() => setSelectedAdminProduct(prod)} className="bg-white/80 backdrop-blur-md border border-[#e2e8f0] rounded-none flex flex-col shadow-sm hover:shadow-[0_12px_24px_rgba(99,102,241,0.06)] hover:border-[#662582]/40 hover:-translate-y-1 transition-all duration-300 relative group overflow-hidden cursor-pointer">
|
||||
{/* Image Section - Top */}
|
||||
<div className="w-full h-48 bg-white p-4 relative overflow-hidden shrink-0 border-b border-slate-100 flex items-center justify-center">
|
||||
<img
|
||||
src={prod.image}
|
||||
alt={prod.name}
|
||||
referrerPolicy="no-referrer"
|
||||
className="w-full h-full object-contain mix-blend-multiply group-hover:scale-110 transition-transform duration-700 ease-in-out"
|
||||
{/* Every photo the product has. ProductMatrixItem
|
||||
carries one `image` and is built by two mappers,
|
||||
so the gallery is looked up by id — see
|
||||
imagesByProduct. */}
|
||||
<CardCarousel
|
||||
images={imagesByProduct.get(prod.id) ?? [prod.image]}
|
||||
alt={prod.name}
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-slate-900/60 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 pointer-events-none" />
|
||||
{prod.isSample && (
|
||||
@@ -906,10 +924,20 @@ export default function InventoryView({
|
||||
return (
|
||||
<div className="flex flex-col gap-8 pb-8">
|
||||
|
||||
{/* Clean Image Container */}
|
||||
<div className="w-full h-64 bg-white rounded-2xl border border-slate-200 overflow-hidden relative flex items-center justify-center p-4">
|
||||
<img src={selectedAdminProduct.image} alt={selectedAdminProduct.name} className="w-auto h-full max-w-full object-contain mix-blend-multiply" />
|
||||
</div>
|
||||
{/* Gallery. A product carries up to ten photos in the global
|
||||
catalogue and only the first was ever stored, so most rows still
|
||||
have one until the backfill runs — ProductGallery renders a
|
||||
plain image in that case rather than empty chrome. */}
|
||||
<ProductGallery
|
||||
// Resolved from the catalogue row rather than from
|
||||
// ProductMatrixItem, which carries a single `image` and is built
|
||||
// by two different mappers — teaching both about a gallery to
|
||||
// reach one drawer is more surface than this earns. Falls back to
|
||||
// that single image, which is all a product has until the
|
||||
// productimages backfill runs.
|
||||
images={imagesByProduct.get(selectedAdminProduct.id) ?? [selectedAdminProduct.image]}
|
||||
alt={selectedAdminProduct.name}
|
||||
/>
|
||||
|
||||
{/* Title & Basics */}
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user