dsg
Copy This
import {
    getDiscoverData
} from "./api/discover.js";
import store from "./store.js";

var $ = Dom7;

// let activeTab = 'all';
let lastSearchText = '';
let controller; // To store the current AbortController

var searchResultsStore = store.getters.getSearchResults;

$(document).on('page:afterin', '.page[data-name="search"]', async function (e) {
    $('#discover-search').focus();
})

// event listener for tab change
$(document).on('click', '.discovery-wrap .tab-link', async function (e) {
    const type = this.getAttribute('data-type')
    activeTab = type
})

function debounce(func, delay) {
    let timer;
    return function (...args) {
        clearTimeout(timer);
        timer = setTimeout(() => func.apply(this, args), delay);
    };
}

function addLoaderToTabs() {
    const eventsContainer = document.querySelector('#events-results .list ul');
    const usersContainer = document.querySelector('#users_vehicles-results .list ul');
    const venuesContainer = document.querySelector('#venues-results .list ul');
    const topContainer = document.querySelector('#top-results .list');

    const loader = `
    <div style="padding-block: .5rem;">
        <div class="infinite-scroll-preloader">
            <div class="preloader"></div>
        </div>
    </div>`;

    eventsContainer.innerHTML = loader;
    usersContainer.innerHTML = loader;
    venuesContainer.innerHTML = loader;
    topContainer.innerHTML = loader;
}

const debouncedSearch = debounce(async function () {
    const search = $(this).val().trim();

    if (search.length < 3 || search === lastSearchText) {
        return;
    }

    lastSearchText = search;

    // Abort the previous request if it's still ongoing
    if (controller) {
        controller.abort();
    }

    // Create a new AbortController for the current request
    controller = new AbortController();
    const signal = controller.signal;

    addLoaderToTabs();
    try {
        const searchResults = await getDiscoverData(search, 'all', 1, signal);
        store.dispatch('setSearchResults', searchResults);
    } catch (error) {
        if (error.name === 'AbortError') {
            console.log('Fetch aborted');
        } else {
            console.error('Error fetching search results:', error);
        }
    }
}, 300); // Adjust the delay (in milliseconds) as needed

$(document).on('change input paste', '#discover-search', debouncedSearch);

// Function to render a list of items in the DOM
function renderList(container, items, renderItem) {
    container.innerHTML = '';

    const noResultsMessage = '<li><strong>No results found</strong></li>';

    if (!items || items.length === 0) {
        container.innerHTML = noResultsMessage;
        return;
    }

    // Render each item
    items.forEach(item => {
        const li = document.createElement('li');
        li.innerHTML = renderItem(item);
        container.appendChild(li);
    });
}

// Function to render the search results
function renderSearchResults(searchResults) {
    const eventsContainer = document.querySelector('#events-results .list ul');
    const usersContainer = document.querySelector('#users_vehicles-results .list ul');
    const venuesContainer = document.querySelector('#venues-results .list ul');
    const topContainer = document.querySelector('#top-results .list');

    // Ensure containers are cleared before rendering
    eventsContainer.innerHTML = '';
    usersContainer.innerHTML = '';
    venuesContainer.innerHTML = '';
    topContainer.innerHTML = '';

    // Render events
    if (searchResults.events) {
        renderList(eventsContainer, searchResults.events.data, event => `
            <a class="item-link search-result item-content" href="/discover-view-event/${event.id}">
                <div class="item-media">
                    <div class="image-square image-rounded" style="background-image:url('${event.thumbnail}')"></div>
                </div>
                <div class="item-inner">
                    <div class="item-title">${event.name}</div>
                </div>
            </a>
        `);
    }

    // Render users
    if (searchResults.users) {
        renderList(usersContainer, searchResults.users.data, (user) => {
            const userLink = user.type == 'user' ? '/profile-view/' + user.id : '/profile-garage-vehicle-view/' + user.id;
            let contentText;

            if (user.type == 'user') {
                contentText = `${user.name} (${user.username})`;
            }

            if (user.type == 'vehicle') {
                contentText = `${user.name}'s <b>${user.meta.make} ${user.meta.model}</b>`;
            }

            return `
                <a class="item-link search-result item-content" href="${userLink}">
                    <div class="item-media">
                        <div class="image-square image-rounded" style="background-image:url('${user.thumbnail || 'assets/img/profile-placeholder.jpg'}')"></div>
                    </div>
                    <div class="item-inner">
                        <div class="item-title">${contentText}</div>
                    </div>
                </a>`
        });
    }

    // Render venues
    if (searchResults.venues) {
        renderList(venuesContainer, searchResults.venues.data, venue => `
            <a class="item-link search-result item-content" href="/discover-view-venue/${venue.id}">
                <div class="item-media">
                    <div class="image-square image-rounded" style="background-image:url('${venue.thumbnail}')"></div>
                </div>
                <div class="item-inner">
                    <div class="item-title">${venue.name} - ${venue.venue_location}</div>
                </div>
            </a>
        `);
    }

    // Render top results
    let hasTopResults = false;

    if (searchResults.top_results) {
        if (searchResults.top_results.events && searchResults.top_results.events.length > 0) {
            hasTopResults = true;
            const eventSubList = document.createElement('ul');
            const heading = document.createElement('h2');

            heading.innerHTML = 'Trending Events';
            heading.classList.add('section-title', 'mt-3', 'mb-2');
            topContainer.appendChild(heading);
            topContainer.appendChild(eventSubList);

            renderList(eventSubList, searchResults.top_results.events, event => `
                <a class="item-link search-result item-content" href="/discover-view-event/${event.id}">
                    <div class="item-media">
                        <div class="image-square image-rounded" style="background-image:url('${event.thumbnail}')"></div>
                    </div>
                    <div class="item-inner">
                        <div class="item-title">${event.name}</div>
                    </div>
                </a>
            `);
        }

        if (searchResults.top_results.users && searchResults.top_results.users.length > 0) {
            hasTopResults = true;

            const userSubList = document.createElement('ul');
            const heading = document.createElement('h2');

            heading.innerHTML = 'Trending Users';
            heading.classList.add('section-title', 'mt-3', 'mb-2');
            topContainer.appendChild(heading);
            topContainer.appendChild(userSubList);

            renderList(userSubList, searchResults.top_results.users, (user) => {
                const userLink = user.type == 'user' ? '/profile-view/' + user.id : '/profile-garage-vehicle-view/' + user.id;
                let contentText;

                if (user.type == 'user') {
                    contentText = `${user.name} (${user.username})`;
                }

                if (user.type == 'vehicle') {
                    contentText = `${user.name}'s <b>${user.meta.make} ${user.meta.model}</b>`;
                }

                return `
                <a class="item-link search-result item-content" href="${userLink}">
                    <div class="item-media">
                        <div class="image-square image-rounded" style="background-image:url('${user.thumbnail || 'assets/img/profile-placeholder.jpg'}')"></div>
                    </div>
                    <div class="item-inner">
                        <div class="item-title">${contentText}</div>
                    </div>
                </a>`
            });
        }

        if (searchResults.top_results.venues && searchResults.top_results.venues.length > 0) {
            hasTopResults = true;

            const venueSubList = document.createElement('ul');
            const heading = document.createElement('h2');

            heading.innerHTML = 'Trending Venues';
            heading.classList.add('section-title', 'mt-3', 'mb-2');

            topContainer.appendChild(heading);
            topContainer.appendChild(venueSubList);

            renderList(venueSubList, searchResults.top_results.venues, venue => `
                <a class="item-link search-result item-content" href="/discover-view-venue/${venue.id}">
                    <div class="item-media">
                        <div class="image-square image-rounded" style="background-image:url('${venue.thumbnail}')"></div>
                    </div>
                    <div class="item-inner">
                        <div class="item-title">${venue.name} - ${venue.venue_location}</div>
                    </div>
                </a>
            `);
        }
    }

    if (!hasTopResults) {
        topContainer.innerHTML = '<div><strong>No top results found</strong></div>';
    }
}

searchResultsStore.onUpdated((results) => {
    renderSearchResults(results);
});
Add JS Function Name