Polish marketplace search states

This commit is contained in:
sdarbinyan
2026-07-05 01:10:56 +04:00
parent 3974eefbfe
commit 3f5aa2af2a
6 changed files with 43 additions and 6 deletions

View File

@@ -131,6 +131,7 @@ export const en: Translations = {
loadingMore: 'Loading...',
allLoaded: 'All results loaded',
emptyState: 'Enter a query to search for products',
minLength: 'Enter at least {{count}} characters to search',
of: 'of',
},
category: {

View File

@@ -131,6 +131,7 @@ export const hy: Translations = {
loadingMore: 'Բեռնում...',
allLoaded: 'Բոլոր արդյունքները բեռնված են',
emptyState: 'Մուտքագրեք հարցում որոնման համար',
minLength: 'Որոնման համար մուտքագրեք առնվազն {{count}} նիշ',
of: '-ից',
},
category: {

View File

@@ -131,6 +131,7 @@ export const ru: Translations = {
loadingMore: 'Загрузка...',
allLoaded: 'Все результаты загружены',
emptyState: 'Введите запрос для поиска товаров',
minLength: 'Введите минимум {{count}} символа для поиска',
of: 'из',
},
category: {

View File

@@ -129,6 +129,7 @@ export interface Translations {
loadingMore: string;
allLoaded: string;
emptyState: string;
minLength: string;
of: string;
};
category: {

View File

@@ -39,11 +39,23 @@
</div>
}
@if (!loading() && searchQuery && items().length === 0 && !error()) {
@if (isQueryTooShort()) {
<div class="empty-state">
<div class="empty-state-icon">
<svg width="56" height="56" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4ZM2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12Z" fill="#d3dad9" />
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.2929 18.2929C18.6834 17.9024 19.3166 17.9024 19.7071 18.2929L25.7071 24.2929C26.0976 24.6834 26.0976 25.3166 25.7071 25.7071C25.3166 26.0976 24.6834 26.0976 24.2929 25.7071L18.2929 19.7071C17.9024 19.3166 17.9024 18.6834 18.2929 18.2929Z" fill="#d3dad9" />
</svg>
</div>
<p>{{ 'search.minLength' | translate:{ count: minSearchLength } }}</p>
</div>
}
@if (!loading() && searchQuery && !isQueryTooShort() && items().length === 0 && !error()) {
<div class="no-results">
<div class="no-results-icon">
<svg width="48" height="48" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4ZZ2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12Z" fill="#a1b4b5" />
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4ZM2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12Z" fill="#a1b4b5" />
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.2929 18.2929C18.6834 17.9024 19.3166 17.9024 19.7071 18.2929L25.7071 24.2929C26.0976 24.6834 26.0976 25.3166 25.7071 25.7071C25.3166 26.0976 24.6834 26.0976 24.2929 25.7071L18.2929 19.7071C17.9024 19.3166 17.9024 18.6834 18.2929 18.2929Z" fill="#a1b4b5" />
</svg>
</div>

View File

@@ -21,6 +21,7 @@ import { ProductCardComponent } from '../../components/product-card/product-card
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SearchComponent implements OnDestroy {
readonly minSearchLength = 3;
searchQuery = '';
items = signal<Item[]>([]);
loading = signal(false);
@@ -60,17 +61,23 @@ export class SearchComponent implements OnDestroy {
onSearchInput(query: string): void {
this.searchQuery = query;
this.error.set(null);
if (this.isQueryTooShort()) {
this.resetSearchState();
return;
}
this.searchSubject.next(query);
}
performSearch(query: string): void {
if (!query.trim()) {
this.items.set([]);
this.hasMore.set(false);
this.totalResults.set(0);
this.resetSearchState();
return;
}
this.error.set(null);
this.items.set([]);
this.skip = 0;
this.hasMore.set(true);
@@ -84,7 +91,7 @@ export class SearchComponent implements OnDestroy {
this.loading.set(true);
this.isLoadingMore = true;
this.productFacade.searchProducts({ search: this.searchQuery, count: this.count, skip: this.skip }).subscribe({
this.productFacade.searchProducts({ search: this.searchQuery.trim(), count: this.count, skip: this.skip }).subscribe({
next: (response) => {
// Update total results (only on first load)
if (this.skip === 0) {
@@ -114,6 +121,20 @@ export class SearchComponent implements OnDestroy {
});
}
private resetSearchState(): void {
this.items.set([]);
this.loading.set(false);
this.hasMore.set(false);
this.totalResults.set(0);
this.skip = 0;
this.isLoadingMore = false;
}
isQueryTooShort(): boolean {
const length = this.searchQuery.trim().length;
return length > 0 && length < this.minSearchLength;
}
private scrollTimeout?: ReturnType<typeof setTimeout>;
@HostListener('window:scroll')