2026-01-19 23:17:07 +04:00
|
|
|
<div class="items-list-container">
|
|
|
|
|
<mat-toolbar color="primary" class="list-toolbar">
|
|
|
|
|
<button mat-icon-button (click)="goBack()">
|
|
|
|
|
<mat-icon>arrow_back</mat-icon>
|
|
|
|
|
</button>
|
2026-02-20 01:25:29 +04:00
|
|
|
<span class="toolbar-title">{{ subcategoryName() || 'Items' }}</span>
|
2026-01-19 23:17:07 +04:00
|
|
|
<span class="toolbar-spacer"></span>
|
|
|
|
|
<button mat-mini-fab color="accent" (click)="addItem()">
|
|
|
|
|
<mat-icon>add</mat-icon>
|
|
|
|
|
</button>
|
|
|
|
|
</mat-toolbar>
|
|
|
|
|
|
|
|
|
|
<div class="filters-bar">
|
|
|
|
|
<mat-form-field appearance="outline" class="search-field">
|
2026-02-20 09:01:02 +04:00
|
|
|
<mat-label>{{ 'SEARCH_ITEMS' | translate }}</mat-label>
|
2026-01-19 23:17:07 +04:00
|
|
|
<input
|
|
|
|
|
matInput
|
|
|
|
|
[(ngModel)]="searchQuery"
|
|
|
|
|
(keyup.enter)="onSearch()"
|
2026-02-20 09:01:02 +04:00
|
|
|
[placeholder]="'SEARCH_PLACEHOLDER' | translate">
|
2026-01-19 23:17:07 +04:00
|
|
|
<button mat-icon-button matSuffix (click)="onSearch()">
|
|
|
|
|
<mat-icon>search</mat-icon>
|
|
|
|
|
</button>
|
|
|
|
|
</mat-form-field>
|
|
|
|
|
|
|
|
|
|
<mat-form-field appearance="outline" class="filter-field">
|
2026-02-20 09:01:02 +04:00
|
|
|
<mat-label>{{ 'VISIBILITY' | translate }}</mat-label>
|
2026-01-19 23:17:07 +04:00
|
|
|
<mat-select [(ngModel)]="visibilityFilter" (selectionChange)="onFilterChange()">
|
2026-02-20 09:01:02 +04:00
|
|
|
<mat-option [value]="undefined">{{ 'ALL' | translate }}</mat-option>
|
|
|
|
|
<mat-option [value]="true">{{ 'VISIBLE' | translate }}</mat-option>
|
|
|
|
|
<mat-option [value]="false">{{ 'HIDDEN' | translate }}</mat-option>
|
2026-01-19 23:17:07 +04:00
|
|
|
</mat-select>
|
|
|
|
|
</mat-form-field>
|
|
|
|
|
|
|
|
|
|
@if (selectedItems().size > 0) {
|
|
|
|
|
<div class="bulk-actions">
|
2026-02-20 09:01:02 +04:00
|
|
|
<span class="selection-count">{{ selectedItems().size }} {{ 'SELECTED' | translate }}</span>
|
2026-01-19 23:17:07 +04:00
|
|
|
<button mat-raised-button (click)="bulkToggleVisibility(true)">
|
|
|
|
|
<mat-icon>visibility</mat-icon>
|
2026-02-20 09:01:02 +04:00
|
|
|
{{ 'SHOW' | translate }}
|
2026-01-19 23:17:07 +04:00
|
|
|
</button>
|
|
|
|
|
<button mat-raised-button (click)="bulkToggleVisibility(false)">
|
|
|
|
|
<mat-icon>visibility_off</mat-icon>
|
2026-02-20 09:01:02 +04:00
|
|
|
{{ 'HIDE' | translate }}
|
2026-01-19 23:17:07 +04:00
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="items-header">
|
|
|
|
|
<mat-checkbox
|
|
|
|
|
[checked]="selectedItems().size === items().length && items().length > 0"
|
|
|
|
|
[indeterminate]="selectedItems().size > 0 && selectedItems().size < items().length"
|
|
|
|
|
(change)="toggleSelectAll()">
|
|
|
|
|
</mat-checkbox>
|
|
|
|
|
<span class="items-count">{{ items().length }} items</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="items-grid">
|
|
|
|
|
@for (item of items(); track item.id) {
|
|
|
|
|
<div class="item-card" (click)="openItem(item.id)">
|
|
|
|
|
<div class="item-card-actions">
|
|
|
|
|
<mat-checkbox
|
|
|
|
|
[checked]="selectedItems().has(item.id)"
|
|
|
|
|
(change)="toggleSelection(item.id)"
|
|
|
|
|
(click)="$event.stopPropagation()">
|
|
|
|
|
</mat-checkbox>
|
|
|
|
|
<button
|
|
|
|
|
mat-icon-button
|
|
|
|
|
color="warn"
|
|
|
|
|
(click)="deleteItem(item, $event)"
|
|
|
|
|
class="delete-btn">
|
|
|
|
|
<mat-icon>delete</mat-icon>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="item-image">
|
|
|
|
|
@if (item.imgs.length) {
|
2026-02-20 01:46:14 +04:00
|
|
|
<img [src]="item.imgs[0]" [alt]="item.name" (error)="onImageError($event)">
|
|
|
|
|
}
|
|
|
|
|
<div class="no-image" [style.display]="item.imgs.length ? 'none' : 'flex'">
|
|
|
|
|
<mat-icon>image</mat-icon>
|
|
|
|
|
</div>
|
|
|
|
|
@if (item.quantity === 0) {
|
|
|
|
|
<div class="out-of-stock-overlay">Out of Stock</div>
|
|
|
|
|
}
|
|
|
|
|
@if (item.badges?.length) {
|
|
|
|
|
<div class="item-badges">
|
|
|
|
|
@for (badge of (item.badges || []).slice(0, 2); track badge) {
|
|
|
|
|
<span class="badge badge-{{ badge }}">{{ badge }}</span>
|
|
|
|
|
}
|
2026-01-19 23:17:07 +04:00
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="item-info">
|
|
|
|
|
<h3>{{ item.name }}</h3>
|
|
|
|
|
|
|
|
|
|
<div class="item-details">
|
|
|
|
|
<span class="price">{{ item.price }} {{ item.currency }}</span>
|
2026-02-20 09:01:02 +04:00
|
|
|
<span class="quantity">{{ 'QTY' | translate }}: {{ item.quantity }}</span>
|
2026-01-19 23:17:07 +04:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="item-meta">
|
2026-02-20 09:01:02 +04:00
|
|
|
<span class="priority">{{ 'PRIORITY' | translate }}: {{ item.priority }}</span>
|
2026-01-19 23:17:07 +04:00
|
|
|
<mat-icon [class.visible]="item.visible" [class.hidden]="!item.visible">
|
|
|
|
|
{{ item.visible ? 'visibility' : 'visibility_off' }}
|
|
|
|
|
</mat-icon>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
@if (item.tags.length) {
|
|
|
|
|
<div class="item-tags">
|
|
|
|
|
@for (tag of item.tags.slice(0, 3); track tag) {
|
|
|
|
|
<mat-chip>{{ tag }}</mat-chip>
|
|
|
|
|
}
|
|
|
|
|
@if (item.tags.length > 3) {
|
|
|
|
|
<span class="more-tags">+{{ item.tags.length - 3 }}</span>
|
|
|
|
|
}
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
@if (loading()) {
|
|
|
|
|
<div class="loading-more">
|
|
|
|
|
<mat-spinner diameter="40"></mat-spinner>
|
2026-02-20 09:01:02 +04:00
|
|
|
<span>{{ 'LOADING_MORE' | translate }}</span>
|
2026-01-19 23:17:07 +04:00
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@if (!hasMore() && items().length > 0) {
|
|
|
|
|
<div class="end-message">
|
2026-02-20 09:01:02 +04:00
|
|
|
{{ 'NO_MORE_ITEMS' | translate }}
|
2026-01-19 23:17:07 +04:00
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@if (!loading() && items().length === 0) {
|
|
|
|
|
<div class="empty-state">
|
|
|
|
|
<mat-icon>inventory_2</mat-icon>
|
2026-02-20 09:01:02 +04:00
|
|
|
<p>{{ 'NO_ITEMS_FOUND' | translate }}</p>
|
2026-01-19 23:17:07 +04:00
|
|
|
</div>
|
|
|
|
|
}
|
2026-02-20 01:25:29 +04:00
|
|
|
|
|
|
|
|
<div #scrollSentinel class="scroll-sentinel"></div>
|
2026-01-19 23:17:07 +04:00
|
|
|
</div>
|