import {defineStore} from "pinia"; import ftch from "@/utils/ftch.js"; import {YA_METRIKA_GOAL} from "@/constants/yaMetrikaGoals.js"; import {useYaMetrikaStore} from "@/stores/yaMetrikaStore.js"; import {toRaw} from "vue"; export const useSearchStore = defineStore('search', { state: () => ({ search: '', page: 1, products: { data: [], meta: {}, }, isLoading: false, isLoadingMore: false, isSearchPerformed: false, hasMore: false, // Placeholder товары для пустого состояния поиска placeholderProducts: { data: [], total: 0, }, isLoadingPlaceholder: false, }), actions: { reset() { this.search = ''; this.isSearchPerformed = false; this.isLoading = false; this.page = 1; this.products = { data: [], meta: {}, }; }, async fetchProducts(search, page = 1, perPage = 5) { return await ftch('products', null, { page, perPage: perPage, search, }); }, async performSearch() { if (!this.search) { return this.reset(); } useYaMetrikaStore().reachGoal(YA_METRIKA_GOAL.PERFORM_SEARCH, { keyword: this.search, }); try { this.page = 1; this.isLoading = true; const response = await this.fetchProducts(this.search, this.page, 10); console.debug('[Search] Perform Search: ', response); this.products = response; this.hasMore = response?.meta?.hasMore || false; } catch (error) { console.error(error); } finally { this.isLoading = false; this.isSearchPerformed = true; } }, async loadMore() { try { if (this.isLoading === true || this.isLoadingMore === true || this.hasMore === false) return; this.isLoadingMore = true; this.page++; const data = toRaw({ page: this.page, perPage: 10, search: this.search, }); console.debug('[Search] Loading more products: ', data); const response = await ftch('products', null, data); console.debug('[Search] Search results: ', response); this.products.data.push(...response.data); this.products.meta = response.meta; this.hasMore = response.meta.hasMore; } catch (error) { console.error(error); } finally { this.isLoading = false; this.isLoadingMore = false; this.isSearchPerformed = true; } }, async loadSearchPlaceholder() { // Если данные уже есть в store, возвращаем их if (this.placeholderProducts.data.length > 0) { return { data: this.placeholderProducts.data, meta: { total: this.placeholderProducts.total, }, }; } try { this.isLoadingPlaceholder = true; // Иначе загружаем с сервера const response = await ftch('productsSearchPlaceholder'); this.placeholderProducts.data = response.data.slice(0, 3); this.placeholderProducts.total = response?.meta?.total || 0; return { data: this.placeholderProducts.data, meta: { total: this.placeholderProducts.total, }, }; } finally { this.isLoadingPlaceholder = false; } }, }, });