diff --git a/client-app/router/routes/constants.ts b/client-app/router/routes/constants.ts index dc1157e846..f6c75cc2d0 100644 --- a/client-app/router/routes/constants.ts +++ b/client-app/router/routes/constants.ts @@ -1,11 +1,10 @@ -type RouteType = { - NAME: string; - PATH: string; -}; - -export const ROUTES: { [key: string]: RouteType } = { +export const ROUTES = { CATALOG: { NAME: "Catalog", PATH: "/catalog", }, + SEARCH: { + NAME: "Search", + PATH: "/search", + }, } as const; diff --git a/client-app/router/routes/main.ts b/client-app/router/routes/main.ts index 7f80b8f21e..af0d65168b 100644 --- a/client-app/router/routes/main.ts +++ b/client-app/router/routes/main.ts @@ -63,7 +63,7 @@ export const mainRoutes: RouteRecordRaw[] = [ }, }, { path: "/branch/:branchId", name: "BranchPage", component: Branch, props: true }, - { path: "/search", name: "Search", component: Search }, + { path: ROUTES.SEARCH.PATH, name: ROUTES.SEARCH.NAME, component: Search }, { path: "/bulk-order", name: "BulkOrder", component: BulkOrder }, { path: "/compare", name: "CompareProducts", component: CompareProducts }, { path: "/cart", name: "Cart", component: Cart }, diff --git a/client-app/shared/layout/components/header/_internal/mobile-header.vue b/client-app/shared/layout/components/header/_internal/mobile-header.vue index 714ae22e55..174a32bdb8 100644 --- a/client-app/shared/layout/components/header/_internal/mobile-header.vue +++ b/client-app/shared/layout/components/header/_internal/mobile-header.vue @@ -87,11 +87,15 @@ maxlength="64" :placeholder="$t('shared.layout.header.mobile.search_bar.input_placeholder')" class="mr-4 grow" + :clearable="!!searchPhrase" no-border - clearable - @keydown.enter="searchPhrase && $router.push(searchPageLink)" @clear="reset" - /> + @keydown.enter="searchPhrase && $router.push(searchPageLink)" + > + + @@ -137,6 +141,7 @@ import { useSearchBar } from "@/shared/layout/composables/useSearchBar"; import MobileMenu from "./mobile-menu/mobile-menu.vue"; import type { StyleValue } from "vue"; import type { RouteLocationRaw } from "vue-router"; +import BarcodeScanner from "@/shared/layout/components/search-bar/barcode-scanner.vue"; const router = useRouter(); const { customComponents } = useCustomMobileHeaderComponents(); @@ -158,7 +163,7 @@ const placeholderStyle = computed(() => ); const searchPageLink = computed(() => ({ - name: "Search", + name: ROUTES.SEARCH.NAME, query: { [QueryParamName.SearchPhrase]: searchPhrase.value.trim(), }, @@ -166,7 +171,14 @@ const searchPageLink = computed(() => ({ function reset() { searchPhrase.value = ""; - void router.push({ name: ROUTES.CATALOG.NAME }); + void router.push({ name: ROUTES.SEARCH.NAME }); +} + +function onBarcodeScanned(value: string) { + if (value) { + searchPhrase.value = value; + void router.push(searchPageLink.value); + } } syncRefs(mobileMenuVisible, useScrollLock(document.body)); diff --git a/client-app/shared/layout/components/search-bar/barcode-scanner-modal.vue b/client-app/shared/layout/components/search-bar/barcode-scanner-modal.vue new file mode 100644 index 0000000000..c4ed37cb2e --- /dev/null +++ b/client-app/shared/layout/components/search-bar/barcode-scanner-modal.vue @@ -0,0 +1,212 @@ + + + + + diff --git a/client-app/shared/layout/components/search-bar/barcode-scanner.vue b/client-app/shared/layout/components/search-bar/barcode-scanner.vue new file mode 100644 index 0000000000..98cb4ade33 --- /dev/null +++ b/client-app/shared/layout/components/search-bar/barcode-scanner.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/client-app/shared/layout/components/search-bar/search-bar.vue b/client-app/shared/layout/components/search-bar/search-bar.vue index 8019ff6b89..31cf72bf28 100644 --- a/client-app/shared/layout/components/search-bar/search-bar.vue +++ b/client-app/shared/layout/components/search-bar/search-bar.vue @@ -5,15 +5,17 @@ type="search" :maxlength="MAX_LENGTH" class="w-full" + :clearable="!!searchPhrase" :placeholder="$t('shared.layout.search_bar.enter_keyword_placeholder')" - clearable + @clear="reset" @keyup.enter="goToSearchResultsPage" @keyup.esc="hideSearchDropdown" @input="onSearchPhraseChanged" @focus="onSearchBarFocused" - @clear="reset" >