Preview:
import { useState, useMemo } from 'react';

// Sample product data (since we can't use Redux)
const initialProducts = [
    {
        _id: '1',
        title: 'Smartphone X',
        brand_name: 'TechBrand',
        category: 'Electronics',
        price: 799,
        color: 'Black'
    },
    {
        _id: '2',
        title: 'Laptop Pro',
        brand_name: 'ComputeCo',
        category: 'Computers',
        price: 1299,
        color: 'Silver'
    },
    {
        _id: '3',
        title: 'Wireless Earbuds',
        brand_name: 'AudioTech',
        category: 'Audio',
        price: 199,
        color: 'White'
    },
    {
        _id: '4',
        title: 'Smartwatch Ultra',
        brand_name: 'TechBrand',
        category: 'Wearables',
        price: 349,
        color: 'Blue'
    },
    {
        _id: '5',
        title: 'Tablet Mini',
        brand_name: 'ComputeCo',
        category: 'Tablets',
        price: 499,
        color: 'Rose Gold'
    }
];

const Brand = () => {
    const [selectedCategories, setSelectedCategories] = useState([]);
    const [priceRange, setPriceRange] = useState([0, 1500]);
    const [selectedBrand, setSelectedBrand] = useState('');
    const [selectedColors, setSelectedColors] = useState([]);

    // Derived data
    const categories = [...new Set(initialProducts.map(p => p.category))];
    const brands = [...new Set(initialProducts.map(p => p.brand_name))];
    const colors = [...new Set(initialProducts.map(p => p.color))];

    // Filtering logic
    const filteredProducts = useMemo(() => {
        return initialProducts.filter(product => {
            // Category filter
            const categoryMatch =
                selectedCategories.length === 0 ||
                selectedCategories.includes(product.category);

            // Price range filter
            const priceMatch =
                product.price >= priceRange[0] &&
                product.price <= priceRange[1];

            // Brand filter
            const brandMatch =
                !selectedBrand ||
                product.brand_name === selectedBrand;

            // Color filter
            const colorMatch =
                selectedColors.length === 0 ||
                selectedColors.includes(product.color);

            return categoryMatch && priceMatch && brandMatch && colorMatch;
        });
    }, [selectedCategories, priceRange, selectedBrand, selectedColors]);

    // Category checkbox handler
    const handleCategoryToggle = (category) => {
        setSelectedCategories(prev =>
            prev.includes(category)
                ? prev.filter(c => c !== category)
                : [...prev, category]
        );
    };

    // Color checkbox handler
    const handleColorToggle = (color) => {
        setSelectedColors(prev =>
            prev.includes(color)
                ? prev.filter(c => c !== color)
                : [...prev, color]
        );
    };

    return (
        <div className='mt-36'>
            <div className="grid md:grid-cols-4 gap-6">
                {/* Categories Checkbox Filter */}
                <div className="border p-4 rounded">
                    <h3 className="font-semibold mb-2">Categories</h3>
                    {categories.map(category => (
                        <div key={category} className="flex items-center mb-2">
                            <input
                                type="checkbox"
                                id={category}
                                checked={selectedCategories.includes(category)}
                                onChange={() => handleCategoryToggle(category)}
                                className="mr-2"
                            />
                            <label htmlFor={category}>{category}</label>
                        </div>
                    ))}
                </div>

                {/* Price Range Slider */}
                <div className="border p-4 rounded">
                    <h3 className="font-semibold mb-2">Price Range</h3>
                    <div className="flex items-center space-x-4">
                        <span>${priceRange[0]}</span>
                        <input
                            type="range"
                            min="0"
                            max="1500"
                            color='red'
                            value={priceRange[1]}
                            onChange={(e) => setPriceRange([priceRange[0], Number(e.target.value)])}
                            className="flex-grow"
                        />
                        <span>${priceRange[1]}</span>
                    </div>
                    <div className="mt-2 text-sm text-gray-600">
                        Price: ${priceRange[0]} - ${priceRange[1]}
                    </div>
                </div>

                {/* Brand Select Dropdown */}
                <div className="border p-4 rounded">
                    <h3 className="font-semibold mb-2">Brand</h3>
                    <div className="relative">
                        <select
                            value={selectedBrand}
                            onChange={(e) => setSelectedBrand(e.target.value)}
                            className="w-full appearance-none border rounded p-2 pr-8"
                        >
                            <option value="">All Brands</option>
                            {brands.map(brand => (
                                <option key={brand} value={brand}>{brand}</option>
                            ))}
                        </select>
                    </div>
                </div>

                {/* Color Checkbox Filter */}
                <div className="border p-4 rounded">
                    <h3 className="font-semibold mb-2">Colors</h3>
                    {colors.map(color => (
                        <div key={color} className="flex items-center mb-2">
                            <input
                                type="checkbox"
                                id={color}
                                checked={selectedColors.includes(color)}
                                onChange={() => handleColorToggle(color)}
                                className="mr-2"
                            />
                            <label 
                                htmlFor={color} 
                                className="flex items-center"
                            >
                                <span 
                                    className="w-4 h-4 mr-2 rounded-full inline-block"
                                    style={{ backgroundColor: color.toLowerCase() }}
                                ></span>
                                {color}
                            </label>
                        </div>
                    ))}
                </div>
            </div>

            {/* Filtered Products Display */}
            <div className="mt-6">
                <h3 className="text-xl font-semibold mb-4">
                    Filtered Products ({filteredProducts.length})
                </h3>
                <div className="grid md:grid-cols-3 gap-4">
                    {filteredProducts.map(product => (
                        <div
                            key={product._id}
                            className="border p-4 rounded hover:shadow-md transition"
                        >
                            <h4 className="font-medium">{product.title}</h4>
                            <p className="text-gray-600">{product.brand_name}</p>
                            <div className="flex items-center mt-2">
                                <span 
                                    className="w-4 h-4 mr-2 rounded-full inline-block"
                                    style={{ backgroundColor: product.color.toLowerCase() }}
                                ></span>
                                <span>{product.color}</span>
                            </div>
                            <p className="font-bold">${product.price}</p>
                        </div>
                    ))}
                </div>
            </div>
        </div>
    )
}

export default Brand
downloadDownload PNG downloadDownload JPEG downloadDownload SVG

Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!

Click to optimize width for Twitter