@beyondcorp/beyond-ui 1.2.41 → 1.2.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,6 +9,7 @@ import { useMarketplaceState } from './hooks/useMarketplaceState.js';
9
9
  import { useCart } from './hooks/useCart.js';
10
10
  import { useProductNavigation } from './hooks/useProductNavigation.js';
11
11
  import { useSearch } from './hooks/useSearch.js';
12
+ import { sanitizeProduct } from './utils/sanitizeProduct.js';
12
13
 
13
14
  /**
14
15
  * Main marketplace component orchestrating all marketplace functionality
@@ -18,7 +19,10 @@ const MarketplaceComponent = ({ userRole = 'buyer', products, cartItems: cartIte
18
19
  // State management hook (fallbacks for backward compatibility)
19
20
  const { sidebarCollapsed, currentView, selectedProduct, searchQuery, cartItems: cartItemsState, showCheckout, filters: filtersState, setSidebarCollapsed, setCurrentView, setSelectedProduct, setSearchQuery, setCartItems, setShowCheckout, setFilters, toggleSidebar, clearCart, resetFilters, } = useMarketplaceState();
20
21
  // Use props if provided, otherwise fallback to internal state/sample data
21
- const productsData = products ?? require('./data/sampleData').sampleProducts;
22
+ const rawProductsData = products ?? require('./data/sampleData').sampleProducts;
23
+ const productsData = Array.isArray(rawProductsData)
24
+ ? rawProductsData.map(sanitizeProduct)
25
+ : [];
22
26
  const cartItems = cartItemsProp ?? cartItemsState;
23
27
  const filters = filtersProp ?? filtersState;
24
28
  // Cart management hook
@@ -53,7 +57,13 @@ const MarketplaceComponent = ({ userRole = 'buyer', products, cartItems: cartIte
53
57
  (onAddToCart ?? addToCart)(product, quantity);
54
58
  setShowCheckout(true);
55
59
  };
56
- return (jsxs("div", { className: `min-h-screen bg-gray-50 ${className}`, children: [jsx(MarketplaceHeader, { searchQuery: searchQuery, onSearchChange: handleSearch, cartItemCount: cartItemCount, onCartClick: handleCartClick, onMenuToggle: toggleSidebar, userRole: userRole }), jsxs("div", { className: "flex", children: [(currentView === 'products' || currentView === 'dashboard') && (jsx(MarketplaceSidebar, { filters: filters, onFiltersChange: onFiltersChange ?? setFilters, onClearFilters: onClearFilters ?? resetFilters, collapsed: sidebarCollapsed, onToggleCollapse: toggleSidebar })), jsxs("main", { className: "flex-1 p-6", children: [currentView === 'dashboard' && (jsx(MarketplaceDashboard, { featuredProducts: featuredProducts, trendingProducts: trendingProducts, recentlyViewed: recentlyViewed, onProductClick: navigateToProduct, onAddToCart: onAddToCart ?? addToCart, onViewAllProducts: navigateToProducts })), currentView === 'products' && (jsx(AllProductsView, { onProductClick: navigateToProduct, onAddToCart: onAddToCart ?? addToCart, products: productsData, filters: filters })), currentView === 'product' && selectedProduct && (jsx(SingleProductView, { product: productsData.find((p) => p.id === selectedProduct.id), onAddToCart: onAddToCart ?? addToCart, onBuyNow: handleBuyNow }))] }), showCheckout && (jsx("div", { className: "fixed right-4 top-20 z-50", children: jsx(CheckoutCompact, { cartItems: cartItems, onClose: () => setShowCheckout(false), onCheckout: handleCheckoutComplete }) }))] })] }));
60
+ return (jsxs("div", { className: `min-h-screen bg-gray-50 ${className}`, children: [jsx(MarketplaceHeader, { searchQuery: searchQuery, onSearchChange: handleSearch, cartItemCount: cartItemCount, onCartClick: handleCartClick, onMenuToggle: toggleSidebar, userRole: userRole }), jsxs("div", { className: "flex", children: [(currentView === 'products' || currentView === 'dashboard') && (jsx(MarketplaceSidebar, { filters: filters, onFiltersChange: onFiltersChange ?? setFilters, onClearFilters: onClearFilters ?? resetFilters, collapsed: sidebarCollapsed, onToggleCollapse: toggleSidebar })), jsxs("main", { className: "flex-1 p-6", children: [currentView === 'dashboard' && (jsx(MarketplaceDashboard, { featuredProducts: featuredProducts, trendingProducts: trendingProducts, recentlyViewed: recentlyViewed, onProductClick: navigateToProduct, onAddToCart: onAddToCart ?? addToCart, onViewAllProducts: navigateToProducts })), currentView === 'products' && (jsx(AllProductsView, { onProductClick: navigateToProduct, onAddToCart: onAddToCart ?? addToCart, products: productsData, filters: filters })), currentView === 'product' && selectedProduct && (jsx(SingleProductView, { product: (() => {
61
+ const found = productsData.find((p) => String(p.id).trim() === String(selectedProduct.id).trim());
62
+ if (!found) {
63
+ console.error("MarketplaceComponent: No product found for selectedProduct.id:", selectedProduct.id, "Available ids:", productsData.map((p) => p.id));
64
+ }
65
+ return found;
66
+ })(), onAddToCart: onAddToCart ?? addToCart, onBuyNow: handleBuyNow }))] }), showCheckout && (jsx("div", { className: "fixed right-4 top-20 z-50", children: jsx(CheckoutCompact, { cartItems: cartItems, onClose: () => setShowCheckout(false), onCheckout: handleCheckoutComplete }) }))] })] }));
57
67
  };
58
68
 
59
69
  export { MarketplaceComponent };
@@ -1 +1 @@
1
- {"version":3,"file":"MarketplaceComponent.js","sources":["../../../src/components/Marketplace/MarketplaceComponent.tsx"],"sourcesContent":["import React from 'react';\nimport { sampleProducts } from './data/sampleData';\nimport { MarketplaceHeader } from './components/MarketplaceHeader';\nimport { MarketplaceDashboard } from './components/MarketplaceDashboard';\nimport { MarketplaceSidebar } from './MarketplaceSidebar';\nimport { AllProductsView } from './AllProductsView';\nimport { SingleProductView } from './SingleProductView';\nimport { CheckoutCompact } from './CheckoutCompact';\nimport { useMarketplaceState } from './hooks/useMarketplaceState';\nimport { useCart } from './hooks/useCart';\nimport { useProductNavigation } from './hooks/useProductNavigation';\nimport { useSearch } from './hooks/useSearch';\nimport type { Product, CartItem, FilterOptions } from './types';\n\nexport interface MarketplaceComponentProps {\n userRole?: 'buyer' | 'seller' | 'admin';\n products?: Product[];\n cartItems?: CartItem[];\n filters?: FilterOptions;\n onProductClick?: (product: Product) => void;\n onAddToCart?: (product: Product, quantity?: number) => void;\n onRemoveFromCart?: (productId: string) => void;\n onFiltersChange?: (filters: FilterOptions) => void;\n onClearFilters?: () => void;\n className?: string;\n}\n\n/**\n * Main marketplace component orchestrating all marketplace functionality\n * Refactored to use modular components and custom hooks for better maintainability\n */\nexport const MarketplaceComponent: React.FC<MarketplaceComponentProps> = ({\n userRole = 'buyer',\n products,\n cartItems: cartItemsProp,\n filters: filtersProp,\n onProductClick,\n onAddToCart,\n onRemoveFromCart,\n onFiltersChange,\n onClearFilters,\n className = '',\n}) => {\n // State management hook (fallbacks for backward compatibility)\n const {\n sidebarCollapsed,\n currentView,\n selectedProduct,\n searchQuery,\n cartItems: cartItemsState,\n showCheckout,\n filters: filtersState,\n setSidebarCollapsed,\n setCurrentView,\n setSelectedProduct,\n setSearchQuery,\n setCartItems,\n setShowCheckout,\n setFilters,\n toggleSidebar,\n clearCart,\n resetFilters,\n } = useMarketplaceState();\n\n // Use props if provided, otherwise fallback to internal state/sample data\n const productsData = products ?? require('./data/sampleData').sampleProducts;\n const cartItems = cartItemsProp ?? cartItemsState;\n const filters = filtersProp ?? filtersState;\n\n // Cart management hook\n const {\n addToCart,\n removeFromCart,\n updateQuantity,\n getCartTotal,\n getCartItemCount,\n isInCart,\n getCartItem,\n } = useCart({ cartItems, setCartItems });\n\n // Navigation hook\n const {\n navigateToProduct,\n navigateToProducts,\n navigateToDashboard,\n navigateToCheckout,\n } = useProductNavigation({\n setSelectedProduct,\n setCurrentView,\n onProductClick,\n });\n\n // Search hook\n const {\n searchResults,\n isSearching,\n handleSearch,\n clearSearch,\n } = useSearch({\n products: productsData,\n searchQuery,\n setSearchQuery,\n setCurrentView,\n });\n\n // Derived data\n const featuredProducts = productsData.slice(0, 4);\n const trendingProducts = productsData.slice(4, 8);\n const recentlyViewed = productsData.slice(8, 12);\n const cartItemCount = getCartItemCount();\n\n // Event handlers\n const handleCartClick = () => {\n setShowCheckout(!showCheckout);\n };\n\n const handleCheckoutComplete = (items: any[]) => {\n clearCart();\n setShowCheckout(false);\n };\n\n const handleBuyNow = (product: Product, quantity: number) => {\n (onAddToCart ?? addToCart)(product, quantity);\n setShowCheckout(true);\n };\n\n return (\n <div className={`min-h-screen bg-gray-50 ${className}`}>\n {/* Header */}\n <MarketplaceHeader\n searchQuery={searchQuery}\n onSearchChange={handleSearch}\n cartItemCount={cartItemCount}\n onCartClick={handleCartClick}\n onMenuToggle={toggleSidebar}\n userRole={userRole}\n />\n\n <div className=\"flex\">\n {/* Sidebar */}\n {(currentView === 'products' || currentView === 'dashboard') && (\n <MarketplaceSidebar\n filters={filters}\n onFiltersChange={onFiltersChange ?? setFilters}\n onClearFilters={onClearFilters ?? resetFilters}\n collapsed={sidebarCollapsed}\n onToggleCollapse={toggleSidebar}\n />\n )}\n\n {/* Main Content */}\n <main className=\"flex-1 p-6\">\n {currentView === 'dashboard' && (\n <MarketplaceDashboard\n featuredProducts={featuredProducts}\n trendingProducts={trendingProducts}\n recentlyViewed={recentlyViewed}\n onProductClick={navigateToProduct}\n onAddToCart={onAddToCart ?? addToCart}\n onViewAllProducts={navigateToProducts}\n />\n )}\n \n {currentView === 'products' && (\n <AllProductsView\n onProductClick={navigateToProduct}\n onAddToCart={onAddToCart ?? addToCart}\n products={productsData}\n filters={filters}\n />\n )}\n \n {currentView === 'product' && selectedProduct && (\n <SingleProductView\n product={productsData.find((p: Product) => p.id === selectedProduct.id)}\n onAddToCart={onAddToCart ?? addToCart}\n onBuyNow={handleBuyNow}\n />\n )}\n </main>\n\n {/* Checkout Sidebar */}\n {showCheckout && (\n <div className=\"fixed right-4 top-20 z-50\">\n <CheckoutCompact\n cartItems={cartItems}\n onClose={() => setShowCheckout(false)}\n onCheckout={handleCheckoutComplete}\n />\n </div>\n )}\n </div>\n </div>\n );\n};"],"names":["_jsxs","_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"MarketplaceComponent.js","sources":["../../../src/components/Marketplace/MarketplaceComponent.tsx"],"sourcesContent":["import React from 'react';\nimport { sampleProducts } from './data/sampleData';\nimport { MarketplaceHeader } from './components/MarketplaceHeader';\nimport { MarketplaceDashboard } from './components/MarketplaceDashboard';\nimport { MarketplaceSidebar } from './MarketplaceSidebar';\nimport { AllProductsView } from './AllProductsView';\nimport { SingleProductView } from './SingleProductView';\nimport { CheckoutCompact } from './CheckoutCompact';\nimport { useMarketplaceState } from './hooks/useMarketplaceState';\nimport { useCart } from './hooks/useCart';\nimport { useProductNavigation } from './hooks/useProductNavigation';\nimport { useSearch } from './hooks/useSearch';\nimport type { Product, CartItem, FilterOptions } from './types';\nimport { sanitizeProduct } from \"./utils/sanitizeProduct\";\n\n\nexport interface MarketplaceComponentProps {\n userRole?: 'buyer' | 'seller' | 'admin';\n products?: Product[];\n cartItems?: CartItem[];\n filters?: FilterOptions;\n onProductClick?: (product: Product) => void;\n onAddToCart?: (product: Product, quantity?: number) => void;\n onRemoveFromCart?: (productId: string) => void;\n onFiltersChange?: (filters: FilterOptions) => void;\n onClearFilters?: () => void;\n className?: string;\n}\n\n/**\n * Main marketplace component orchestrating all marketplace functionality\n * Refactored to use modular components and custom hooks for better maintainability\n */\nexport const MarketplaceComponent: React.FC<MarketplaceComponentProps> = ({\n userRole = 'buyer',\n products,\n cartItems: cartItemsProp,\n filters: filtersProp,\n onProductClick,\n onAddToCart,\n onRemoveFromCart,\n onFiltersChange,\n onClearFilters,\n className = '',\n}) => {\n // State management hook (fallbacks for backward compatibility)\n const {\n sidebarCollapsed,\n currentView,\n selectedProduct,\n searchQuery,\n cartItems: cartItemsState,\n showCheckout,\n filters: filtersState,\n setSidebarCollapsed,\n setCurrentView,\n setSelectedProduct,\n setSearchQuery,\n setCartItems,\n setShowCheckout,\n setFilters,\n toggleSidebar,\n clearCart,\n resetFilters,\n } = useMarketplaceState();\n\n // Use props if provided, otherwise fallback to internal state/sample data\n \n const rawProductsData: Product[] = products ?? require('./data/sampleData').sampleProducts;\n const productsData: Product[] = Array.isArray(rawProductsData)\n ? rawProductsData.map(sanitizeProduct)\n : [];\n const cartItems = cartItemsProp ?? cartItemsState;\n const filters = filtersProp ?? filtersState;\n\n // Cart management hook\n const {\n addToCart,\n removeFromCart,\n updateQuantity,\n getCartTotal,\n getCartItemCount,\n isInCart,\n getCartItem,\n } = useCart({ cartItems, setCartItems });\n\n // Navigation hook\n const {\n navigateToProduct,\n navigateToProducts,\n navigateToDashboard,\n navigateToCheckout,\n } = useProductNavigation({\n setSelectedProduct,\n setCurrentView,\n onProductClick,\n });\n\n // Search hook\n const {\n searchResults,\n isSearching,\n handleSearch,\n clearSearch,\n } = useSearch({\n products: productsData,\n searchQuery,\n setSearchQuery,\n setCurrentView,\n });\n\n // Derived data\n const featuredProducts = productsData.slice(0, 4);\n const trendingProducts = productsData.slice(4, 8);\n const recentlyViewed = productsData.slice(8, 12);\n const cartItemCount = getCartItemCount();\n\n // Event handlers\n const handleCartClick = () => {\n setShowCheckout(!showCheckout);\n };\n\n const handleCheckoutComplete = (items: any[]) => {\n clearCart();\n setShowCheckout(false);\n };\n\n const handleBuyNow = (product: Product, quantity: number) => {\n (onAddToCart ?? addToCart)(product, quantity);\n setShowCheckout(true);\n };\n\n return (\n <div className={`min-h-screen bg-gray-50 ${className}`}>\n {/* Header */}\n <MarketplaceHeader\n searchQuery={searchQuery}\n onSearchChange={handleSearch}\n cartItemCount={cartItemCount}\n onCartClick={handleCartClick}\n onMenuToggle={toggleSidebar}\n userRole={userRole}\n />\n\n <div className=\"flex\">\n {/* Sidebar */}\n {(currentView === 'products' || currentView === 'dashboard') && (\n <MarketplaceSidebar\n filters={filters}\n onFiltersChange={onFiltersChange ?? setFilters}\n onClearFilters={onClearFilters ?? resetFilters}\n collapsed={sidebarCollapsed}\n onToggleCollapse={toggleSidebar}\n />\n )}\n\n {/* Main Content */}\n <main className=\"flex-1 p-6\">\n {currentView === 'dashboard' && (\n <MarketplaceDashboard\n featuredProducts={featuredProducts}\n trendingProducts={trendingProducts}\n recentlyViewed={recentlyViewed}\n onProductClick={navigateToProduct}\n onAddToCart={onAddToCart ?? addToCart}\n onViewAllProducts={navigateToProducts}\n />\n )}\n \n {currentView === 'products' && (\n <AllProductsView\n onProductClick={navigateToProduct}\n onAddToCart={onAddToCart ?? addToCart}\n products={productsData}\n filters={filters}\n />\n )}\n \n {currentView === 'product' && selectedProduct && (\n <SingleProductView\n product={\n (() => {\n const found = productsData.find((p: Product) => String(p.id).trim() === String(selectedProduct.id).trim());\n if (!found) {\n console.error(\n \"MarketplaceComponent: No product found for selectedProduct.id:\",\n selectedProduct.id,\n \"Available ids:\",\n productsData.map((p: Product) => p.id)\n );\n }\n return found;\n })()\n }\n onAddToCart={onAddToCart ?? addToCart}\n onBuyNow={handleBuyNow}\n />\n )}\n </main>\n\n {/* Checkout Sidebar */}\n {showCheckout && (\n <div className=\"fixed right-4 top-20 z-50\">\n <CheckoutCompact\n cartItems={cartItems}\n onClose={() => setShowCheckout(false)}\n onCheckout={handleCheckoutComplete}\n />\n </div>\n )}\n </div>\n </div>\n );\n};"],"names":["_jsxs","_jsx"],"mappings":"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"}
@@ -20,6 +20,16 @@ const SingleProductView = ({ product, reviews, relatedProducts, onAddToCart, onB
20
20
  const productData = product ?? productsData[0];
21
21
  const reviewsList = reviews ?? reviewsData;
22
22
  const relatedProductsList = relatedProducts ?? productsData.slice(1, 5);
23
+ // Defensive guards and fallbacks
24
+ const images = Array.isArray(productData.images) && productData.images.length > 0
25
+ ? productData.images
26
+ : ["/images/placeholder-product.png"];
27
+ const specifications = productData.specifications && Object.keys(productData.specifications).length > 0
28
+ ? productData.specifications
29
+ : { "Info": "No specifications available" };
30
+ const vendor = productData.vendor && productData.vendor.name
31
+ ? productData.vendor
32
+ : { name: "Unknown Vendor", rating: 0, logo: undefined };
23
33
  const [selectedImageIndex, setSelectedImageIndex] = useState(0);
24
34
  const [quantity, setQuantity] = useState(1);
25
35
  const [isWishlisted, setIsWishlisted] = useState(false);
@@ -42,15 +52,17 @@ const SingleProductView = ({ product, reviews, relatedProducts, onAddToCart, onB
42
52
  const prevImage = () => {
43
53
  setSelectedImageIndex((prev) => prev === 0 ? productData.images.length - 1 : prev - 1);
44
54
  };
45
- return (jsxs("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8", children: [jsxs("nav", { className: "flex items-center space-x-2 text-sm text-gray-600 mb-8", children: [jsx("a", { href: "/", className: "hover:text-primary-600", children: "Home" }), jsx("span", { children: "/" }), jsx("a", { href: "/products", className: "hover:text-primary-600", children: "Products" }), jsx("span", { children: "/" }), jsx("a", { href: `/category/${productData.category.toLowerCase()}`, className: "hover:text-primary-600", children: productData.category }), jsx("span", { children: "/" }), jsx("span", { className: "text-gray-900", children: productData.name })] }), jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-12", children: [jsxs("div", { children: [jsxs("div", { className: "relative aspect-square bg-gray-100 rounded-lg overflow-hidden mb-4", children: [jsx("img", { src: productData.images[selectedImageIndex], alt: productData.name, className: "w-full h-full object-cover" }), productData.images.length > 1 && (jsxs(Fragment, { children: [jsx("button", { onClick: prevImage, className: "absolute left-4 top-1/2 transform -translate-y-1/2 bg-white/80 hover:bg-white rounded-full p-2 shadow-lg transition-colors", children: jsx(ChevronLeft, { className: "h-5 w-5" }) }), jsx("button", { onClick: nextImage, className: "absolute right-4 top-1/2 transform -translate-y-1/2 bg-white/80 hover:bg-white rounded-full p-2 shadow-lg transition-colors", children: jsx(ChevronRight, { className: "h-5 w-5" }) })] })), productData.discount && (jsxs(Badge, { variant: "danger", className: "absolute top-4 left-4", children: ["-", productData.discount, "%"] }))] }), productData.images.length > 1 && (jsx("div", { className: "flex space-x-2 overflow-x-auto", children: productData.images.map((image, index) => (jsx("button", { onClick: () => setSelectedImageIndex(index), className: `flex-shrink-0 w-20 h-20 rounded-lg overflow-hidden border-2 transition-colors ${selectedImageIndex === index
55
+ return (jsxs("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8", children: [jsxs("nav", { className: "flex items-center space-x-2 text-sm text-gray-600 mb-8", children: [jsx("a", { href: "/", className: "hover:text-primary-600", children: "Home" }), jsx("span", { children: "/" }), jsx("a", { href: "/products", className: "hover:text-primary-600", children: "Products" }), jsx("span", { children: "/" }), jsx("a", { href: `/category/${productData.category.toLowerCase()}`, className: "hover:text-primary-600", children: productData.category }), jsx("span", { children: "/" }), jsx("span", { className: "text-gray-900", children: productData.name })] }), jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-12", children: [jsxs("div", { children: [jsxs("div", { className: "relative aspect-square bg-gray-100 rounded-lg overflow-hidden mb-4", children: [jsx("img", { src: images[selectedImageIndex] ?? "/images/placeholder-product.png", alt: productData.name, className: "w-full h-full object-cover" }), images.length > 1 && (jsxs(Fragment, { children: [jsx("button", { onClick: prevImage, className: "absolute left-4 top-1/2 transform -translate-y-1/2 bg-white/80 hover:bg-white rounded-full p-2 shadow-lg transition-colors", children: jsx(ChevronLeft, { className: "h-5 w-5" }) }), jsx("button", { onClick: nextImage, className: "absolute right-4 top-1/2 transform -translate-y-1/2 bg-white/80 hover:bg-white rounded-full p-2 shadow-lg transition-colors", children: jsx(ChevronRight, { className: "h-5 w-5" }) })] })), productData.discount && (jsxs(Badge, { variant: "danger", className: "absolute top-4 left-4", children: ["-", productData.discount, "%"] }))] }), images.length > 1 && (jsx("div", { className: "flex space-x-2 overflow-x-auto", children: images.map((image, index) => (jsx("button", { onClick: () => setSelectedImageIndex(index), className: `flex-shrink-0 w-20 h-20 rounded-lg overflow-hidden border-2 transition-colors ${selectedImageIndex === index
46
56
  ? 'border-primary-500'
47
- : 'border-gray-200 hover:border-gray-300'}`, children: jsx("img", { src: image, alt: `${productData.name} ${index + 1}`, className: "w-full h-full object-cover" }) }, index))) }))] }), jsxs("div", { children: [jsxs("div", { className: "flex items-center space-x-2 mb-4", children: [jsx("span", { className: "text-sm text-gray-600", children: "Sold by" }), jsxs("div", { className: "flex items-center space-x-2", children: [productData.vendor.logo && (jsxs(Avatar, { size: "sm", children: [jsx(AvatarImage, { src: productData.vendor.logo }), jsx(AvatarFallback, { children: productData.vendor.name[0] })] })), jsx("span", { className: "font-medium text-primary-600", children: productData.vendor.name }), jsxs("div", { className: "flex items-center space-x-1", children: [jsx(Star, { className: "h-4 w-4 text-yellow-400 fill-current" }), jsx("span", { className: "text-sm text-gray-600", children: productData.vendor.rating })] })] })] }), jsx("h1", { className: "text-3xl font-bold text-gray-900 mb-4", children: productData.name }), jsxs("div", { className: "flex items-center space-x-4 mb-6", children: [jsxs("div", { className: "flex items-center space-x-1", children: [[1, 2, 3, 4, 5].map((star) => (jsx(Star, { className: `h-5 w-5 ${star <= Math.floor(productData.rating)
57
+ : 'border-gray-200 hover:border-gray-300'}`, children: jsx("img", { src: image, alt: `${productData.name} ${index + 1}`, className: "w-full h-full object-cover" }) }, index))) }))] }), jsxs("div", { children: [jsxs("div", { className: "flex items-center space-x-2 mb-4", children: [jsx("span", { className: "text-sm text-gray-600", children: "Sold by" }), jsxs("div", { className: "flex items-center space-x-2", children: [vendor.logo ? (jsxs(Avatar, { size: "sm", children: [jsx(AvatarImage, { src: vendor.logo }), jsx(AvatarFallback, { children: vendor.name[0] })] })) : (jsx(Avatar, { size: "sm", children: jsx(AvatarFallback, { children: vendor.name[0] }) })), jsx("span", { className: "font-medium text-primary-600", children: vendor.name }), jsxs("div", { className: "flex items-center space-x-1", children: [jsx(Star, { className: "h-4 w-4 text-yellow-400 fill-current" }), jsx("span", { className: "text-sm text-gray-600", children: vendor.rating })] })] })] }), jsx("h1", { className: "text-3xl font-bold text-gray-900 mb-4", children: productData.name }), jsxs("div", { className: "flex items-center space-x-4 mb-6", children: [jsxs("div", { className: "flex items-center space-x-1", children: [[1, 2, 3, 4, 5].map((star) => (jsx(Star, { className: `h-5 w-5 ${star <= Math.floor(productData.rating)
48
58
  ? 'text-yellow-400 fill-current'
49
- : 'text-gray-300'}` }, star))), jsx("span", { className: "text-lg font-medium text-gray-900 ml-2", children: productData.rating })] }), jsxs("span", { className: "text-gray-600", children: ["(", productData.reviewCount, " reviews)"] }), jsx(Badge, { variant: productData.inStock ? 'success' : 'danger', children: productData.inStock ? 'In Stock' : 'Out of Stock' })] }), jsx("div", { className: "mb-6", children: jsxs("div", { className: "flex items-center space-x-3", children: [jsxs("span", { className: "text-3xl font-bold text-gray-900", children: ["$", productData.price.toFixed(2)] }), productData.originalPrice && (jsxs("span", { className: "text-xl text-gray-500 line-through", children: ["$", productData.originalPrice.toFixed(2)] })), productData.discount && (jsxs(Badge, { variant: "danger", children: ["Save ", productData.discount, "%"] }))] }) }), jsx("p", { className: "text-gray-600 mb-6 leading-relaxed", children: productData.description }), jsxs("div", { className: "space-y-4 mb-8", children: [jsxs("div", { className: "flex items-center space-x-4", children: [jsx("span", { className: "font-medium text-gray-900", children: "Quantity:" }), jsxs("div", { className: "flex items-center border border-gray-300 rounded-lg", children: [jsx("button", { onClick: () => setQuantity(Math.max(1, quantity - 1)), className: "p-2 hover:bg-gray-50 transition-colors", disabled: quantity <= 1, children: jsx(Minus, { className: "h-4 w-4" }) }), jsx(Input, { type: "number", value: quantity, onChange: (e) => setQuantity(Math.max(1, parseInt(e.target.value) || 1)), className: "w-16 text-center border-0 focus:ring-0", min: "1" }), jsx("button", { onClick: () => setQuantity(quantity + 1), className: "p-2 hover:bg-gray-50 transition-colors", children: jsx(Plus, { className: "h-4 w-4" }) })] })] }), jsxs("div", { className: "flex space-x-4", children: [jsxs(Button, { variant: "primary", size: "lg", onClick: handleAddToCart, disabled: !productData.inStock, className: "flex-1", children: [jsx(ShoppingCart, { className: "mr-2 h-5 w-5" }), "Add to Cart"] }), jsxs(Button, { variant: "secondary", size: "lg", onClick: handleBuyNow, disabled: !productData.inStock, className: "flex-1", children: [jsx(Zap, { className: "mr-2 h-5 w-5" }), "Buy Now"] })] }), jsxs("div", { className: "flex space-x-2", children: [jsxs(Button, { variant: "outline", onClick: () => setIsWishlisted(!isWishlisted), className: "flex-1", children: [jsx(Heart, { className: `mr-2 h-5 w-5 ${isWishlisted ? 'fill-current text-red-500' : ''}` }), isWishlisted ? 'Wishlisted' : 'Add to Wishlist'] }), jsx(Button, { variant: "outline", onClick: handleShare, children: jsx(Share2, { className: "h-5 w-5" }) })] })] }), jsxs("div", { className: "grid grid-cols-2 gap-4 mb-8", children: [jsxs("div", { className: "flex items-center space-x-2 text-sm text-gray-600", children: [jsx(Truck, { className: "h-4 w-4 text-green-600" }), jsx("span", { children: "Free shipping" })] }), jsxs("div", { className: "flex items-center space-x-2 text-sm text-gray-600", children: [jsx(RotateCcw, { className: "h-4 w-4 text-blue-600" }), jsx("span", { children: "30-day returns" })] }), jsxs("div", { className: "flex items-center space-x-2 text-sm text-gray-600", children: [jsx(Shield, { className: "h-4 w-4 text-purple-600" }), jsx("span", { children: "2-year warranty" })] }), jsxs("div", { className: "flex items-center space-x-2 text-sm text-gray-600", children: [jsx(Check, { className: "h-4 w-4 text-green-600" }), jsx("span", { children: "Authentic product" })] })] })] })] }), jsx("div", { className: "mt-16", children: jsxs(Tabs, { value: selectedTab, onValueChange: setSelectedTab, children: [jsxs(TabsList, { children: [jsx(TabsTrigger, { value: "description", children: "Description" }), jsx(TabsTrigger, { value: "specifications", children: "Specifications" }), jsxs(TabsTrigger, { value: "reviews", children: ["Reviews (", reviewsList.length, ")"] })] }), jsx(TabsContent, { value: "description", className: "mt-8", children: jsx(Card, { children: jsxs(CardContent, { className: "p-8", children: [jsx("h3", { className: "text-xl font-semibold mb-4", children: "Product Description" }), jsxs("div", { className: "prose max-w-none", children: [jsx("p", { className: "text-gray-600 leading-relaxed mb-4", children: productData.description }), jsx("p", { className: "text-gray-600 leading-relaxed", children: "This premium product offers exceptional quality and performance, designed to meet the highest standards. With advanced features and reliable construction, it's perfect for both professional and personal use." })] })] }) }) }), jsx(TabsContent, { value: "specifications", className: "mt-8", children: jsx(Card, { children: jsxs(CardContent, { className: "p-8", children: [jsx("h3", { className: "text-xl font-semibold mb-4", children: "Technical Specifications" }), jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: Object.entries(productData.specifications).map(([key, value]) => (jsxs("div", { className: "flex justify-between py-2 border-b border-gray-100", children: [jsxs("span", { className: "font-medium text-gray-900", children: [key, ":"] }), jsx("span", { className: "text-gray-600", children: String(value) })] }, key))) })] }) }) }), jsx(TabsContent, { value: "reviews", className: "mt-8", children: jsxs("div", { className: "space-y-6", children: [jsx(Card, { children: jsx(CardContent, { className: "p-8", children: jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-8", children: [jsxs("div", { children: [jsx("h3", { className: "text-xl font-semibold mb-4", children: "Customer Reviews" }), jsxs("div", { className: "flex items-center space-x-4 mb-4", children: [jsx("span", { className: "text-4xl font-bold text-gray-900", children: productData.rating }), jsxs("div", { children: [jsx("div", { className: "flex items-center space-x-1 mb-1", children: [1, 2, 3, 4, 5].map((star) => (jsx(Star, { className: `h-5 w-5 ${star <= Math.floor(productData.rating)
59
+ : 'text-gray-300'}` }, star))), jsx("span", { className: "text-lg font-medium text-gray-900 ml-2", children: productData.rating })] }), jsxs("span", { className: "text-gray-600", children: ["(", productData.reviewCount, " reviews)"] }), jsx(Badge, { variant: productData.inStock ? 'success' : 'danger', children: productData.inStock ? 'In Stock' : 'Out of Stock' })] }), jsx("div", { className: "mb-6", children: jsxs("div", { className: "flex items-center space-x-3", children: [jsxs("span", { className: "text-3xl font-bold text-gray-900", children: ["$", productData.price.toFixed(2)] }), productData.originalPrice && (jsxs("span", { className: "text-xl text-gray-500 line-through", children: ["$", productData.originalPrice.toFixed(2)] })), productData.discount && (jsxs(Badge, { variant: "danger", children: ["Save ", productData.discount, "%"] }))] }) }), jsx("p", { className: "text-gray-600 mb-6 leading-relaxed", children: productData.description }), jsxs("div", { className: "space-y-4 mb-8", children: [jsxs("div", { className: "flex items-center space-x-4", children: [jsx("span", { className: "font-medium text-gray-900", children: "Quantity:" }), jsxs("div", { className: "flex items-center border border-gray-300 rounded-lg", children: [jsx("button", { onClick: () => setQuantity(Math.max(1, quantity - 1)), className: "p-2 hover:bg-gray-50 transition-colors", disabled: quantity <= 1, children: jsx(Minus, { className: "h-4 w-4" }) }), jsx(Input, { type: "number", value: quantity, onChange: (e) => setQuantity(Math.max(1, parseInt(e.target.value) || 1)), className: "w-16 text-center border-0 focus:ring-0", min: "1" }), jsx("button", { onClick: () => setQuantity(quantity + 1), className: "p-2 hover:bg-gray-50 transition-colors", children: jsx(Plus, { className: "h-4 w-4" }) })] })] }), jsxs("div", { className: "flex space-x-4", children: [jsxs(Button, { variant: "primary", size: "lg", onClick: handleAddToCart, disabled: !productData.inStock, className: "flex-1", children: [jsx(ShoppingCart, { className: "mr-2 h-5 w-5" }), "Add to Cart"] }), jsxs(Button, { variant: "secondary", size: "lg", onClick: handleBuyNow, disabled: !productData.inStock, className: "flex-1", children: [jsx(Zap, { className: "mr-2 h-5 w-5" }), "Buy Now"] })] }), jsxs("div", { className: "flex space-x-2", children: [jsxs(Button, { variant: "outline", onClick: () => setIsWishlisted(!isWishlisted), className: "flex-1", children: [jsx(Heart, { className: `mr-2 h-5 w-5 ${isWishlisted ? 'fill-current text-red-500' : ''}` }), isWishlisted ? 'Wishlisted' : 'Add to Wishlist'] }), jsx(Button, { variant: "outline", onClick: handleShare, children: jsx(Share2, { className: "h-5 w-5" }) })] })] }), jsxs("div", { className: "grid grid-cols-2 gap-4 mb-8", children: [jsxs("div", { className: "flex items-center space-x-2 text-sm text-gray-600", children: [jsx(Truck, { className: "h-4 w-4 text-green-600" }), jsx("span", { children: "Free shipping" })] }), jsxs("div", { className: "flex items-center space-x-2 text-sm text-gray-600", children: [jsx(RotateCcw, { className: "h-4 w-4 text-blue-600" }), jsx("span", { children: "30-day returns" })] }), jsxs("div", { className: "flex items-center space-x-2 text-sm text-gray-600", children: [jsx(Shield, { className: "h-4 w-4 text-purple-600" }), jsx("span", { children: "2-year warranty" })] }), jsxs("div", { className: "flex items-center space-x-2 text-sm text-gray-600", children: [jsx(Check, { className: "h-4 w-4 text-green-600" }), jsx("span", { children: "Authentic product" })] })] })] })] }), jsx("div", { className: "mt-16", children: jsxs(Tabs, { value: selectedTab, onValueChange: setSelectedTab, children: [jsxs(TabsList, { children: [jsx(TabsTrigger, { value: "description", children: "Description" }), jsx(TabsTrigger, { value: "specifications", children: "Specifications" }), jsxs(TabsTrigger, { value: "reviews", children: ["Reviews (", reviewsList.length, ")"] })] }), jsx(TabsContent, { value: "description", className: "mt-8", children: jsx(Card, { children: jsxs(CardContent, { className: "p-8", children: [jsx("h3", { className: "text-xl font-semibold mb-4", children: "Product Description" }), jsxs("div", { className: "prose max-w-none", children: [jsx("p", { className: "text-gray-600 leading-relaxed mb-4", children: productData.description }), jsx("p", { className: "text-gray-600 leading-relaxed", children: "This premium product offers exceptional quality and performance, designed to meet the highest standards. With advanced features and reliable construction, it's perfect for both professional and personal use." })] })] }) }) }), jsx(TabsContent, { value: "specifications", className: "mt-8", children: jsx(Card, { children: jsxs(CardContent, { className: "p-8", children: [jsx("h3", { className: "text-xl font-semibold mb-4", children: "Technical Specifications" }), jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: Object.entries(specifications).map(([key, value]) => (jsxs("div", { className: "flex justify-between py-2 border-b border-gray-100", children: [jsxs("span", { className: "font-medium text-gray-900", children: [key, ":"] }), jsx("span", { className: "text-gray-600", children: String(value) })] }, key))) })] }) }) }), jsx(TabsContent, { value: "reviews", className: "mt-8", children: jsxs("div", { className: "space-y-6", children: [jsx(Card, { children: jsx(CardContent, { className: "p-8", children: jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-8", children: [jsxs("div", { children: [jsx("h3", { className: "text-xl font-semibold mb-4", children: "Customer Reviews" }), jsxs("div", { className: "flex items-center space-x-4 mb-4", children: [jsx("span", { className: "text-4xl font-bold text-gray-900", children: productData.rating }), jsxs("div", { children: [jsx("div", { className: "flex items-center space-x-1 mb-1", children: [1, 2, 3, 4, 5].map((star) => (jsx(Star, { className: `h-5 w-5 ${star <= Math.floor(productData.rating)
50
60
  ? 'text-yellow-400 fill-current'
51
61
  : 'text-gray-300'}` }, star))) }), jsxs("span", { className: "text-gray-600", children: ["Based on ", productData.reviewCount, " reviews"] })] })] })] }), jsx("div", { children: jsx(Button, { variant: "primary", className: "w-full", children: "Write a Review" }) })] }) }) }), reviewsList.map((review) => (jsx(Card, { children: jsx(CardContent, { className: "p-6", children: jsxs("div", { className: "flex items-start space-x-4", children: [jsxs(Avatar, { children: [jsx(AvatarImage, { src: review.userAvatar }), jsx(AvatarFallback, { children: review.userName[0] })] }), jsxs("div", { className: "flex-1", children: [jsxs("div", { className: "flex items-center space-x-2 mb-2", children: [jsx("span", { className: "font-medium text-gray-900", children: review.userName }), review.verified && (jsx(Badge, { variant: "success", className: "text-xs", children: "Verified Purchase" }))] }), jsxs("div", { className: "flex items-center space-x-2 mb-2", children: [jsx("div", { className: "flex items-center space-x-1", children: [1, 2, 3, 4, 5].map((star) => (jsx(Star, { className: `h-4 w-4 ${star <= review.rating
52
62
  ? 'text-yellow-400 fill-current'
53
- : 'text-gray-300'}` }, star))) }), jsx("span", { className: "text-sm text-gray-600", children: review.date })] }), jsx("h4", { className: "font-medium text-gray-900 mb-2", children: review.title }), jsx("p", { className: "text-gray-600 mb-4", children: review.comment }), jsx("div", { className: "flex items-center space-x-4", children: jsxs("button", { className: "flex items-center space-x-1 text-sm text-gray-600 hover:text-gray-900", children: [jsx(ThumbsUp, { className: "h-4 w-4" }), jsxs("span", { children: ["Helpful (", review.helpful, ")"] })] }) })] })] }) }) }, review.id)))] }) })] }) }), jsxs("div", { className: "mt-16", children: [jsx("h2", { className: "text-2xl font-bold text-gray-900 mb-8", children: "Related Products" }), jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6", children: relatedProductsList.map((relatedProduct) => (jsxs(Card, { className: "hover:shadow-lg transition-shadow", children: [jsx("div", { className: "aspect-square bg-gray-100 rounded-t-lg overflow-hidden", children: jsx("img", { src: relatedProduct.images[0], alt: relatedProduct.name, className: "w-full h-full object-cover" }) }), jsxs(CardContent, { className: "p-4", children: [jsx("h3", { className: "font-medium text-gray-900 mb-2 line-clamp-2", children: relatedProduct.name }), jsxs("div", { className: "flex items-center space-x-1 mb-2", children: [jsx(Star, { className: "h-4 w-4 text-yellow-400 fill-current" }), jsxs("span", { className: "text-sm text-gray-600", children: [relatedProduct.rating, " (", relatedProduct.reviewCount, ")"] })] }), jsxs("div", { className: "flex items-center justify-between", children: [jsxs("span", { className: "text-lg font-bold text-gray-900", children: ["$", relatedProduct.price.toFixed(2)] }), jsx(Button, { size: "sm", variant: "outline", children: "View" })] })] })] }, relatedProduct.id))) })] })] }));
63
+ : 'text-gray-300'}` }, star))) }), jsx("span", { className: "text-sm text-gray-600", children: review.date })] }), jsx("h4", { className: "font-medium text-gray-900 mb-2", children: review.title }), jsx("p", { className: "text-gray-600 mb-4", children: review.comment }), jsx("div", { className: "flex items-center space-x-4", children: jsxs("button", { className: "flex items-center space-x-1 text-sm text-gray-600 hover:text-gray-900", children: [jsx(ThumbsUp, { className: "h-4 w-4" }), jsxs("span", { children: ["Helpful (", review.helpful, ")"] })] }) })] })] }) }) }, review.id)))] }) })] }) }), jsxs("div", { className: "mt-16", children: [jsx("h2", { className: "text-2xl font-bold text-gray-900 mb-8", children: "Related Products" }), jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6", children: relatedProductsList.map((relatedProduct) => (jsxs(Card, { className: "hover:shadow-lg transition-shadow", children: [jsx("div", { className: "aspect-square bg-gray-100 rounded-t-lg overflow-hidden", children: jsx("img", { src: Array.isArray(relatedProduct.images) && relatedProduct.images.length > 0
64
+ ? relatedProduct.images[0]
65
+ : "/images/placeholder-product.png", alt: relatedProduct.name, className: "w-full h-full object-cover" }) }), jsxs(CardContent, { className: "p-4", children: [jsx("h3", { className: "font-medium text-gray-900 mb-2 line-clamp-2", children: relatedProduct.name }), jsxs("div", { className: "flex items-center space-x-1 mb-2", children: [jsx(Star, { className: "h-4 w-4 text-yellow-400 fill-current" }), jsxs("span", { className: "text-sm text-gray-600", children: [relatedProduct.rating, " (", relatedProduct.reviewCount, ")"] })] }), jsxs("div", { className: "flex items-center justify-between", children: [jsxs("span", { className: "text-lg font-bold text-gray-900", children: ["$", relatedProduct.price.toFixed(2)] }), jsx(Button, { size: "sm", variant: "outline", children: "View" })] })] })] }, relatedProduct.id))) })] })] }));
54
66
  };
55
67
 
56
68
  export { SingleProductView };
@@ -1 +1 @@
1
- {"version":3,"file":"SingleProductView.js","sources":["../../../src/components/Marketplace/SingleProductView.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { \n Star, \n Heart, \n Share2, \n ShoppingCart, \n Zap, \n Shield, \n Truck, \n RotateCcw,\n ChevronLeft,\n ChevronRight,\n Plus,\n Minus,\n Check,\n ThumbsUp\n} from 'lucide-react';\nimport { Button } from '../Button';\nimport { Card, CardHeader, CardTitle, CardContent } from '../Card';\nimport { Badge } from '../Badge';\nimport { Avatar, AvatarImage, AvatarFallback } from '../Avatar';\nimport { Input } from '../Input';\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from '../Tabs';\nimport { showToast } from '../Toast';\nimport type { Product, Review } from './types';\nimport { sampleProducts, sampleReviews } from './data/sampleData';\n\ninterface SingleProductViewProps {\n product?: Product;\n reviews?: Review[];\n relatedProducts?: Product[];\n onAddToCart?: (product: Product, quantity: number) => void;\n onBuyNow?: (product: Product, quantity: number) => void;\n}\n\nexport const SingleProductView: React.FC<SingleProductViewProps> = ({\n product,\n reviews,\n relatedProducts,\n onAddToCart,\n onBuyNow,\n}) => {\n const productsData = require('./data/sampleData').sampleProducts;\n const reviewsData = require('./data/sampleData').sampleReviews;\n\n // Fallbacks for backward compatibility\n // Defensive: If product is undefined, show a fallback UI instead of crashing\n if (!product && (!productsData || productsData.length === 0)) {\n return <div className=\"text-red-600\">Product not found.</div>;\n }\n const productData = product ?? productsData[0];\n const reviewsList = reviews ?? reviewsData;\n const relatedProductsList = relatedProducts ?? productsData.slice(1, 5);\n\n const [selectedImageIndex, setSelectedImageIndex] = useState(0);\n const [quantity, setQuantity] = useState(1);\n const [isWishlisted, setIsWishlisted] = useState(false);\n const [selectedTab, setSelectedTab] = useState('description');\n\n const handleAddToCart = () => {\n onAddToCart?.(productData, quantity);\n showToast.success(`Added ${quantity} item(s) to cart!`);\n };\n\n const handleBuyNow = () => {\n onBuyNow?.(productData, quantity);\n showToast.info('Redirecting to checkout...');\n };\n\n const handleShare = () => {\n navigator.clipboard.writeText(window.location.href);\n showToast.success('Product link copied to clipboard!');\n };\n\n const nextImage = () => {\n setSelectedImageIndex((prev) =>\n prev === productData.images.length - 1 ? 0 : prev + 1\n );\n };\n\n const prevImage = () => {\n setSelectedImageIndex((prev) =>\n prev === 0 ? productData.images.length - 1 : prev - 1\n );\n };\n\n return (\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8\">\n {/* Breadcrumb */}\n <nav className=\"flex items-center space-x-2 text-sm text-gray-600 mb-8\">\n <a href=\"/\" className=\"hover:text-primary-600\">Home</a>\n <span>/</span>\n <a href=\"/products\" className=\"hover:text-primary-600\">Products</a>\n <span>/</span>\n <a href={`/category/${productData.category.toLowerCase()}`} className=\"hover:text-primary-600\">\n {productData.category}\n </a>\n <span>/</span>\n <span className=\"text-gray-900\">{productData.name}</span>\n </nav>\n\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-12\">\n {/* Product Images */}\n <div>\n {/* Main Image */}\n <div className=\"relative aspect-square bg-gray-100 rounded-lg overflow-hidden mb-4\">\n <img\n src={productData.images[selectedImageIndex]}\n alt={productData.name}\n className=\"w-full h-full object-cover\"\n />\n {productData.images.length > 1 && (\n <>\n <button\n onClick={prevImage}\n className=\"absolute left-4 top-1/2 transform -translate-y-1/2 bg-white/80 hover:bg-white rounded-full p-2 shadow-lg transition-colors\"\n >\n <ChevronLeft className=\"h-5 w-5\" />\n </button>\n <button\n onClick={nextImage}\n className=\"absolute right-4 top-1/2 transform -translate-y-1/2 bg-white/80 hover:bg-white rounded-full p-2 shadow-lg transition-colors\"\n >\n <ChevronRight className=\"h-5 w-5\" />\n </button>\n </>\n )}\n {productData.discount && (\n <Badge variant=\"danger\" className=\"absolute top-4 left-4\">\n -{productData.discount}%\n </Badge>\n )}\n </div>\n\n {/* Thumbnail Images */}\n {productData.images.length > 1 && (\n <div className=\"flex space-x-2 overflow-x-auto\">\n {productData.images.map((image: string, index: number) => (\n <button\n key={index}\n onClick={() => setSelectedImageIndex(index)}\n className={`flex-shrink-0 w-20 h-20 rounded-lg overflow-hidden border-2 transition-colors ${\n selectedImageIndex === index\n ? 'border-primary-500'\n : 'border-gray-200 hover:border-gray-300'\n }`}\n >\n <img\n src={image}\n alt={`${productData.name} ${index + 1}`}\n className=\"w-full h-full object-cover\"\n />\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Product Details */}\n <div>\n {/* Vendor */}\n <div className=\"flex items-center space-x-2 mb-4\">\n <span className=\"text-sm text-gray-600\">Sold by</span>\n <div className=\"flex items-center space-x-2\">\n {productData.vendor.logo && (\n <Avatar size=\"sm\">\n <AvatarImage src={productData.vendor.logo} />\n <AvatarFallback>{productData.vendor.name[0]}</AvatarFallback>\n </Avatar>\n )}\n <span className=\"font-medium text-primary-600\">{productData.vendor.name}</span>\n <div className=\"flex items-center space-x-1\">\n <Star className=\"h-4 w-4 text-yellow-400 fill-current\" />\n <span className=\"text-sm text-gray-600\">{productData.vendor.rating}</span>\n </div>\n </div>\n </div>\n\n {/* Product Title */}\n <h1 className=\"text-3xl font-bold text-gray-900 mb-4\">{productData.name}</h1>\n\n {/* Rating and Reviews */}\n <div className=\"flex items-center space-x-4 mb-6\">\n <div className=\"flex items-center space-x-1\">\n {[1, 2, 3, 4, 5].map((star) => (\n <Star\n key={star}\n className={`h-5 w-5 ${\n star <= Math.floor(productData.rating)\n ? 'text-yellow-400 fill-current'\n : 'text-gray-300'\n }`}\n />\n ))}\n <span className=\"text-lg font-medium text-gray-900 ml-2\">\n {productData.rating}\n </span>\n </div>\n <span className=\"text-gray-600\">({productData.reviewCount} reviews)</span>\n <Badge variant={productData.inStock ? 'success' : 'danger'}>\n {productData.inStock ? 'In Stock' : 'Out of Stock'}\n </Badge>\n </div>\n\n {/* Price */}\n <div className=\"mb-6\">\n <div className=\"flex items-center space-x-3\">\n <span className=\"text-3xl font-bold text-gray-900\">\n ${productData.price.toFixed(2)}\n </span>\n {productData.originalPrice && (\n <span className=\"text-xl text-gray-500 line-through\">\n ${productData.originalPrice.toFixed(2)}\n </span>\n )}\n {productData.discount && (\n <Badge variant=\"danger\">Save {productData.discount}%</Badge>\n )}\n </div>\n </div>\n\n {/* Description */}\n <p className=\"text-gray-600 mb-6 leading-relaxed\">{productData.description}</p>\n\n {/* Quantity and Actions */}\n <div className=\"space-y-4 mb-8\">\n <div className=\"flex items-center space-x-4\">\n <span className=\"font-medium text-gray-900\">Quantity:</span>\n <div className=\"flex items-center border border-gray-300 rounded-lg\">\n <button\n onClick={() => setQuantity(Math.max(1, quantity - 1))}\n className=\"p-2 hover:bg-gray-50 transition-colors\"\n disabled={quantity <= 1}\n >\n <Minus className=\"h-4 w-4\" />\n </button>\n <Input\n type=\"number\"\n value={quantity}\n onChange={(e) => setQuantity(Math.max(1, parseInt(e.target.value) || 1))}\n className=\"w-16 text-center border-0 focus:ring-0\"\n min=\"1\"\n />\n <button\n onClick={() => setQuantity(quantity + 1)}\n className=\"p-2 hover:bg-gray-50 transition-colors\"\n >\n <Plus className=\"h-4 w-4\" />\n </button>\n </div>\n </div>\n\n <div className=\"flex space-x-4\">\n <Button\n variant=\"primary\"\n size=\"lg\"\n onClick={handleAddToCart}\n disabled={!productData.inStock}\n className=\"flex-1\"\n >\n <ShoppingCart className=\"mr-2 h-5 w-5\" />\n Add to Cart\n </Button>\n <Button\n variant=\"secondary\"\n size=\"lg\"\n onClick={handleBuyNow}\n disabled={!productData.inStock}\n className=\"flex-1\"\n >\n <Zap className=\"mr-2 h-5 w-5\" />\n Buy Now\n </Button>\n </div>\n\n <div className=\"flex space-x-2\">\n <Button\n variant=\"outline\"\n onClick={() => setIsWishlisted(!isWishlisted)}\n className=\"flex-1\"\n >\n <Heart className={`mr-2 h-5 w-5 ${isWishlisted ? 'fill-current text-red-500' : ''}`} />\n {isWishlisted ? 'Wishlisted' : 'Add to Wishlist'}\n </Button>\n <Button variant=\"outline\" onClick={handleShare}>\n <Share2 className=\"h-5 w-5\" />\n </Button>\n </div>\n </div>\n\n {/* Features */}\n <div className=\"grid grid-cols-2 gap-4 mb-8\">\n <div className=\"flex items-center space-x-2 text-sm text-gray-600\">\n <Truck className=\"h-4 w-4 text-green-600\" />\n <span>Free shipping</span>\n </div>\n <div className=\"flex items-center space-x-2 text-sm text-gray-600\">\n <RotateCcw className=\"h-4 w-4 text-blue-600\" />\n <span>30-day returns</span>\n </div>\n <div className=\"flex items-center space-x-2 text-sm text-gray-600\">\n <Shield className=\"h-4 w-4 text-purple-600\" />\n <span>2-year warranty</span>\n </div>\n <div className=\"flex items-center space-x-2 text-sm text-gray-600\">\n <Check className=\"h-4 w-4 text-green-600\" />\n <span>Authentic product</span>\n </div>\n </div>\n </div>\n </div>\n\n {/* Product Details Tabs */}\n <div className=\"mt-16\">\n <Tabs value={selectedTab} onValueChange={setSelectedTab}>\n <TabsList>\n <TabsTrigger value=\"description\">Description</TabsTrigger>\n <TabsTrigger value=\"specifications\">Specifications</TabsTrigger>\n <TabsTrigger value=\"reviews\">Reviews ({reviewsList.length})</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"description\" className=\"mt-8\">\n <Card>\n <CardContent className=\"p-8\">\n <h3 className=\"text-xl font-semibold mb-4\">Product Description</h3>\n <div className=\"prose max-w-none\">\n <p className=\"text-gray-600 leading-relaxed mb-4\">\n {productData.description}\n </p>\n <p className=\"text-gray-600 leading-relaxed\">\n This premium product offers exceptional quality and performance, \n designed to meet the highest standards. With advanced features and \n reliable construction, it's perfect for both professional and personal use.\n </p>\n </div>\n </CardContent>\n </Card>\n </TabsContent>\n\n <TabsContent value=\"specifications\" className=\"mt-8\">\n <Card>\n <CardContent className=\"p-8\">\n <h3 className=\"text-xl font-semibold mb-4\">Technical Specifications</h3>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {Object.entries(productData.specifications).map(([key, value]) => (\n <div key={key} className=\"flex justify-between py-2 border-b border-gray-100\">\n <span className=\"font-medium text-gray-900\">{key}:</span>\n <span className=\"text-gray-600\">{String(value)}</span>\n </div>\n ))}\n </div>\n </CardContent>\n </Card>\n </TabsContent>\n\n <TabsContent value=\"reviews\" className=\"mt-8\">\n <div className=\"space-y-6\">\n {/* Reviews Summary */}\n <Card>\n <CardContent className=\"p-8\">\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-8\">\n <div>\n <h3 className=\"text-xl font-semibold mb-4\">Customer Reviews</h3>\n <div className=\"flex items-center space-x-4 mb-4\">\n <span className=\"text-4xl font-bold text-gray-900\">\n {productData.rating}\n </span>\n <div>\n <div className=\"flex items-center space-x-1 mb-1\">\n {[1, 2, 3, 4, 5].map((star) => (\n <Star\n key={star}\n className={`h-5 w-5 ${\n star <= Math.floor(productData.rating)\n ? 'text-yellow-400 fill-current'\n : 'text-gray-300'\n }`}\n />\n ))}\n </div>\n <span className=\"text-gray-600\">\n Based on {productData.reviewCount} reviews\n </span>\n </div>\n </div>\n </div>\n <div>\n <Button variant=\"primary\" className=\"w-full\">\n Write a Review\n </Button>\n </div>\n </div>\n </CardContent>\n </Card>\n\n {/* Individual Reviews */}\n {reviewsList.map((review: Review) => (\n <Card key={review.id}>\n <CardContent className=\"p-6\">\n <div className=\"flex items-start space-x-4\">\n <Avatar>\n <AvatarImage src={review.userAvatar} />\n <AvatarFallback>{review.userName[0]}</AvatarFallback>\n </Avatar>\n <div className=\"flex-1\">\n <div className=\"flex items-center space-x-2 mb-2\">\n <span className=\"font-medium text-gray-900\">{review.userName}</span>\n {review.verified && (\n <Badge variant=\"success\" className=\"text-xs\">\n Verified Purchase\n </Badge>\n )}\n </div>\n <div className=\"flex items-center space-x-2 mb-2\">\n <div className=\"flex items-center space-x-1\">\n {[1, 2, 3, 4, 5].map((star: number) => (\n <Star\n key={star}\n className={`h-4 w-4 ${\n star <= review.rating\n ? 'text-yellow-400 fill-current'\n : 'text-gray-300'\n }`}\n />\n ))}\n </div>\n <span className=\"text-sm text-gray-600\">{review.date}</span>\n </div>\n <h4 className=\"font-medium text-gray-900 mb-2\">{review.title}</h4>\n <p className=\"text-gray-600 mb-4\">{review.comment}</p>\n <div className=\"flex items-center space-x-4\">\n <button className=\"flex items-center space-x-1 text-sm text-gray-600 hover:text-gray-900\">\n <ThumbsUp className=\"h-4 w-4\" />\n <span>Helpful ({review.helpful})</span>\n </button>\n </div>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n </TabsContent>\n </Tabs>\n </div>\n\n {/* Related Products */}\n <div className=\"mt-16\">\n <h2 className=\"text-2xl font-bold text-gray-900 mb-8\">Related Products</h2>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6\">\n {relatedProductsList.map((relatedProduct: Product) => (\n <Card key={relatedProduct.id} className=\"hover:shadow-lg transition-shadow\">\n <div className=\"aspect-square bg-gray-100 rounded-t-lg overflow-hidden\">\n <img\n src={relatedProduct.images[0]}\n alt={relatedProduct.name}\n className=\"w-full h-full object-cover\"\n />\n </div>\n <CardContent className=\"p-4\">\n <h3 className=\"font-medium text-gray-900 mb-2 line-clamp-2\">\n {relatedProduct.name}\n </h3>\n <div className=\"flex items-center space-x-1 mb-2\">\n <Star className=\"h-4 w-4 text-yellow-400 fill-current\" />\n <span className=\"text-sm text-gray-600\">\n {relatedProduct.rating} ({relatedProduct.reviewCount})\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-lg font-bold text-gray-900\">\n ${relatedProduct.price.toFixed(2)}\n </span>\n <Button size=\"sm\" variant=\"outline\">\n View\n </Button>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n </div>\n </div>\n );\n};"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
1
+ {"version":3,"file":"SingleProductView.js","sources":["../../../src/components/Marketplace/SingleProductView.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { \n Star, \n Heart, \n Share2, \n ShoppingCart, \n Zap, \n Shield, \n Truck, \n RotateCcw,\n ChevronLeft,\n ChevronRight,\n Plus,\n Minus,\n Check,\n ThumbsUp\n} from 'lucide-react';\nimport { Button } from '../Button';\nimport { Card, CardHeader, CardTitle, CardContent } from '../Card';\nimport { Badge } from '../Badge';\nimport { Avatar, AvatarImage, AvatarFallback } from '../Avatar';\nimport { Input } from '../Input';\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from '../Tabs';\nimport { showToast } from '../Toast';\nimport type { Product, Review } from './types';\nimport { sampleProducts, sampleReviews } from './data/sampleData';\n\ninterface SingleProductViewProps {\n product?: Product;\n reviews?: Review[];\n relatedProducts?: Product[];\n onAddToCart?: (product: Product, quantity: number) => void;\n onBuyNow?: (product: Product, quantity: number) => void;\n}\n\nexport const SingleProductView: React.FC<SingleProductViewProps> = ({\n product,\n reviews,\n relatedProducts,\n onAddToCart,\n onBuyNow,\n}) => {\n const productsData = require('./data/sampleData').sampleProducts;\n const reviewsData = require('./data/sampleData').sampleReviews;\n\n // Fallbacks for backward compatibility\n // Defensive: If product is undefined, show a fallback UI instead of crashing\n if (!product && (!productsData || productsData.length === 0)) {\n return <div className=\"text-red-600\">Product not found.</div>;\n }\n const productData = product ?? productsData[0];\n const reviewsList = reviews ?? reviewsData;\n const relatedProductsList = relatedProducts ?? productsData.slice(1, 5);\n \n // Defensive guards and fallbacks\n const images = Array.isArray(productData.images) && productData.images.length > 0\n ? productData.images\n : [\"/images/placeholder-product.png\"];\n const specifications = productData.specifications && Object.keys(productData.specifications).length > 0\n ? productData.specifications\n : { \"Info\": \"No specifications available\" };\n const vendor = productData.vendor && productData.vendor.name\n ? productData.vendor\n : { id: \"unknown\", name: \"Unknown Vendor\", rating: 0, logo: undefined };\n\n const [selectedImageIndex, setSelectedImageIndex] = useState(0);\n const [quantity, setQuantity] = useState(1);\n const [isWishlisted, setIsWishlisted] = useState(false);\n const [selectedTab, setSelectedTab] = useState('description');\n\n const handleAddToCart = () => {\n onAddToCart?.(productData, quantity);\n showToast.success(`Added ${quantity} item(s) to cart!`);\n };\n\n const handleBuyNow = () => {\n onBuyNow?.(productData, quantity);\n showToast.info('Redirecting to checkout...');\n };\n\n const handleShare = () => {\n navigator.clipboard.writeText(window.location.href);\n showToast.success('Product link copied to clipboard!');\n };\n\n const nextImage = () => {\n setSelectedImageIndex((prev) =>\n prev === productData.images.length - 1 ? 0 : prev + 1\n );\n };\n\n const prevImage = () => {\n setSelectedImageIndex((prev) =>\n prev === 0 ? productData.images.length - 1 : prev - 1\n );\n };\n\n return (\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8\">\n {/* Breadcrumb */}\n <nav className=\"flex items-center space-x-2 text-sm text-gray-600 mb-8\">\n <a href=\"/\" className=\"hover:text-primary-600\">Home</a>\n <span>/</span>\n <a href=\"/products\" className=\"hover:text-primary-600\">Products</a>\n <span>/</span>\n <a href={`/category/${productData.category.toLowerCase()}`} className=\"hover:text-primary-600\">\n {productData.category}\n </a>\n <span>/</span>\n <span className=\"text-gray-900\">{productData.name}</span>\n </nav>\n\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-12\">\n {/* Product Images */}\n <div>\n {/* Main Image */}\n <div className=\"relative aspect-square bg-gray-100 rounded-lg overflow-hidden mb-4\">\n <img\n src={images[selectedImageIndex] ?? \"/images/placeholder-product.png\"}\n alt={productData.name}\n className=\"w-full h-full object-cover\"\n />\n {images.length > 1 && (\n <>\n <button\n onClick={prevImage}\n className=\"absolute left-4 top-1/2 transform -translate-y-1/2 bg-white/80 hover:bg-white rounded-full p-2 shadow-lg transition-colors\"\n >\n <ChevronLeft className=\"h-5 w-5\" />\n </button>\n <button\n onClick={nextImage}\n className=\"absolute right-4 top-1/2 transform -translate-y-1/2 bg-white/80 hover:bg-white rounded-full p-2 shadow-lg transition-colors\"\n >\n <ChevronRight className=\"h-5 w-5\" />\n </button>\n </>\n )}\n {productData.discount && (\n <Badge variant=\"danger\" className=\"absolute top-4 left-4\">\n -{productData.discount}%\n </Badge>\n )}\n </div>\n\n {/* Thumbnail Images */}\n {images.length > 1 && (\n <div className=\"flex space-x-2 overflow-x-auto\">\n {images.map((image: string, index: number) => (\n <button\n key={index}\n onClick={() => setSelectedImageIndex(index)}\n className={`flex-shrink-0 w-20 h-20 rounded-lg overflow-hidden border-2 transition-colors ${\n selectedImageIndex === index\n ? 'border-primary-500'\n : 'border-gray-200 hover:border-gray-300'\n }`}\n >\n <img\n src={image}\n alt={`${productData.name} ${index + 1}`}\n className=\"w-full h-full object-cover\"\n />\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Product Details */}\n <div>\n {/* Vendor */}\n <div className=\"flex items-center space-x-2 mb-4\">\n <span className=\"text-sm text-gray-600\">Sold by</span>\n <div className=\"flex items-center space-x-2\">\n {vendor.logo ? (\n <Avatar size=\"sm\">\n <AvatarImage src={vendor.logo} />\n <AvatarFallback>{vendor.name[0]}</AvatarFallback>\n </Avatar>\n ) : (\n <Avatar size=\"sm\">\n <AvatarFallback>{vendor.name[0]}</AvatarFallback>\n </Avatar>\n )}\n <span className=\"font-medium text-primary-600\">{vendor.name}</span>\n <div className=\"flex items-center space-x-1\">\n <Star className=\"h-4 w-4 text-yellow-400 fill-current\" />\n <span className=\"text-sm text-gray-600\">{vendor.rating}</span>\n </div>\n </div>\n </div>\n\n {/* Product Title */}\n <h1 className=\"text-3xl font-bold text-gray-900 mb-4\">{productData.name}</h1>\n\n {/* Rating and Reviews */}\n <div className=\"flex items-center space-x-4 mb-6\">\n <div className=\"flex items-center space-x-1\">\n {[1, 2, 3, 4, 5].map((star) => (\n <Star\n key={star}\n className={`h-5 w-5 ${\n star <= Math.floor(productData.rating)\n ? 'text-yellow-400 fill-current'\n : 'text-gray-300'\n }`}\n />\n ))}\n <span className=\"text-lg font-medium text-gray-900 ml-2\">\n {productData.rating}\n </span>\n </div>\n <span className=\"text-gray-600\">({productData.reviewCount} reviews)</span>\n <Badge variant={productData.inStock ? 'success' : 'danger'}>\n {productData.inStock ? 'In Stock' : 'Out of Stock'}\n </Badge>\n </div>\n\n {/* Price */}\n <div className=\"mb-6\">\n <div className=\"flex items-center space-x-3\">\n <span className=\"text-3xl font-bold text-gray-900\">\n ${productData.price.toFixed(2)}\n </span>\n {productData.originalPrice && (\n <span className=\"text-xl text-gray-500 line-through\">\n ${productData.originalPrice.toFixed(2)}\n </span>\n )}\n {productData.discount && (\n <Badge variant=\"danger\">Save {productData.discount}%</Badge>\n )}\n </div>\n </div>\n\n {/* Description */}\n <p className=\"text-gray-600 mb-6 leading-relaxed\">{productData.description}</p>\n\n {/* Quantity and Actions */}\n <div className=\"space-y-4 mb-8\">\n <div className=\"flex items-center space-x-4\">\n <span className=\"font-medium text-gray-900\">Quantity:</span>\n <div className=\"flex items-center border border-gray-300 rounded-lg\">\n <button\n onClick={() => setQuantity(Math.max(1, quantity - 1))}\n className=\"p-2 hover:bg-gray-50 transition-colors\"\n disabled={quantity <= 1}\n >\n <Minus className=\"h-4 w-4\" />\n </button>\n <Input\n type=\"number\"\n value={quantity}\n onChange={(e) => setQuantity(Math.max(1, parseInt(e.target.value) || 1))}\n className=\"w-16 text-center border-0 focus:ring-0\"\n min=\"1\"\n />\n <button\n onClick={() => setQuantity(quantity + 1)}\n className=\"p-2 hover:bg-gray-50 transition-colors\"\n >\n <Plus className=\"h-4 w-4\" />\n </button>\n </div>\n </div>\n\n <div className=\"flex space-x-4\">\n <Button\n variant=\"primary\"\n size=\"lg\"\n onClick={handleAddToCart}\n disabled={!productData.inStock}\n className=\"flex-1\"\n >\n <ShoppingCart className=\"mr-2 h-5 w-5\" />\n Add to Cart\n </Button>\n <Button\n variant=\"secondary\"\n size=\"lg\"\n onClick={handleBuyNow}\n disabled={!productData.inStock}\n className=\"flex-1\"\n >\n <Zap className=\"mr-2 h-5 w-5\" />\n Buy Now\n </Button>\n </div>\n\n <div className=\"flex space-x-2\">\n <Button\n variant=\"outline\"\n onClick={() => setIsWishlisted(!isWishlisted)}\n className=\"flex-1\"\n >\n <Heart className={`mr-2 h-5 w-5 ${isWishlisted ? 'fill-current text-red-500' : ''}`} />\n {isWishlisted ? 'Wishlisted' : 'Add to Wishlist'}\n </Button>\n <Button variant=\"outline\" onClick={handleShare}>\n <Share2 className=\"h-5 w-5\" />\n </Button>\n </div>\n </div>\n\n {/* Features */}\n <div className=\"grid grid-cols-2 gap-4 mb-8\">\n <div className=\"flex items-center space-x-2 text-sm text-gray-600\">\n <Truck className=\"h-4 w-4 text-green-600\" />\n <span>Free shipping</span>\n </div>\n <div className=\"flex items-center space-x-2 text-sm text-gray-600\">\n <RotateCcw className=\"h-4 w-4 text-blue-600\" />\n <span>30-day returns</span>\n </div>\n <div className=\"flex items-center space-x-2 text-sm text-gray-600\">\n <Shield className=\"h-4 w-4 text-purple-600\" />\n <span>2-year warranty</span>\n </div>\n <div className=\"flex items-center space-x-2 text-sm text-gray-600\">\n <Check className=\"h-4 w-4 text-green-600\" />\n <span>Authentic product</span>\n </div>\n </div>\n </div>\n </div>\n\n {/* Product Details Tabs */}\n <div className=\"mt-16\">\n <Tabs value={selectedTab} onValueChange={setSelectedTab}>\n <TabsList>\n <TabsTrigger value=\"description\">Description</TabsTrigger>\n <TabsTrigger value=\"specifications\">Specifications</TabsTrigger>\n <TabsTrigger value=\"reviews\">Reviews ({reviewsList.length})</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"description\" className=\"mt-8\">\n <Card>\n <CardContent className=\"p-8\">\n <h3 className=\"text-xl font-semibold mb-4\">Product Description</h3>\n <div className=\"prose max-w-none\">\n <p className=\"text-gray-600 leading-relaxed mb-4\">\n {productData.description}\n </p>\n <p className=\"text-gray-600 leading-relaxed\">\n This premium product offers exceptional quality and performance, \n designed to meet the highest standards. With advanced features and \n reliable construction, it's perfect for both professional and personal use.\n </p>\n </div>\n </CardContent>\n </Card>\n </TabsContent>\n\n <TabsContent value=\"specifications\" className=\"mt-8\">\n <Card>\n <CardContent className=\"p-8\">\n <h3 className=\"text-xl font-semibold mb-4\">Technical Specifications</h3>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {Object.entries(specifications).map(([key, value]) => (\n <div key={key} className=\"flex justify-between py-2 border-b border-gray-100\">\n <span className=\"font-medium text-gray-900\">{key}:</span>\n <span className=\"text-gray-600\">{String(value)}</span>\n </div>\n ))}\n </div>\n </CardContent>\n </Card>\n </TabsContent>\n\n <TabsContent value=\"reviews\" className=\"mt-8\">\n <div className=\"space-y-6\">\n {/* Reviews Summary */}\n <Card>\n <CardContent className=\"p-8\">\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-8\">\n <div>\n <h3 className=\"text-xl font-semibold mb-4\">Customer Reviews</h3>\n <div className=\"flex items-center space-x-4 mb-4\">\n <span className=\"text-4xl font-bold text-gray-900\">\n {productData.rating}\n </span>\n <div>\n <div className=\"flex items-center space-x-1 mb-1\">\n {[1, 2, 3, 4, 5].map((star) => (\n <Star\n key={star}\n className={`h-5 w-5 ${\n star <= Math.floor(productData.rating)\n ? 'text-yellow-400 fill-current'\n : 'text-gray-300'\n }`}\n />\n ))}\n </div>\n <span className=\"text-gray-600\">\n Based on {productData.reviewCount} reviews\n </span>\n </div>\n </div>\n </div>\n <div>\n <Button variant=\"primary\" className=\"w-full\">\n Write a Review\n </Button>\n </div>\n </div>\n </CardContent>\n </Card>\n\n {/* Individual Reviews */}\n {reviewsList.map((review: Review) => (\n <Card key={review.id}>\n <CardContent className=\"p-6\">\n <div className=\"flex items-start space-x-4\">\n <Avatar>\n <AvatarImage src={review.userAvatar} />\n <AvatarFallback>{review.userName[0]}</AvatarFallback>\n </Avatar>\n <div className=\"flex-1\">\n <div className=\"flex items-center space-x-2 mb-2\">\n <span className=\"font-medium text-gray-900\">{review.userName}</span>\n {review.verified && (\n <Badge variant=\"success\" className=\"text-xs\">\n Verified Purchase\n </Badge>\n )}\n </div>\n <div className=\"flex items-center space-x-2 mb-2\">\n <div className=\"flex items-center space-x-1\">\n {[1, 2, 3, 4, 5].map((star: number) => (\n <Star\n key={star}\n className={`h-4 w-4 ${\n star <= review.rating\n ? 'text-yellow-400 fill-current'\n : 'text-gray-300'\n }`}\n />\n ))}\n </div>\n <span className=\"text-sm text-gray-600\">{review.date}</span>\n </div>\n <h4 className=\"font-medium text-gray-900 mb-2\">{review.title}</h4>\n <p className=\"text-gray-600 mb-4\">{review.comment}</p>\n <div className=\"flex items-center space-x-4\">\n <button className=\"flex items-center space-x-1 text-sm text-gray-600 hover:text-gray-900\">\n <ThumbsUp className=\"h-4 w-4\" />\n <span>Helpful ({review.helpful})</span>\n </button>\n </div>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n </TabsContent>\n </Tabs>\n </div>\n\n {/* Related Products */}\n <div className=\"mt-16\">\n <h2 className=\"text-2xl font-bold text-gray-900 mb-8\">Related Products</h2>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6\">\n {relatedProductsList.map((relatedProduct: Product) => (\n <Card key={relatedProduct.id} className=\"hover:shadow-lg transition-shadow\">\n <div className=\"aspect-square bg-gray-100 rounded-t-lg overflow-hidden\">\n <img\n src={Array.isArray(relatedProduct.images) && relatedProduct.images.length > 0\n ? relatedProduct.images[0]\n : \"/images/placeholder-product.png\"}\n alt={relatedProduct.name}\n className=\"w-full h-full object-cover\"\n />\n </div>\n <CardContent className=\"p-4\">\n <h3 className=\"font-medium text-gray-900 mb-2 line-clamp-2\">\n {relatedProduct.name}\n </h3>\n <div className=\"flex items-center space-x-1 mb-2\">\n <Star className=\"h-4 w-4 text-yellow-400 fill-current\" />\n <span className=\"text-sm text-gray-600\">\n {relatedProduct.rating} ({relatedProduct.reviewCount})\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-lg font-bold text-gray-900\">\n ${relatedProduct.price.toFixed(2)}\n </span>\n <Button size=\"sm\" variant=\"outline\">\n View\n </Button>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n </div>\n </div>\n );\n};"],"names":["_jsx","_jsxs"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Product } from "../types";
2
+ /**
3
+ * Ensures a Product object has all required fields and valid defaults.
4
+ * Returns a sanitized copy of the product.
5
+ */
6
+ export declare function sanitizeProduct(product: Partial<Product>): Product;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Ensures a Product object has all required fields and valid defaults.
3
+ * Returns a sanitized copy of the product.
4
+ */
5
+ function sanitizeProduct(product) {
6
+ return {
7
+ id: product.id ?? "unknown",
8
+ name: product.name ?? "Unnamed Product",
9
+ description: product.description ?? "No description available.",
10
+ price: typeof product.price === "number" ? product.price : 0,
11
+ originalPrice: typeof product.originalPrice === "number" ? product.originalPrice : undefined,
12
+ discount: typeof product.discount === "number" ? product.discount : undefined,
13
+ images: Array.isArray(product.images) && product.images.length > 0
14
+ ? product.images
15
+ : ["https://images.pexels.com/photos/2255935/pexels-photo-2255935.jpeg"],
16
+ category: product.category ?? "Misc",
17
+ brand: product.brand ?? "Unknown",
18
+ rating: typeof product.rating === "number" ? product.rating : 0,
19
+ reviewCount: typeof product.reviewCount === "number" ? product.reviewCount : 0,
20
+ inStock: typeof product.inStock === "boolean" ? product.inStock : false,
21
+ specifications: product.specifications && Object.keys(product.specifications).length > 0
22
+ ? product.specifications
23
+ : { "Info": "No specifications available" },
24
+ tags: Array.isArray(product.tags) ? product.tags : [],
25
+ vendor: product.vendor && product.vendor.name
26
+ ? {
27
+ id: product.vendor.id ?? "unknown",
28
+ name: product.vendor.name,
29
+ rating: typeof product.vendor.rating === "number" ? product.vendor.rating : 0,
30
+ logo: product.vendor.logo,
31
+ }
32
+ : {
33
+ id: "unknown",
34
+ name: "Unknown Vendor",
35
+ rating: 0,
36
+ logo: undefined,
37
+ },
38
+ };
39
+ }
40
+
41
+ export { sanitizeProduct };
42
+ //# sourceMappingURL=sanitizeProduct.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizeProduct.js","sources":["../../../../src/components/Marketplace/utils/sanitizeProduct.ts"],"sourcesContent":["import type { Product } from \"../types\";\r\n\r\n/**\r\n * Ensures a Product object has all required fields and valid defaults.\r\n * Returns a sanitized copy of the product.\r\n */\r\nexport function sanitizeProduct(product: Partial<Product>): Product {\r\n return {\r\n id: product.id ?? \"unknown\",\r\n name: product.name ?? \"Unnamed Product\",\r\n description: product.description ?? \"No description available.\",\r\n price: typeof product.price === \"number\" ? product.price : 0,\r\n originalPrice: typeof product.originalPrice === \"number\" ? product.originalPrice : undefined,\r\n discount: typeof product.discount === \"number\" ? product.discount : undefined,\r\n images: Array.isArray(product.images) && product.images.length > 0\r\n ? product.images\r\n : [\"https://images.pexels.com/photos/2255935/pexels-photo-2255935.jpeg\"],\r\n category: product.category ?? \"Misc\",\r\n brand: product.brand ?? \"Unknown\",\r\n rating: typeof product.rating === \"number\" ? product.rating : 0,\r\n reviewCount: typeof product.reviewCount === \"number\" ? product.reviewCount : 0,\r\n inStock: typeof product.inStock === \"boolean\" ? product.inStock : false,\r\n specifications: product.specifications && Object.keys(product.specifications).length > 0\r\n ? product.specifications\r\n : { \"Info\": \"No specifications available\" },\r\n tags: Array.isArray(product.tags) ? product.tags : [],\r\n vendor: product.vendor && product.vendor.name\r\n ? {\r\n id: product.vendor.id ?? \"unknown\",\r\n name: product.vendor.name,\r\n rating: typeof product.vendor.rating === \"number\" ? product.vendor.rating : 0,\r\n logo: product.vendor.logo,\r\n }\r\n : {\r\n id: \"unknown\",\r\n name: \"Unknown Vendor\",\r\n rating: 0,\r\n logo: undefined,\r\n },\r\n };\r\n}"],"names":[],"mappings":"AAEA;;;AAGG;AACG,SAAU,eAAe,CAAC,OAAyB,EAAA;IACvD,OAAO;AACL,QAAA,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,SAAS;AAC3B,QAAA,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,iBAAiB;AACvC,QAAA,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,2BAA2B;AAC/D,QAAA,KAAK,EAAE,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,GAAG,OAAO,CAAC,KAAK,GAAG,CAAC;AAC5D,QAAA,aAAa,EAAE,OAAO,OAAO,CAAC,aAAa,KAAK,QAAQ,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS;AAC5F,QAAA,QAAQ,EAAE,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS;AAC7E,QAAA,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG;cAC7D,OAAO,CAAC;cACR,CAAC,oEAAoE,CAAC;AAC1E,QAAA,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,MAAM;AACpC,QAAA,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,SAAS;AACjC,QAAA,MAAM,EAAE,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC;AAC/D,QAAA,WAAW,EAAE,OAAO,OAAO,CAAC,WAAW,KAAK,QAAQ,GAAG,OAAO,CAAC,WAAW,GAAG,CAAC;AAC9E,QAAA,OAAO,EAAE,OAAO,OAAO,CAAC,OAAO,KAAK,SAAS,GAAG,OAAO,CAAC,OAAO,GAAG,KAAK;AACvE,QAAA,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,MAAM,GAAG;cACnF,OAAO,CAAC;AACV,cAAE,EAAE,MAAM,EAAE,6BAA6B,EAAE;AAC7C,QAAA,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,GAAG,EAAE;QACrD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;AACvC,cAAE;AACE,gBAAA,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,SAAS;AAClC,gBAAA,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;gBACzB,MAAM,EAAE,OAAO,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;AAC7E,gBAAA,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;AAC1B;AACH,cAAE;AACE,gBAAA,EAAE,EAAE,SAAS;AACb,gBAAA,IAAI,EAAE,gBAAgB;AACtB,gBAAA,MAAM,EAAE,CAAC;AACT,gBAAA,IAAI,EAAE,SAAS;AAChB,aAAA;KACN;AACH;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beyondcorp/beyond-ui",
3
- "version": "1.2.41",
3
+ "version": "1.2.47",
4
4
  "description": "A comprehensive React UI component library built with TypeScript, TailwindCSS, and CVA",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",