@@ -75,7 +49,7 @@
import NoProducts from "@/components/NoProducts.vue";
import ProductImageSwiper from "@/components/ProductImageSwiper.vue";
import {useProductsStore} from "@/stores/ProductsStore.js";
-import {useDebounceFn, useInfiniteScroll} from '@vueuse/core';
+import {useInfiniteScroll} from '@vueuse/core';
import {useRoute} from "vue-router";
import {useSettingsStore} from "@/stores/SettingsStore.js";
import {nextTick, onMounted, onUnmounted, ref, watch} from "vue";
@@ -85,12 +59,6 @@ const categoryId = route.params.category_id ?? null;
const productsStore = useProductsStore();
const settings = useSettingsStore();
const bottom = ref(null);
-const debounceMs = 500;
-
-const debouncedSearch = useDebounceFn(() => {
- productsStore.reset();
- loadMore();
-}, debounceMs);
function haptic() {
window.Telegram.WebApp.HapticFeedback.selectionChanged();
diff --git a/spa/src/components/SearchInput.vue b/spa/src/components/SearchInput.vue
new file mode 100644
index 0000000..e97572a
--- /dev/null
+++ b/spa/src/components/SearchInput.vue
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
diff --git a/spa/src/main.js b/spa/src/main.js
index 1879df4..c80a768 100644
--- a/spa/src/main.js
+++ b/spa/src/main.js
@@ -15,6 +15,7 @@ import {injectYaMetrika} from "@/utils/yaMetrika.js";
import { register } from 'swiper/element/bundle';
import 'swiper/element/bundle';
import 'swiper/css/bundle';
+import AppLoading from "@/AppLoading.vue";
register();
const pinia = createPinia();
@@ -26,6 +27,9 @@ app
const settings = useSettingsStore();
+const appLoading = createApp(AppLoading);
+appLoading.mount('#app');
+
settings.load()
.then(() => {
if (settings.app_enabled === false) {
@@ -33,6 +37,7 @@ settings.load()
}
})
.then(() => {
+ console.log('Set theme attributes');
document.documentElement.setAttribute('data-theme', settings.theme[window.Telegram.WebApp.colorScheme]);
if (settings.night_auto) {
window.Telegram.WebApp.onEvent('themeChanged', function () {
@@ -41,12 +46,13 @@ settings.load()
}
})
.then(() => {
+ console.log('Load front page categories and products.');
const categoriesStore = useCategoriesStore();
categoriesStore.fetchTopCategories();
categoriesStore.fetchCategories();
})
.then(() => new AppMetaInitializer(settings).init())
- .then(() => app.mount('#app'))
+ .then(() => { appLoading.unmount(); app.mount('#app'); })
.then(() => window.Telegram.WebApp.ready())
.then(() => settings.ya_metrika_enabled && injectYaMetrika())
.catch(error => {
diff --git a/spa/src/router.js b/spa/src/router.js
index 8d35db2..d98d7eb 100644
--- a/spa/src/router.js
+++ b/spa/src/router.js
@@ -6,6 +6,7 @@ import Cart from "./views/Cart.vue";
import Products from "@/views/Products.vue";
import Checkout from "@/views/Checkout.vue";
import OrderCreated from "@/views/OrderCreated.vue";
+import Search from "@/views/Search.vue";
const routes = [
{path: '/', name: 'home', component: Home},
@@ -16,6 +17,7 @@ const routes = [
{path: '/cart', name: 'cart', component: Cart},
{path: '/checkout', name: 'checkout', component: Checkout},
{path: '/success', name: 'order_created', component: OrderCreated},
+ {path: '/search', name: 'search', component: Search},
];
export const router = createRouter({
diff --git a/spa/src/stores/ProductsStore.js b/spa/src/stores/ProductsStore.js
index a438b5c..11ad84e 100644
--- a/spa/src/stores/ProductsStore.js
+++ b/spa/src/stores/ProductsStore.js
@@ -37,6 +37,7 @@ export const useProductsStore = defineStore('products', {
this.page = 1;
this.hasMore = true;
this.loadFinished = false;
+ this.search = '';
this.products = {
data: [],
meta: {},
diff --git a/spa/src/stores/SearchStore.js b/spa/src/stores/SearchStore.js
new file mode 100644
index 0000000..17caebd
--- /dev/null
+++ b/spa/src/stores/SearchStore.js
@@ -0,0 +1,51 @@
+import {defineStore} from "pinia";
+import ftch from "@/utils/ftch.js";
+
+export const useSearchStore = defineStore('search', {
+
+ state: () => ({
+ search: '',
+ page: 1,
+ products: {
+ data: [],
+ meta: {},
+ },
+
+ isLoading: false,
+ isSearchPerformed: false,
+ }),
+
+ actions: {
+ reset() {
+ this.search = '';
+ this.isSearchPerformed = false;
+ this.isLoading = false;
+ this.page = 1;
+ this.products = {
+ data: [],
+ meta: {},
+ };
+ },
+
+ async performSearch() {
+ if (!this.search) {
+ return this.reset();
+ }
+
+ try {
+ this.isLoading = true;
+ this.products = await ftch('products', {
+ page: this.page,
+ perPage: 10,
+ search: this.search,
+ });
+ } catch (error) {
+ console.error(error);
+ } finally {
+ this.isLoading = false;
+ this.isSearchPerformed = true;
+ }
+ },
+ },
+
+});
diff --git a/spa/src/stores/SettingsStore.js b/spa/src/stores/SettingsStore.js
index b3dfe9a..0d9af1a 100644
--- a/spa/src/stores/SettingsStore.js
+++ b/spa/src/stores/SettingsStore.js
@@ -22,6 +22,7 @@ export const useSettingsStore = defineStore('settings', {
actions: {
async load() {
+ console.log('Load settings');
const settings = await fetchSettings();
this.manifest_url = settings.manifest_url;
this.app_name = settings.app_name;
diff --git a/spa/src/utils/AppMetaInitializer.ts b/spa/src/utils/AppMetaInitializer.ts
index b220f3f..8fadab9 100644
--- a/spa/src/utils/AppMetaInitializer.ts
+++ b/spa/src/utils/AppMetaInitializer.ts
@@ -6,6 +6,7 @@ class AppMetaInitializer {
}
public init() {
+ console.log('Init app meta');
document.title = this.settings.app_name;
this.setMeta('application-name', this.settings.app_name);
this.setMeta('apple-mobile-web-app-title', this.settings.app_name);
diff --git a/spa/src/views/Home.vue b/spa/src/views/Home.vue
index 4c4f5e9..ca0b998 100644
--- a/spa/src/views/Home.vue
+++ b/spa/src/views/Home.vue
@@ -1,6 +1,7 @@
@@ -8,4 +9,5 @@
diff --git a/spa/src/views/Search.vue b/spa/src/views/Search.vue
new file mode 100644
index 0000000..b786806
--- /dev/null
+++ b/spa/src/views/Search.vue
@@ -0,0 +1,96 @@
+
+
+
Поиск
+
+
+
+
+
+
+
+
![]()
+
+
+
+
+
{{ product.name }}
+
{{ product.price }}
+
+
+
+
+
+
+
+
🛒
+
Товары не найдены
+
Попробуйте изменить или уточнить запрос
+
+
+
+
+