schon/storefront/composables/search/useSearchUi.ts
Alexandr SaVBaD Waltz 64730a1d4e Features: 1) Add appStore integration for managing search overlay state in search.vue; 2) Enhance expiration date formatting in promocodes.vue with detailed and localized time display; 3) Replace avatar image handling in settings.vue with nuxt-img for better performance and format support;
Fixes: 1) Add missing type annotations for `isSearchActive` in `useSearchUi.ts`; 2) Resolve improper conditional rendering in empty state templates across multiple files; 3) Remove unnecessary `console.log` calls in `goTo` function;

Extra: 1) Update SCSS styles including border thickness, colors, and padding tweaks; 2) Refactor `loader.vue` to use `<span>` instead of `<li>` for dots and adjust size; 3) Clean up obsolete TODOs, comments, and unused imports.
2025-07-15 21:25:51 +10:00

66 lines
No EOL
1.6 KiB
TypeScript

import { computed, ref, watch } from 'vue';
import { useSearch } from './useSearch.js';
import { useDebounceFn } from '@vueuse/core';
export function useSearchUI() {
const query = ref('');
const isSearchActive = ref<boolean>(false);
const { search, loading, searchResults } = useSearch();
const filteredSearchResults = computed(() => {
if (!searchResults.value) return {};
return Object.entries(searchResults.value)
.reduce<Record<string, any[]>>((acc, [category, blocks]) => {
if (Array.isArray(blocks) && blocks.length > 0) {
acc[category] = blocks;
}
return acc;
}, {});
});
const hasResults = computed(() => {
if (!searchResults.value) return false;
return Object.values(searchResults.value).some(
(blocks) => Array.isArray(blocks) && blocks.length > 0
);
});
function getBlockTitle(category: string) {
return category.charAt(0).toUpperCase() + category.slice(1);
}
function clearSearch() {
query.value = '';
searchResults.value = null;
}
function toggleSearch(value: boolean) {
isSearchActive.value = value !== undefined ? value : !isSearchActive.value;
}
const debouncedSearch = useDebounceFn(async () => {
if (query.value) {
await search(query.value);
} else {
searchResults.value = null;
}
}, 750);
watch(() => query.value, async () => {
await debouncedSearch();
}, { immediate: false });
return {
query,
isSearchActive,
loading,
searchResults,
filteredSearchResults,
hasResults,
getBlockTitle,
clearSearch,
toggleSearch
};
}