105 lines
3.1 KiB
Plaintext
105 lines
3.1 KiB
Plaintext
|
|
<div class="page-head">
|
|||
|
|
<h1>Panel</h1>
|
|||
|
|
<p class="muted">Genel envanter özeti ve son stok hareketleri</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="stat-grid">
|
|||
|
|
<div class="stat-card">
|
|||
|
|
<div class="stat-icon">📦</div>
|
|||
|
|
<div>
|
|||
|
|
<div class="stat-value"><%= totalProducts %></div>
|
|||
|
|
<div class="stat-label">Toplam Ürün</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="stat-card">
|
|||
|
|
<div class="stat-icon">💵</div>
|
|||
|
|
<div>
|
|||
|
|
<div class="stat-value"><%= totalStockValue.toLocaleString('tr-TR') %> ₺</div>
|
|||
|
|
<div class="stat-label">Stok Değeri</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="stat-card">
|
|||
|
|
<div class="stat-icon">🔢</div>
|
|||
|
|
<div>
|
|||
|
|
<div class="stat-value"><%= totalStockCount %></div>
|
|||
|
|
<div class="stat-label">Toplam Stok Miktarı</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="stat-card <%= lowStockCount > 0 ? 'danger' : '' %>">
|
|||
|
|
<div class="stat-icon">⚠️</div>
|
|||
|
|
<div>
|
|||
|
|
<div class="stat-value"><%= lowStockCount %></div>
|
|||
|
|
<div class="stat-label">Düşük Stok</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="grid-2">
|
|||
|
|
<section class="card">
|
|||
|
|
<h2>Düşük Stoklu Ürünler</h2>
|
|||
|
|
<% if (lowStockProducts.length === 0) { %>
|
|||
|
|
<p class="muted">Tüm ürünlerin stoku güvenli seviyede. ✅</p>
|
|||
|
|
<% } else { %>
|
|||
|
|
<table class="table">
|
|||
|
|
<thead>
|
|||
|
|
<tr><th>Ürün</th><th>Stok</th><th>Eşik</th></tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
<% lowStockProducts.forEach(p => { %>
|
|||
|
|
<tr>
|
|||
|
|
<td><a href="/api/products/<%= p.id %>"><%= p.name %></a></td>
|
|||
|
|
<td class="badge-err"><%= p.stock %></td>
|
|||
|
|
<td><%= p.minimumStock %></td>
|
|||
|
|
</tr>
|
|||
|
|
<% }) %>
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
<% } %>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section class="card">
|
|||
|
|
<h2>Son Hareketler</h2>
|
|||
|
|
<% if (recentMovements.length === 0) { %>
|
|||
|
|
<p class="muted">Henüz stok hareketi yok.</p>
|
|||
|
|
<% } else { %>
|
|||
|
|
<table class="table">
|
|||
|
|
<thead>
|
|||
|
|
<tr><th>Ürün</th><th>Tip</th><th>Miktar</th><th>Tarih</th></tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
<% recentMovements.forEach(m => { %>
|
|||
|
|
<tr>
|
|||
|
|
<td><%= m.productName %></td>
|
|||
|
|
<td><span class="tag <%= m.type === 'in' ? 'tag-in' : 'tag-out' %>">
|
|||
|
|
<%= m.type === 'in' ? 'Giriş' : 'Çıkış' %></span></td>
|
|||
|
|
<td><%= m.quantity %></td>
|
|||
|
|
<td class="muted"><%= new Date(m.date).toLocaleString('tr-TR') %></td>
|
|||
|
|
</tr>
|
|||
|
|
<% }) %>
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
<% } %>
|
|||
|
|
</section>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<section class="card">
|
|||
|
|
<h2>Kategori Bazlı Özet</h2>
|
|||
|
|
<table class="table">
|
|||
|
|
<thead>
|
|||
|
|
<tr><th>Kategori</th><th>Ürün Sayısı</th><th>Stok Değeri</th><th>Düşük Stok</th></tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
<% categorySummary.forEach(c => { %>
|
|||
|
|
<tr>
|
|||
|
|
<td><%= c.name %></td>
|
|||
|
|
<td><%= c.totalProducts %></td>
|
|||
|
|
<td><%= c.totalStockValue.toLocaleString('tr-TR') %> ₺</td>
|
|||
|
|
<td class="<%= c.lowStockCount > 0 ? 'badge-err' : '' %>">
|
|||
|
|
<%= c.lowStockCount > 0 ? '⚠️ ' + c.lowStockCount : '—' %>
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
<% }) %>
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
</section>
|