261 lines
10 KiB
HTML
261 lines
10 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block content %}
|
|
<div class="row g-4 mb-4">
|
|
<!-- Stats Cards -->
|
|
<div class="col-md-3">
|
|
<div class="card glass-card h-100">
|
|
<div class="card-body">
|
|
<div class="stats-icon bg-primary-subtle text-primary">
|
|
<i data-lucide="package"></i>
|
|
</div>
|
|
<h6 class="text-muted mb-1 small fw-bold text-uppercase">TOTAL BARANG</h6>
|
|
<h2 class="fw-bold mb-0 text-dark">{{ total_medicines }}</h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="card glass-card h-100">
|
|
<div class="card-body">
|
|
<div class="stats-icon bg-success-subtle text-success">
|
|
<i data-lucide="boxes"></i>
|
|
</div>
|
|
<h6 class="text-muted mb-1 small fw-bold text-uppercase">TOTAL STOK</h6>
|
|
<h2 class="fw-bold mb-0 text-dark">{{ total_stock }}</h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="card glass-card h-100">
|
|
<div class="card-body">
|
|
<div class="stats-icon bg-warning-subtle text-warning">
|
|
<i data-lucide="alert-triangle"></i>
|
|
</div>
|
|
<h6 class="text-muted mb-1 small fw-bold text-uppercase">STOK MENIPIS</h6>
|
|
<h2 class="fw-bold mb-0 text-dark">{{ low_stock_count }}</h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="card glass-card h-100">
|
|
<div class="card-body">
|
|
<div class="stats-icon bg-danger-subtle text-danger">
|
|
<i data-lucide="calendar-x"></i>
|
|
</div>
|
|
<h6 class="text-muted mb-1 small fw-bold text-uppercase">KADALUARSA</h6>
|
|
<h2 class="fw-bold mb-0 text-dark">{{ expired_count }}</h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-4 mb-4">
|
|
<!-- Chart Area -->
|
|
<div class="col-lg-8">
|
|
<div class="card glass-card h-100">
|
|
<div class="card-body p-4">
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h5 class="fw-bold mb-0">Pergerakan Stok</h5>
|
|
<span class="badge bg-light text-dark border py-2 px-3 rounded-pill small">7 Hari Terakhir</span>
|
|
</div>
|
|
<div style="height: 300px;">
|
|
<canvas id="movementChart"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Expiry Overview -->
|
|
<div class="col-lg-4">
|
|
<div class="card border-0 rounded-4 h-100 bg-white shadow-sm overflow-hidden">
|
|
<div class="card-body p-0">
|
|
<div class="p-4 bg-danger text-white">
|
|
<h5 class="fw-bold mb-0">Pantauan Kadaluarsa</h5>
|
|
<p class="small opacity-75 mb-0">Segera kadaluarsa (90 hari ke depan)</p>
|
|
</div>
|
|
<div class="p-4 text-center">
|
|
<div class="display-1 fw-bold text-danger mb-2">{{ near_expiry_count }}</div>
|
|
<p class="text-muted mb-4">Item memerlukan perhatian segera</p>
|
|
<div class="d-grid">
|
|
<a href="/admin/core/batch/" class="btn btn-outline-danger d-flex align-items-center justify-content-center">
|
|
<i data-lucide="external-link" class="me-2 icon-sm"></i> Tinjau Batch
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-4">
|
|
<div class="col-12">
|
|
<div class="card glass-card">
|
|
<div class="card-body p-4">
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h5 class="fw-bold mb-0 d-flex align-items-center">
|
|
<i data-lucide="history" class="me-2 text-primary"></i> Data Barang Terbaru
|
|
</h5>
|
|
<a href="/admin/core/medicine/" class="btn btn-primary btn-sm d-flex align-items-center px-3 rounded-pill">
|
|
<i data-lucide="settings" class="me-2 icon-sm"></i> Kelola Semua
|
|
</a>
|
|
</div>
|
|
<div class="table-responsive">
|
|
<table class="table align-middle mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>SKU</th>
|
|
<th>Nama Barang</th>
|
|
<th>Kategori</th>
|
|
<th>Stok</th>
|
|
<th>Status</th>
|
|
<th class="text-end">Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for medicine in recent_medicines %}
|
|
<tr>
|
|
<td><span class="badge bg-light text-muted">{{ medicine.sku }}</span></td>
|
|
<td><span class="fw-bold">{{ medicine.name }}</span></td>
|
|
<td><span class="text-muted small">{{ medicine.category.name }}</span></td>
|
|
<td>
|
|
<span class="fw-bold">{{ medicine.total_stock }}</span>
|
|
<span class="text-muted small ms-1">{{ medicine.unit }}</span>
|
|
</td>
|
|
<td>
|
|
{% if medicine.status == 'Tersedia' %}
|
|
<span class="badge bg-success-subtle text-success rounded-pill px-3">Tersedia</span>
|
|
{% elif medicine.status == 'Stok Menipis' %}
|
|
<span class="badge bg-warning-subtle text-warning rounded-pill px-3">Stok Menipis</span>
|
|
{% else %}
|
|
<span class="badge bg-danger-subtle text-danger rounded-pill px-3">Habis</span>
|
|
{% endif %}
|
|
</td>
|
|
<td class="text-end">
|
|
<a href="/admin/core/medicine/{{ medicine.id }}/change/" class="btn btn-light btn-sm rounded-circle p-2">
|
|
<i data-lucide="edit-3" class="icon-sm"></i>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr>
|
|
<td colspan="6" class="text-center py-5 text-muted">
|
|
<i data-lucide="inbox" class="mb-2 d-block mx-auto opacity-20" style="width: 48px; height: 48px;"></i>
|
|
Belum ada data tersedia.
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
<script>
|
|
const ctx = document.getElementById('movementChart').getContext('2d');
|
|
|
|
// Create gradients
|
|
const gradientIn = ctx.createLinearGradient(0, 0, 0, 300);
|
|
gradientIn.addColorStop(0, 'rgba(67, 97, 238, 0.2)');
|
|
gradientIn.addColorStop(1, 'rgba(67, 97, 238, 0)');
|
|
|
|
const gradientOut = ctx.createLinearGradient(0, 0, 0, 300);
|
|
gradientOut.addColorStop(0, 'rgba(239, 35, 60, 0.2)');
|
|
gradientOut.addColorStop(1, 'rgba(239, 35, 60, 0)');
|
|
|
|
new Chart(ctx, {
|
|
type: 'line',
|
|
data: {
|
|
labels: {{ chart_labels|safe }},
|
|
datasets: [
|
|
{
|
|
label: 'Barang Masuk',
|
|
data: {{ chart_data_in|safe }},
|
|
borderColor: '#4361ee',
|
|
backgroundColor: gradientIn,
|
|
fill: true,
|
|
tension: 0.4,
|
|
borderWidth: 3,
|
|
pointRadius: 4,
|
|
pointHoverRadius: 6,
|
|
pointBackgroundColor: '#fff',
|
|
pointBorderWidth: 2
|
|
},
|
|
{
|
|
label: 'Barang Keluar',
|
|
data: {{ chart_data_out|safe }},
|
|
borderColor: '#ef233c',
|
|
backgroundColor: gradientOut,
|
|
fill: true,
|
|
tension: 0.4,
|
|
borderWidth: 3,
|
|
pointRadius: 4,
|
|
pointHoverRadius: 6,
|
|
pointBackgroundColor: '#fff',
|
|
pointBorderWidth: 2
|
|
}
|
|
]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
interaction: {
|
|
mode: 'index',
|
|
intersect: false,
|
|
},
|
|
plugins: {
|
|
legend: {
|
|
position: 'top',
|
|
align: 'end',
|
|
labels: {
|
|
usePointStyle: true,
|
|
boxWidth: 8,
|
|
font: {
|
|
family: 'Plus Jakarta Sans',
|
|
size: 12,
|
|
weight: '600'
|
|
}
|
|
}
|
|
},
|
|
tooltip: {
|
|
padding: 12,
|
|
backgroundColor: 'rgba(255, 255, 255, 0.9)',
|
|
titleColor: '#1e293b',
|
|
titleFont: { size: 14, weight: 'bold' },
|
|
bodyColor: '#64748b',
|
|
borderColor: '#e2e8f0',
|
|
borderWidth: 1,
|
|
displayColors: true,
|
|
boxPadding: 6,
|
|
usePointStyle: true
|
|
}
|
|
},
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true,
|
|
grid: {
|
|
color: 'rgba(0, 0, 0, 0.03)',
|
|
drawBorder: false
|
|
},
|
|
ticks: {
|
|
font: { family: 'Plus Jakarta Sans' }
|
|
}
|
|
},
|
|
x: {
|
|
grid: {
|
|
display: false
|
|
},
|
|
ticks: {
|
|
font: { family: 'Plus Jakarta Sans' }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %}
|