File size: 5,236 Bytes
3105a9a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
document.addEventListener('DOMContentLoaded', () => {
    const productGrid = document.getElementById('product-grid');
    const loader = document.getElementById('loader');
    let products = [];

    // Cart State
    let cartCount = 0;

    // --- Event Listeners for Filters ---
    document.getElementById('filter-all').addEventListener('click', () => filterProducts('all'));
    document.getElementById('filter-tech').addEventListener('click', () => filterProducts('tech'));
    document.getElementById('filter-design').addEventListener('click', () => filterProducts('design'));

    // --- Function: Fetch Data ---
    async function loadProducts() {
        // Show Loader
        loader.style.display = 'flex';
        productGrid.innerHTML = '';

        try {
            // Attempt to fetch from local data.json file
            const response = await fetch('data.json');
            if (!response.ok) throw new Error("HTTP error");
            products = await response.json();
        } catch (error) {
            console.warn('Could not load data.json (likely due to CORS on local file system). Using fallback data.', error);
            // Fallback Data if JSON fetch fails
            products = [
                { id: 1, name: "Wireless Headphones", price: 299, category: "tech", image: "http://static.photos/technology/640x360/1", rating: 4.8 },
                { id: 2, name: "Mechanical Keyboard", price: 149, category: "tech", image: "http://static.photos/workspace/640x360/2", rating: 4.7 },
                { id: 3, name: "Modern Lamp", price: 89, category: "design", image: "http://static.photos/interior/640x360/3", rating: 4.5 },
                { id: 4, name: "Smart Watch", price: 399, category: "tech", image: "http://static.photos/technology/640x360/6", rating: 4.6 }
            ];
        } finally {
            // Hide Loader
            loader.style.display = 'none';
            renderProducts(products);
        }
    }

    // --- Function: Render Products ---
    function renderProducts(items) {
        productGrid.innerHTML = '';
        
        items.forEach(product => {
            const card = document.createElement('shop-card');
            // Set attributes for the web component
            card.setAttribute('name', product.name);
            card.setAttribute('price', product.price);
            card.setAttribute('category', product.category);
            card.setAttribute('image', product.image);
            card.setAttribute('rating', product.rating);
            
            productGrid.appendChild(card);
        });
    }

    // --- Function: Filter Products ---
    function filterProducts(category) {
        // Update active button styles
        const buttons = document.querySelectorAll('button[id^="filter-"]');
        buttons.forEach(btn => {
            if (btn.id === `filter-${category}`) {
                btn.classList.remove('bg-white', 'text-gray-600');
                btn.classList.add('bg-primary', 'text-white');
            } else {
                btn.classList.remove('bg-primary', 'text-white');
                btn.classList.add('bg-white', 'text-gray-600');
            }
        });

        if (category === 'all') {
            renderProducts(products);
        } else {
            const filtered = products.filter(p => p.category === category);
            renderProducts(filtered);
        }
    }

    // --- Global Event Listener: Add to Cart ---
    // We listen for a custom event dispatched from inside the Shadow DOM of the Web Component
    window.addEventListener('add-to-cart', (e) => {
        cartCount++;
        updateCartDisplay();
        showToast(`Added ${e.detail.productName} to cart!`);
    });

    // --- Global Event Listener: Remove Product ---
    window.addEventListener('remove-product', (e) => {
        const card = e.detail.element;
        card.style.opacity = '0';
        card.style.transform = 'scale(0.9)';
        setTimeout(() => {
            card.remove();
        }, 300);
        showToast('Product removed.');
    });

    function updateCartDisplay() {
        // We dispatch an event to the navbar since we can't easily access its shadow DOM internals directly
        window.dispatchEvent(new CustomEvent('update-cart-count', { 
            detail: { count: cartCount } 
        }));
    }

    // --- Function: Show Toast Notification ---
    function showToast(message) {
        const container = document.getElementById('toast-container');
        const toast = document.createElement('div');
        toast.className = 'toast-enter bg-dark text-white px-6 py-3 rounded-lg shadow-xl flex items-center gap-3';
        toast.innerHTML = `
            <i data-feather="check-circle" class="text-green-400"></i>
            <span class="font-medium">${message}</span>
        `;
        
        container.appendChild(toast);
        feather.replace(); // Refresh icons in new element

        // Remove after 3 seconds
        setTimeout(() => {
            toast.classList.remove('toast-enter');
            toast.classList.add('toast-exit');
            setTimeout(() => {
                toast.remove();
            }, 300);
        }, 3000);
    }

    // Initialize
    loadProducts();
});