Initial commit

This commit is contained in:
Porawit Dongwang
2026-09-16 23:20:08 +07:00
commit 0041668dbb
32577 changed files with 3687927 additions and 0 deletions
@@ -0,0 +1,147 @@
<?php require_once APP_ROOT . '/app/Views/layouts/header.php'; ?>
<div class="mb-6">
<h2 class="text-2xl font-bold text-slate-800 dark:text-white">Dashboard (แผงควบคุม)</h2>
<p class="text-slate-500 dark:text-slate-400">ยินดีต้อนรับเข้าสู่ระบบจัดการข้อมูลเงินเดือนเจ้าหน้าที่</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-6 mb-8">
<div class="bg-white dark:bg-slate-800 rounded-2xl p-6 shadow-sm border-l-4 border-sky-500 flex flex-col items-center justify-center transition-transform hover:-translate-y-1">
<h6 class="text-slate-500 dark:text-slate-400 text-xs font-bold uppercase tracking-wider mb-2">บุคลากรทั้งหมด (งวดล่าสุด)</h6>
<h2 class="text-sky-500 text-3xl font-extrabold m-0"><?= number_format($totalEmployees ?? 0) ?></h2>
<p class="text-slate-400 text-xs m-0 mt-1">คน</p>
</div>
<div class="bg-white dark:bg-slate-800 rounded-2xl p-6 shadow-sm border-l-4 border-teal-500 flex flex-col items-center justify-center transition-transform hover:-translate-y-1">
<h6 class="text-slate-500 dark:text-slate-400 text-xs font-bold uppercase tracking-wider mb-2">ยอดเงินเดือนสุทธิ (งวดล่าสุด)</h6>
<h2 class="text-teal-500 text-3xl font-extrabold m-0"><?= number_format($totalSalary ?? 0, 2) ?></h2>
<p class="text-slate-400 text-xs m-0 mt-1">บาท</p>
</div>
<div class="bg-white dark:bg-slate-800 rounded-2xl p-6 shadow-sm border-l-4 border-amber-500 flex flex-col items-center justify-center transition-transform hover:-translate-y-1">
<h6 class="text-slate-500 dark:text-slate-400 text-xs font-bold uppercase tracking-wider mb-2">สถานะงวดล่าสุด</h6>
<?php if ($latestPeriod): ?>
<h2 class="text-amber-500 text-xl font-extrabold m-0"><?= htmlspecialchars($latestPeriod['status']) ?></h2>
<p class="text-slate-400 text-xs m-0 mt-1">เดือน <?= $latestPeriod['month_no'] ?>/<?= $latestPeriod['year_no'] > 2500 ? $latestPeriod['year_no'] : $latestPeriod['year_no'] + 543 ?></p>
<?php else: ?>
<h2 class="text-slate-500 text-xl font-extrabold m-0">ไม่มีข้อมูล</h2>
<?php endif; ?>
</div>
<div class="bg-white dark:bg-slate-800 rounded-2xl p-6 shadow-sm flex flex-col justify-center">
<h6 class="text-slate-500 dark:text-slate-400 text-xs font-bold uppercase tracking-wider mb-4 text-center">เมนูด่วน</h6>
<a href="<?= BASE_URL ?>/payroll" class="w-full flex items-center justify-center px-4 py-2 bg-sky-500 text-white rounded-xl hover:bg-sky-600 transition-colors mb-3 font-medium text-sm">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 mr-2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v6m3-3H9m12 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" /></svg>
จัดการงวดเงินเดือน
</a>
<a href="<?= BASE_URL ?>/import" class="w-full flex items-center justify-center px-4 py-2 bg-white dark:bg-slate-700 border border-slate-300 dark:border-slate-600 text-slate-700 dark:text-slate-200 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-600 transition-colors font-medium text-sm">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 mr-2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5m-13.5-9L12 3m0 0 4.5 4.5M12 3v13.5" /></svg>
นำเข้าข้อมูล
</a>
</div>
</div>
<div class="bg-white dark:bg-slate-800 rounded-2xl shadow-sm p-6 mb-8">
<div class="flex flex-col md:flex-row md:items-center md:justify-between mb-6 gap-4">
<div class="flex items-center">
<div class="p-2 bg-sky-100 dark:bg-sky-900/40 rounded-lg text-sky-500 mr-3">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 18 9 11.25l4.306 4.306a11.95 11.95 0 0 1 5.814-5.518l2.74-1.22m0 0-5.94-2.281m5.94 2.28-2.28 5.941" /></svg>
</div>
<h5 class="font-bold text-lg text-slate-800 dark:text-white m-0">ภาพรวมรายรับ-รายจ่าย ประจำปี พ.ศ. <?= htmlspecialchars($yearBE ?? date('Y')+543) ?></h5>
</div>
<div>
<form action="<?= BASE_URL ?>/dashboard" method="GET" class="flex items-center">
<label for="year" class="text-sm font-medium text-slate-600 dark:text-slate-400 mr-2">เลือกปี:</label>
<select name="year" id="year" onchange="this.form.submit()" class="rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-700 dark:text-slate-200 px-3 py-1.5 focus:outline-none focus:ring-2 focus:ring-sky-500 transition-all text-sm font-medium cursor-pointer">
<?php if (isset($availableYears) && is_array($availableYears)): ?>
<?php foreach ($availableYears as $y): ?>
<option value="<?= $y ?>" <?= ($currentYear == $y) ? 'selected' : '' ?>>พ.ศ. <?= $y + 543 ?></option>
<?php endforeach; ?>
<?php endif; ?>
</select>
</form>
</div>
</div>
<div class="w-full bg-slate-50 dark:bg-slate-900/50 rounded-xl border border-slate-100 dark:border-slate-700 p-4 h-80 relative">
<canvas id="payrollChart"></canvas>
</div>
</div>
<!-- Chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
const ctx = document.getElementById('payrollChart').getContext('2d');
const isDark = document.documentElement.classList.contains('dark');
const textColor = isDark ? '#94a3b8' : '#64748b';
const gridColor = isDark ? '#334155' : '#e2e8f0';
new Chart(ctx, {
type: 'bar',
data: {
labels: <?= $chartLabels ?? '[]' ?>,
datasets: [
{
label: 'รายรับรวม (บาท)',
data: <?= $chartIncome ?? '[]' ?>,
backgroundColor: '#10b981', // emerald-500
borderRadius: 4,
},
{
label: 'รายจ่ายรวม (บาท)',
data: <?= $chartDeduction ?? '[]' ?>,
backgroundColor: '#ef4444', // red-500
borderRadius: 4,
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
labels: {
color: textColor
}
},
tooltip: {
callbacks: {
label: function(context) {
let label = context.dataset.label || '';
if (label) {
label += ': ';
}
if (context.parsed.y !== null) {
label += new Intl.NumberFormat('th-TH', { style: 'currency', currency: 'THB' }).format(context.parsed.y);
}
return label;
}
}
}
},
scales: {
y: {
grid: { color: gridColor },
ticks: {
color: textColor,
callback: function(value, index, values) {
if(value >= 1000000) return (value / 1000000) + 'M';
if(value >= 1000) return (value / 1000) + 'k';
return value;
}
}
},
x: {
grid: { display: false },
ticks: { color: textColor }
}
}
}
});
});
</script>
<?php require_once APP_ROOT . '/app/Views/layouts/footer.php'; ?>