From 404375248b0d64cb36a576b6b1fc8e9f3e9e2ff0 Mon Sep 17 00:00:00 2001 From: Ruslan Bakiev <572431+veikab@users.noreply.github.com> Date: Sat, 24 Jan 2026 10:09:55 +0700 Subject: [PATCH] Fix catalog UI: navbar alignment, selection panel, map search, infinite scroll - Fix team selector alignment in navbar (use items-center, fixed height) - Fix SelectionPanel header padding to account for parent p-4 - Add map search input (white glass, positioned next to panel) - Add infinite scroll to SelectionPanel with IntersectionObserver - Products load all at once (no server-side pagination yet) - Hubs and Suppliers support pagination with loadMore --- app/components/catalog/SelectionPanel.vue | 47 ++++++++++++++++++-- app/components/navigation/MainNavigation.vue | 6 +-- app/components/page/CatalogPage.vue | 26 +++++++++++ app/composables/useCatalogProducts.ts | 11 +++++ app/pages/catalog/index.vue | 32 +++++++++++-- i18n/locales/en/catalog.json | 3 +- i18n/locales/ru/catalog.json | 3 +- 7 files changed, 117 insertions(+), 11 deletions(-) diff --git a/app/components/catalog/SelectionPanel.vue b/app/components/catalog/SelectionPanel.vue index 3c9f5f6..85f4639 100644 --- a/app/components/catalog/SelectionPanel.vue +++ b/app/components/catalog/SelectionPanel.vue @@ -1,7 +1,7 @@ + + +
+ +
@@ -85,16 +94,48 @@ const props = defineProps<{ suppliers?: Item[] selectedId?: string loading?: boolean + loadingMore?: boolean + hasMore?: boolean }>() const emit = defineEmits<{ 'select': [type: string, item: Item] 'close': [] + 'load-more': [] }>() const { t } = useI18n() const searchQuery = ref('') +const loadMoreSentinel = ref(null) + +// Infinite scroll using IntersectionObserver +let observer: IntersectionObserver | null = null + +onMounted(() => { + observer = new IntersectionObserver( + (entries) => { + const entry = entries[0] + if (entry?.isIntersecting && props.hasMore && !props.loadingMore && !searchQuery.value) { + emit('load-more') + } + }, + { threshold: 0.1 } + ) +}) + +watch(loadMoreSentinel, (el) => { + if (el && observer) { + observer.observe(el) + } +}) + +onUnmounted(() => { + if (observer) { + observer.disconnect() + observer = null + } +}) const title = computed(() => { switch (props.selectMode) { diff --git a/app/components/navigation/MainNavigation.vue b/app/components/navigation/MainNavigation.vue index 2e7d039..d04dc0d 100644 --- a/app/components/navigation/MainNavigation.vue +++ b/app/components/navigation/MainNavigation.vue @@ -143,8 +143,8 @@ - -
+ +
+ + +