The product catalog is the core of the Bİ DOLU İÇECEK e-commerce platform, organizing water and beverage products in a hierarchical structure with main products and sub-products.
Product Structure
Products are organized in a two-level hierarchy:
Main Products - Category-level products (e.g., “Fuska Su”, “Pınar Su”)
Sub-Products - Individual SKUs within each main product (e.g., “Fuska Su 19Lt Damacana”)
The product catalog is defined in src/data/products.js and exported as the PRODUCTS constant.
Product Data Structure
Main Product Schema
export const PRODUCTS = [
{
id: 1 ,
name: "Fuska Su" ,
price: "Seçenekleri Görün" ,
image: "/images/fuska.jpeg" ,
imagePlaceholder: "🍓" ,
whatsappMessage: "Merhaba Sultan Su sipariş etmek istiyorum. Adresim: " ,
subProducts: [
// Sub-products array
]
}
];
Sub-Product Schema
Each main product contains an array of sub-products with detailed specifications:
{
id : 11 ,
name : "Fuska Su 19Lt Damacana" ,
price : "160 TL" ,
image : "/images/f19.png" ,
imagePlaceholder : "🏺" ,
whatsappMessage : "Merhaba Sultan Su 19L damacana sipariş etmek istiyorum. Adresim: "
}
Product Field Definitions
Field Type Description idnumber Unique identifier for the product namestring Display name of the product pricestring Price or “Seçenekleri Görün” for main products imagestring Path to product image imagePlaceholderstring Emoji shown while image loads whatsappMessagestring Pre-filled WhatsApp message template subProductsarray Array of sub-product objects (main products only)
Product Categories
The platform currently supports 9 main product categories:
Main Products
Example Sub-Products
1. Fuska Su ( id : 1 )
2. Pınar Su ( id : 2 )
3. Buzdağı Su ( id : 3 )
4. Sultan Su ( id : 4 )
5. Uludağ İçecek ( id : 5 )
6. Erikli Su ( id : 6 )
7. Munzur Su ( id : 7 )
8. Taşkesti Su ( id : 8 )
9. Bardak Su ( id : 9 )
Image Management
Image Paths
Product images are stored in the /public/images/ directory and referenced using absolute paths:
image : "/images/fuska.jpeg"
Image Placeholders
While images load, emoji placeholders provide visual feedback:
imagePlaceholder : "🍓" // Main product
imagePlaceholder : "🏺" // Damacana (jug)
imagePlaceholder : "🍼" // Bottle
imagePlaceholder : "📦" // Package
Use descriptive emojis that represent the product type for better user experience during loading.
Image Helper Function
The catalog includes a helper function for normalizing image paths:
export const getProductImagePath = ( imageName ) => {
const normalizedName = imageName
. toLowerCase ()
. replace ( / \s + / g , '-' )
. replace ( / [ ^ a-z0-9- ] / g , '' );
return `/images/ ${ normalizedName } .jpg` ;
};
Product Modals
When users click on a main product, a modal displays all sub-products. The modal is implemented in ProductModal.js:
src/components/ProductModal.js
const ProductModal = ({ product , isOpen , onClose }) => {
if ( ! isOpen || ! product ) return null ;
return (
< div className = "modal-overlay" >
< div className = "modal-backdrop" ></ div >
< div className = "modal-content" >
{ /* Header with product info */ }
< div className = "modal-header" >
< div className = "modal-header-info" >
< div className = "modal-header-icon" >
< span > { product . imagePlaceholder } </ span >
</ div >
< h2 > { product . name } </ h2 >
</ div >
< button onClick = { onClose } className = "modal-close-btn" >
< span > ‹ </ span >
</ button >
</ div >
{ /* Sub Products Grid */ }
< div className = "modal-body" >
< div className = "modal-grid" >
{ product . subProducts ?. map (( subProduct ) => (
< SubProductCard
key = { subProduct . id }
subProduct = { subProduct }
/>
)) }
</ div >
</ div >
</ div >
</ div >
);
};
The modal uses backdrop click detection to close. Make sure event propagation is properly handled in nested elements.
Sub-Product Cards
Each sub-product is rendered as a card with cart integration:
src/components/ProductModal.js
const SubProductCard = ({ subProduct }) => {
const { addItem , removeItem , getItemQuantity } = useCart ();
const quantity = getItemQuantity ( subProduct . id );
return (
< div className = "sub-product-card" onClick = { () => addItem ( subProduct ) } >
< div className = "sub-product-image" >
< ProductImage
src = { subProduct . image }
alt = { ` ${ subProduct . name } resmi` }
placeholder = { subProduct . imagePlaceholder }
/>
</ div >
< h4 className = "sub-product-name" > { subProduct . name } </ h4 >
< div className = "sub-product-price" > { subProduct . price } </ div >
{ quantity > 0 ? (
< div className = "quantity-controls" >
< button onClick = { handleRemoveFromCart } > − </ button >
< span > { quantity } </ span >
< button onClick = { handleAddToCart } > + </ button >
</ div >
) : (
< button onClick = { handleAddToCart } >
{ t ( 'addToCart' ) }
</ button >
) }
</ div >
);
};
Best Practices
Unique IDs Ensure all product and sub-product IDs are unique across the entire catalog to prevent cart conflicts.
Image Optimization Use optimized images and appropriate emoji placeholders to improve loading performance.
Price Formatting Maintain consistent price formatting (e.g., “160 TL”) for proper cart total calculations.
Accessibility Include descriptive alt text for images and proper ARIA labels for interactive elements.
Adding New Products
To add a new product to the catalog:
Add product images to /public/images/
Choose an emoji placeholder that represents the product
Add product data to the PRODUCTS array:
{
id : 10 , // Next available ID
name : "New Water Brand" ,
price : "Seçenekleri Görün" ,
image : "/images/new-brand.png" ,
imagePlaceholder : "💧" ,
whatsappMessage : "Merhaba New Water Brand sipariş etmek istiyorum. Adresim: " ,
subProducts : [
{
id: 101 , // Unique sub-product ID
name: "New Water Brand 19Lt Damacana" ,
price: "180 TL" ,
image: "/images/new-19.png" ,
imagePlaceholder: "🏺" ,
whatsappMessage: "Merhaba New Water Brand 19L sipariş etmek istiyorum. Adresim: "
}
]
}
Start sub-product IDs at (mainProductId * 10 + 1) to maintain clear ID organization.
Shopping Cart Learn how products are added to and managed in the shopping cart
WhatsApp Ordering See how product data is used to generate WhatsApp order messages