PageSourceSearch

https://vibeotter-5690a.firebaseapp.com/js/showcase-filter.js?v=1790948744

js vibeotter-5690a.firebaseapp.com collected 2026-10-03 14:08:17 UTC 4,417 bytes, 111 lines download raw bytes

1// Showcase filter functionality for filtering example sites by category
2document.addEventListener('DOMContentLoaded', function() {
3    const filterButtons = document.querySelectorAll('.showcase-filter-btn');
4    const examplesGrid = document.querySelector('.examples-grid');
5
6    if (!filterButtons.length || !examplesGrid) return; // Exit if elements not found
7
8    // Map data-filter values to showcaseSites keys
9    const filterToConfigKey = {
10        'default': 'default',
11        'small-business': 'smallBusiness',
12        'nonprofit': 'nonprofit',
13        'personal': 'personal'
14    };
15
16    // Map config keys to image folder names
17    const configKeyToFolder = {
18        'default': 'default',
19        'smallBusiness': 'small-business',
20        'nonprofit': 'nonprofit',
21        'personal': 'personal'
22    };
23
24    // Build a single card HTML string
25    function buildCardHTML(site, category) {
26        const folderName = configKeyToFolder[category] || category;
27        return `
28            <div class="example-card">
29                <a href="${site.url}" target="_blank" rel="noopener" class="preview-link">
30                    <div class="example-iframe-container">
31                        <div class="site-preview">
32                            <img src="/images/previews/${folderName}/${site.image}" alt="${site.name} website" class="preview-image" loading="lazy">
33                            <div class="preview-overlay">
34                                <span>Visit Site →</span>
35                            </div>
36                        </div>
37                    </div>
38                </a>
39                <div class="example-info">
40                    <h4 class="example-site-title">${site.name}</h4>
41                    <a href="${site.url}" target="_blank" rel="noopener">View Site →</a>
42                    <a href="#" class="use-template-btn" data-analytics-event="template" data-site="${site.url}">Use as template →</a>
43                </div>
44            </div>
45        `;
46    }
47
48    // Attach click handlers to "Use as template" buttons
49    function attachTemplateHandlers() {
50        const templateButtons = examplesGrid.querySelectorAll('.use-template-btn');
51        templateButtons.forEach(function(btn) {
52            btn.addEventListener('click', function(e) {
53                e.preventDefault();
54                const siteUrl = this.getAttribute('data-site');
55                if (siteUrl) {
56                    const inputBar = document.querySelector('#homepage-input-bar textarea, #homepage-input-bar input');
57                    if (inputBar) {
58                        inputBar.value = 'Replicate this website ' + siteUrl;
59                        inputBar.focus();
60                        inputBar.dispatchEvent(new Event('input', { bubbles: true }));
61                        window.scrollTo({ top: 0, behavior: 'smooth' });
62                    }
63                }
64            });
65        });
66    }
67
68    // Rebuild the grid with sites from the specified category
69    function rebuildGrid(category) {
70        if (typeof showcaseSites === 'undefined' || !showcaseSites[category]) {
71            console.warn('showcaseSites not found or category missing:', category);
72            return;
73        }
74
75        const sites = showcaseSites[category];
76        let html = '';
77        sites.forEach(function(site) {
78            html += buildCardHTML(site, category);
79        });
80
81        examplesGrid.innerHTML = html;
82        attachTemplateHandlers();
83    }
84
85    // Handle filter button clicks
86    filterButtons.forEach(function(btn) {
87        btn.addEventListener('click', function() {
88            const filterType = this.getAttribute('data-filter');
89            const configKey = filterToConfigKey[filterType] || 'default';
90
91            // Update active state on buttons
92            filterButtons.forEach(function(b) {
93                b.classList.remove('active');
94            });
95            this.classList.add('active');
96
97            // Fade out current cards
98            examplesGrid.style.transition = 'opacity 0.3s ease';
99            examplesGrid.style.opacity = '0';
100
101            // After fade out, rebuild and fade in
102            setTimeout(function() {
103                rebuildGrid(configKey);
104                examplesGrid.style.opacity = '1';
105            }, 300);
106        });
107    });
108
109    // Attach handlers to initial template buttons on page load
110    attachTemplateHandlers();
111});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.