Some checks failed
Telegram Mini App Shop Builder / Compute version metadata (push) Has been cancelled
Telegram Mini App Shop Builder / Run Frontend tests (push) Has been cancelled
Telegram Mini App Shop Builder / Run Backend tests (push) Has been cancelled
Telegram Mini App Shop Builder / Run PHP_CodeSniffer (push) Has been cancelled
Telegram Mini App Shop Builder / Build module. (push) Has been cancelled
Telegram Mini App Shop Builder / release (push) Has been cancelled
133 lines
4.1 KiB
JavaScript
133 lines
4.1 KiB
JavaScript
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;
|
||
}
|
||
},
|
||
},
|
||
|
||
});
|