fix: render before/after gallery images from API with tab filtering
CI/CD / CI · dotnet build (push) Successful in 40s
CI/CD / Deploy · drsousan (push) Failing after 52s

- Gallery section now fetches /api/gallery and renders real items
  instead of hardcoded placeholders
- Before+after pairs render as side-by-side split with قبل/بعد labels
- Single imageUrl items render as a standard gallery card
- Tab buttons now filter items by category via data-cat attribute
- CSS added for .before-after, .ba-half, .ba-divider, .ba-label, .gallery-caption
- Fixes applied to correct file (Index.cshtml Razor page, not root index.html)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-01 23:59:57 +03:30
parent f034f70ae3
commit 7f5444085b
2 changed files with 145 additions and 80 deletions
+40 -18
View File
@@ -119,6 +119,14 @@
.gallery-placeholder p { font-size:0.75rem; }
.gallery-item-overlay { position:absolute; inset:0; background:rgba(184,149,90,0); display:flex; align-items:center; justify-content:center; transition:background 0.3s; }
.gallery-item:hover .gallery-item-overlay { background:rgba(184,149,90,0.15); }
.gallery-item.before-after { display:flex; flex-direction:row; }
.gallery-item.before-after .ba-half { flex:1; position:relative; overflow:hidden; }
.gallery-item.before-after .ba-half img { width:100%; height:100%; object-fit:cover; display:block; transition:transform 0.4s; }
.gallery-item.before-after:hover .ba-half img { transform:scale(1.05); }
.gallery-item.before-after .ba-label { position:absolute; bottom:6px; left:50%; transform:translateX(-50%); background:rgba(0,0,0,0.55); color:#fff; font-size:0.65rem; padding:2px 8px; border-radius:20px; white-space:nowrap; pointer-events:none; }
.gallery-item.before-after .ba-divider { width:2px; background:rgba(255,255,255,0.7); flex-shrink:0; }
.gallery-caption { position:absolute; bottom:0; left:0; right:0; background:linear-gradient(transparent,rgba(0,0,0,0.5)); color:#fff; font-size:0.75rem; padding:1.2rem 0.8rem 0.5rem; text-align:center; pointer-events:none; }
.gallery-item[style*="display:none"] { display:none !important; }
/* ─── Testimonials ─────────────────────────────────────────── */
#testimonials { background:var(--section-bg); }
.testimonials-header { text-align:center; margin-bottom:3rem; }
@@ -412,28 +420,37 @@
<button class="tab-btn">مزوتراپی</button>
<button class="tab-btn">پاکسازی</button>
</div>
<div class="gallery-grid">
<div class="gallery-grid" id="galleryGrid">
@if (Model.Gallery.Any())
{
@foreach (var item in Model.Gallery)
{
<div class="gallery-item fade-in">
@if (!string.IsNullOrEmpty(item.ImageUrl))
{
<img src="@item.ImageUrl" alt="@item.Caption" loading="lazy" />
}
else
{
<div class="gallery-placeholder">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
<rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/>
<polyline points="21 15 16 10 5 21"/>
</svg>
<p>تصویر قبل و بعد</p>
var hasBoth = !string.IsNullOrEmpty(item.BeforeImageUrl) && !string.IsNullOrEmpty(item.AfterImageUrl);
var hasImg = !string.IsNullOrEmpty(item.ImageUrl);
if (hasBoth)
{
<div class="gallery-item before-after fade-in" data-cat="@item.Category">
<div class="ba-half">
<img src="@item.BeforeImageUrl" alt="قبل از درمان" loading="lazy"/>
<span class="ba-label">قبل</span>
</div>
}
<div class="gallery-item-overlay"></div>
</div>
<div class="ba-divider"></div>
<div class="ba-half">
<img src="@item.AfterImageUrl" alt="بعد از درمان" loading="lazy"/>
<span class="ba-label">بعد</span>
</div>
@if (!string.IsNullOrEmpty(item.Caption)) { <div class="gallery-caption">@item.Caption</div> }
<div class="gallery-item-overlay"></div>
</div>
}
else if (hasImg)
{
<div class="gallery-item fade-in" data-cat="@item.Category">
<img src="@item.ImageUrl" alt="@item.Caption" loading="lazy"/>
@if (!string.IsNullOrEmpty(item.Caption)) { <div class="gallery-caption">@item.Caption</div> }
<div class="gallery-item-overlay"></div>
</div>
}
}
}
else
@@ -703,11 +720,16 @@
btns[1].classList.toggle('active');
}
// Tab buttons
// Tab buttons — filter gallery by category
document.querySelectorAll('.tab-btn').forEach(btn => {
btn.addEventListener('click', () => {
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
const cat = btn.textContent.trim();
document.querySelectorAll('#galleryGrid .gallery-item').forEach(item => {
const match = cat === 'همه' || (item.dataset.cat || '') === cat;
item.style.display = match ? '' : 'none';
});
});
});