added sceleton for loading
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
<div class="item-card">
|
||||
<a [routerLink]="['/item', item.itemID] | langRoute" class="item-link">
|
||||
<div class="item-image">
|
||||
<img [src]="getMainImage(item)" [alt]="item.name" loading="lazy" decoding="async" width="300" height="300" />
|
||||
<img [src]="getMainImage(item)" [alt]="item.name" loading="lazy" decoding="async" />
|
||||
@if (item.discount > 0) {
|
||||
<div class="discount-badge">-{{ item.discount }}%</div>
|
||||
}
|
||||
@@ -50,14 +50,24 @@
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@if (loading() && items().length > 0) {
|
||||
<div class="loading-more">
|
||||
<div class="spinner"></div>
|
||||
<p>{{ 'category.loadingMore' | translate }}</p>
|
||||
</div>
|
||||
}
|
||||
@if (loading() && items().length > 0) {
|
||||
@for (i of skeletonSlots; track i) {
|
||||
<div class="item-card skeleton-card">
|
||||
<div class="item-link">
|
||||
<div class="item-image skeleton-image"></div>
|
||||
<div class="item-details">
|
||||
<div class="skeleton-line skeleton-title"></div>
|
||||
<div class="skeleton-line skeleton-rating"></div>
|
||||
<div class="skeleton-line skeleton-price"></div>
|
||||
<div class="skeleton-line skeleton-stock"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="skeleton-btn"></div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
|
||||
@if (!hasMore() && items().length > 0) {
|
||||
<div class="no-more">
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #f5f5f5;
|
||||
background: #f0f0f0;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
@@ -149,7 +149,7 @@
|
||||
object-fit: contain;
|
||||
background: white;
|
||||
padding: 12px;
|
||||
transition: transform 0.3s ease;
|
||||
transition: transform 0.3s ease, opacity 0.3s ease;
|
||||
}
|
||||
|
||||
&:hover img {
|
||||
@@ -290,11 +290,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.loading-more {
|
||||
text-align: center;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
@@ -315,6 +310,59 @@
|
||||
padding: 40px 20px;
|
||||
}
|
||||
|
||||
// Skeleton loading cards
|
||||
.skeleton-card {
|
||||
pointer-events: none;
|
||||
|
||||
.skeleton-image {
|
||||
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||
background-size: 200% 100%;
|
||||
animation: shimmer 1.5s infinite;
|
||||
}
|
||||
|
||||
.skeleton-line {
|
||||
border-radius: 6px;
|
||||
background: linear-gradient(90deg, #e8e8e8 25%, #d8d8d8 50%, #e8e8e8 75%);
|
||||
background-size: 200% 100%;
|
||||
animation: shimmer 1.5s infinite;
|
||||
}
|
||||
|
||||
.skeleton-title {
|
||||
height: 16px;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.skeleton-rating {
|
||||
height: 12px;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.skeleton-price {
|
||||
height: 18px;
|
||||
width: 40%;
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.skeleton-stock {
|
||||
height: 6px;
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.skeleton-btn {
|
||||
height: 42px;
|
||||
background: linear-gradient(90deg, #5a8a85 25%, #497671 50%, #5a8a85 75%);
|
||||
background-size: 200% 100%;
|
||||
animation: shimmer 1.5s infinite;
|
||||
border-radius: 0 0 13px 13px;
|
||||
margin-top: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% { background-position: 200% 0; }
|
||||
100% { background-position: -200% 0; }
|
||||
}
|
||||
|
||||
// Responsive
|
||||
@media (max-width: 1200px) {
|
||||
.items-grid {
|
||||
|
||||
@@ -90,7 +90,7 @@ export class CategoryComponent implements OnInit, OnDestroy {
|
||||
|
||||
this.scrollTimeout = setTimeout(() => {
|
||||
const scrollPosition = window.innerHeight + window.scrollY;
|
||||
const bottomPosition = document.documentElement.scrollHeight - 500;
|
||||
const bottomPosition = document.documentElement.scrollHeight - 1200;
|
||||
|
||||
if (scrollPosition >= bottomPosition && !this.loading() && this.hasMore() && !this.isLoadingMore) {
|
||||
this.loadItems();
|
||||
@@ -104,6 +104,7 @@ export class CategoryComponent implements OnInit, OnDestroy {
|
||||
this.cartService.addItem(itemID);
|
||||
}
|
||||
|
||||
readonly skeletonSlots = Array.from({ length: 8 });
|
||||
readonly getDiscountedPrice = getDiscountedPrice;
|
||||
readonly getMainImage = getMainImage;
|
||||
readonly trackByItemId = trackByItemId;
|
||||
|
||||
Reference in New Issue
Block a user