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,267 @@
<?php require_once APP_ROOT . '/app/Views/layouts/header.php'; ?>
<div class="flex flex-col md:flex-row md:items-center md:justify-between mb-6 gap-4">
<div>
<h2 class="text-2xl font-bold text-slate-800 dark:text-white">รายการรายจ่าย (Deduction Categories)</h2>
<p class="text-slate-500 dark:text-slate-400 text-sm mt-1">จัดการประเภทรายจ่าย/หักลบทั้งหมดในระบบ</p>
</div>
<button onclick="document.getElementById('createDeductionModal').classList.remove('hidden')" class="inline-flex items-center justify-center px-4 py-2.5 bg-rose-500 hover:bg-rose-600 text-white text-sm font-medium rounded-xl transition-colors shadow-sm w-full md:w-auto">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-4 h-4 mr-2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" /></svg>
เพิ่มรายจ่ายใหม่
</button>
</div>
<!-- DataTables CSS for Tailwind -->
<link rel="stylesheet" href="https://cdn.datatables.net/2.0.8/css/dataTables.tailwindcss.css">
<style>
/* DataTables Dark Mode Overrides */
.dark .dt-container { color: #cbd5e1; }
.dark .dt-length select, .dark .dt-search input {
background-color: #1e293b; border-color: #334155; color: #f8fafc; border-radius: 0.5rem; padding: 0.25rem 0.5rem;
}
.dark .dt-info, .dark .dt-paging-button { color: #94a3b8 !important; }
.dark .dt-paging-button.current { background: #38bdf8 !important; color: #0f172a !important; border-color: #38bdf8 !important; }
.dark .dt-paging-button:hover { background: #334155 !important; color: #f8fafc !important; }
table.dataTable.no-footer { border-bottom: 1px solid #334155 !important; }
</style>
<div class="bg-white dark:bg-slate-800 rounded-2xl shadow-sm border border-slate-100 dark:border-slate-700 overflow-hidden p-6">
<div class="overflow-x-hidden">
<table id="deductionTable" class="w-full text-left text-sm text-slate-600 dark:text-slate-300 display">
<thead class="bg-slate-50 dark:bg-slate-900/50 text-slate-500 dark:text-slate-400 text-xs uppercase font-semibold">
<tr>
<th class="px-6 py-4">รหัส</th>
<th class="px-6 py-4">ชื่อรายการรายจ่าย</th>
<th class="px-6 py-4 text-center">แหล่งที่มาเงิน</th>
<th class="px-6 py-4 text-center">ลดหย่อนภาษี</th>
<th class="px-6 py-4 text-center">สถานะ</th>
<th class="px-6 py-4 text-right">จัดการ</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-100 dark:divide-slate-700">
<?php if (empty($deductions)): ?>
<tr>
<td colspan="6" class="px-6 py-8 text-center text-slate-500 dark:text-slate-400">
ยังไม่มีข้อมูลรายการรายจ่าย
</td>
</tr>
<?php else: ?>
<?php foreach ($deductions as $ded): ?>
<tr class="hover:bg-slate-50 dark:hover:bg-slate-700/50 transition-colors">
<td class="px-6 py-4 font-mono font-bold text-slate-700 dark:text-slate-200">
<?= htmlspecialchars($ded['code']) ?>
</td>
<td class="px-6 py-4">
<div class="font-medium text-slate-800 dark:text-slate-200"><?= htmlspecialchars($ded['name']) ?></div>
<?php if (!empty($ded['description'])): ?>
<div class="text-xs text-slate-500 dark:text-slate-400 mt-1"><?= htmlspecialchars($ded['description']) ?></div>
<?php endif; ?>
</td>
<td class="px-6 py-4 text-center font-medium text-slate-700 dark:text-slate-200">
<?= $ded['fund_source'] === 'CGD' ? 'กรมบัญชีกลาง' : 'โรงพยาบาล' ?>
</td>
<td class="px-6 py-4 text-center">
<?php if ($ded['is_tax_deductible']): ?>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400">ใช่</span>
<?php else: ?>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-slate-100 text-slate-700 dark:bg-slate-700 dark:text-slate-300">ไม่</span>
<?php endif; ?>
</td>
<td class="px-6 py-4 text-center">
<?php if ($ded['is_active']): ?>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400">ใช้งาน</span>
<?php else: ?>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400">ปิดใช้งาน</span>
<?php endif; ?>
</td>
<td class="px-6 py-4 text-right">
<button onclick='openEditDeductionModal(<?= json_encode($ded) ?>)' class="inline-flex items-center px-3 py-1.5 border border-slate-300 dark:border-slate-600 rounded-lg text-xs font-medium text-slate-700 dark:text-slate-300 hover:bg-slate-50 dark:hover:bg-slate-700 transition-colors">
แก้ไข
</button>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
<!-- Create Modal -->
<div id="createDeductionModal" class="hidden fixed inset-0 z-50 overflow-y-auto">
<div class="fixed inset-0 bg-slate-900/50 backdrop-blur-sm transition-opacity" onclick="document.getElementById('createDeductionModal').classList.add('hidden')"></div>
<div class="flex min-h-screen items-center justify-center p-4">
<div class="relative transform overflow-hidden rounded-2xl bg-white dark:bg-slate-800 text-left shadow-xl transition-all sm:w-full sm:max-w-lg border border-slate-100 dark:border-slate-700">
<form action="<?= BASE_URL ?>/settings/deduction" method="POST">
<div class="p-6">
<h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-6">เพิ่มรายการรายจ่ายใหม่</h3>
<div class="space-y-4">
<div>
<label for="code" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">รหัสรายจ่าย (Code)</label>
<input type="text" id="code" name="code" required class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-rose-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
</div>
<div>
<label for="name" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ชื่อรายการ (Name)</label>
<input type="text" id="name" name="name" required class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-rose-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
</div>
<div>
<label for="description" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">รายละเอียด (Description)</label>
<input type="text" id="description" name="description" class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-sky-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
</div>
<div>
<label for="fund_source" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">แหล่งที่มาเงิน</label>
<select id="fund_source" name="fund_source" class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-sky-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
<option value="HOSPITAL">โรงพยาบาล</option>
<option value="CGD">กรมบัญชีกลาง (CGD)</option>
</select>
</div>
<div class="flex items-center justify-between mt-4">
<label class="flex items-center cursor-pointer">
<div class="relative">
<input type="checkbox" name="is_tax_deductible" class="sr-only">
<div class="block bg-slate-200 dark:bg-slate-700 w-10 h-6 rounded-full transition-colors"></div>
<div class="dot absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform transform translate-x-full"></div>
</div>
<div class="ml-3 text-sm font-medium text-slate-700 dark:text-slate-300">ใช้ลดหย่อนภาษีได้</div>
</label>
<label class="flex items-center cursor-pointer">
<div class="relative">
<input type="checkbox" name="is_active" class="sr-only" checked>
<div class="block bg-slate-200 dark:bg-slate-700 w-10 h-6 rounded-full transition-colors"></div>
<div class="dot absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform transform translate-x-full"></div>
</div>
<div class="ml-3 text-sm font-medium text-slate-700 dark:text-slate-300">เปิดใช้งาน</div>
</label>
</div>
</div>
</div>
<div class="bg-slate-50 dark:bg-slate-700/50 px-6 py-4 flex justify-end space-x-3">
<button type="button" onclick="document.getElementById('createDeductionModal').classList.add('hidden')" class="px-4 py-2 text-sm font-semibold text-slate-700 dark:text-slate-300 bg-white dark:bg-slate-800 border border-slate-300 dark:border-slate-600 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-700 transition-colors">ยกเลิก</button>
<button type="submit" class="px-4 py-2 text-sm font-semibold text-white bg-rose-500 rounded-xl hover:bg-rose-600 transition-colors">บันทึก</button>
</div>
</form>
</div>
</div>
</div>
<!-- Edit Modal -->
<div id="editDeductionModal" class="hidden fixed inset-0 z-50 overflow-y-auto">
<div class="fixed inset-0 bg-slate-900/50 backdrop-blur-sm transition-opacity" onclick="document.getElementById('editDeductionModal').classList.add('hidden')"></div>
<div class="flex min-h-screen items-center justify-center p-4">
<div class="relative transform overflow-hidden rounded-2xl bg-white dark:bg-slate-800 text-left shadow-xl transition-all sm:w-full sm:max-w-lg border border-slate-100 dark:border-slate-700">
<form action="<?= BASE_URL ?>/settings/deduction/update" method="POST">
<input type="hidden" id="edit_id" name="id">
<div class="p-6">
<h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-6">แก้ไขรายการรายจ่าย</h3>
<div class="space-y-4">
<div>
<label for="edit_code" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">รหัสรายจ่าย (Code)</label>
<input type="text" id="edit_code" name="code" required class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-rose-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
</div>
<div>
<label for="edit_name" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ชื่อรายการ (Name)</label>
<input type="text" id="edit_name" name="name" required class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-rose-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
</div>
<div>
<label for="edit_description" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">รายละเอียด (Description)</label>
<input type="text" id="edit_description" name="description" class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-rose-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
</div>
<div>
<label for="edit_display_order" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ลำดับการแสดงผล</label>
<input type="number" id="edit_display_order" name="display_order" class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-sky-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
</div>
<div>
<label for="edit_fund_source" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">แหล่งที่มาเงิน</label>
<select id="edit_fund_source" name="fund_source" class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-sky-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
<option value="HOSPITAL">โรงพยาบาล</option>
<option value="CGD">กรมบัญชีกลาง (CGD)</option>
</select>
</div>
<div class="flex items-center justify-between mt-4">
<label class="flex items-center cursor-pointer">
<div class="relative">
<input type="checkbox" id="edit_is_tax_deductible" name="is_tax_deductible" class="sr-only">
<div class="block bg-slate-200 dark:bg-slate-700 w-10 h-6 rounded-full transition-colors"></div>
<div class="dot absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform transform translate-x-full"></div>
</div>
<div class="ml-3 text-sm font-medium text-slate-700 dark:text-slate-300">ใช้ลดหย่อนภาษีได้</div>
</label>
<label class="flex items-center cursor-pointer">
<div class="relative">
<input type="checkbox" id="edit_is_active" name="is_active" class="sr-only">
<div class="block bg-slate-200 dark:bg-slate-700 w-10 h-6 rounded-full transition-colors"></div>
<div class="dot absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform transform translate-x-full"></div>
</div>
<div class="ml-3 text-sm font-medium text-slate-700 dark:text-slate-300">เปิดใช้งาน</div>
</label>
</div>
</div>
</div>
<div class="bg-slate-50 dark:bg-slate-700/50 px-6 py-4 flex justify-end space-x-3">
<button type="button" onclick="document.getElementById('editDeductionModal').classList.add('hidden')" class="px-4 py-2 text-sm font-semibold text-slate-700 dark:text-slate-300 bg-white dark:bg-slate-800 border border-slate-300 dark:border-slate-600 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-700 transition-colors">ยกเลิก</button>
<button type="submit" class="px-4 py-2 text-sm font-semibold text-white bg-rose-500 rounded-xl hover:bg-rose-600 transition-colors">บันทึกการแก้ไข</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<style>
/* Custom Toggle Switch Logic */
input:checked ~ .block { background-color: #0ea5e9; }
input:checked[name="is_tax_deductible"] ~ .block { background-color: #10b981; }
input:checked ~ .dot { transform: translateX(100%); }
input:not(:checked) ~ .dot { transform: translateX(0); }
</style>
<!-- jQuery and DataTables JS -->
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://cdn.datatables.net/2.0.8/js/dataTables.js"></script>
<script src="https://cdn.datatables.net/2.0.8/js/dataTables.tailwindcss.js"></script>
<script>
$(document).ready(function() {
$('#deductionTable').DataTable({
"language": {
"sProcessing": "กำลังดำเนินการ...",
"sLengthMenu": "แสดง _MENU_ เรคคอร์ด",
"sZeroRecords": "ไม่พบข้อมูล",
"sInfo": "แสดง _START_ ถึง _END_ จาก _TOTAL_ เรคคอร์ด",
"sInfoEmpty": "แสดง 0 ถึง 0 จาก 0 เรคคอร์ด",
"sInfoFiltered": "(กรองข้อมูล _MAX_ ทุกเรคคอร์ด)",
"sSearch": "ค้นหา:",
"oPaginate": {
"sFirst": "แรกสุด",
"sPrevious": "ก่อนหน้า",
"sNext": "ถัดไป",
"sLast": "สุดท้าย"
}
},
"pageLength": 25,
"columnDefs": [
{ "orderable": false, "targets": 5 } // Disable sorting on Action column
]
});
});
function openEditDeductionModal(deduction) {
document.getElementById('edit_id').value = deduction.id;
document.getElementById('edit_code').value = deduction.code;
document.getElementById('edit_name').value = deduction.name;
document.getElementById('edit_description').value = deduction.description;
document.getElementById('edit_fund_source').value = deduction.fund_source || 'HOSPITAL';
document.getElementById('edit_display_order').value = deduction.display_order;
document.getElementById('edit_is_tax_deductible').checked = deduction.is_tax_deductible == 1;
document.getElementById('edit_is_active').checked = deduction.is_active == 1;
document.getElementById('editDeductionModal').classList.remove('hidden');
}
</script>
<?php require_once APP_ROOT . '/app/Views/layouts/footer.php'; ?>
@@ -0,0 +1,263 @@
<?php require_once APP_ROOT . '/app/Views/layouts/header.php'; ?>
<div class="flex flex-col md:flex-row md:items-center md:justify-between mb-6 gap-4">
<div>
<h2 class="text-2xl font-bold text-slate-800 dark:text-white">รายการรายรับ (Income Categories)</h2>
<p class="text-slate-500 dark:text-slate-400 text-sm mt-1">จัดการประเภทรายรับทั้งหมดในระบบ</p>
</div>
<button onclick="document.getElementById('createIncomeModal').classList.remove('hidden')" class="inline-flex items-center justify-center px-4 py-2.5 bg-sky-500 hover:bg-sky-600 text-white text-sm font-medium rounded-xl transition-colors shadow-sm w-full md:w-auto">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-4 h-4 mr-2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" /></svg>
เพิ่มรายรับใหม่
</button>
</div>
<!-- DataTables CSS for Tailwind -->
<link rel="stylesheet" href="https://cdn.datatables.net/2.0.8/css/dataTables.tailwindcss.css">
<style>
/* DataTables Dark Mode Overrides */
.dark .dt-container { color: #cbd5e1; }
.dark .dt-length select, .dark .dt-search input {
background-color: #1e293b; border-color: #334155; color: #f8fafc; border-radius: 0.5rem; padding: 0.25rem 0.5rem;
}
.dark .dt-info, .dark .dt-paging-button { color: #94a3b8 !important; }
.dark .dt-paging-button.current { background: #38bdf8 !important; color: #0f172a !important; border-color: #38bdf8 !important; }
.dark .dt-paging-button:hover { background: #334155 !important; color: #f8fafc !important; }
table.dataTable.no-footer { border-bottom: 1px solid #334155 !important; }
</style>
<div class="bg-white dark:bg-slate-800 rounded-2xl shadow-sm border border-slate-100 dark:border-slate-700 overflow-hidden p-6">
<div class="overflow-x-hidden">
<table id="incomeTable" class="w-full text-left text-sm text-slate-600 dark:text-slate-300 display">
<thead class="bg-slate-50 dark:bg-slate-900/50 text-slate-500 dark:text-slate-400 text-xs uppercase font-semibold">
<tr>
<th class="px-6 py-4">รหัส</th>
<th class="px-6 py-4">ชื่อรายการรายรับ</th>
<th class="px-6 py-4 text-center">แหล่งที่มาเงิน</th>
<th class="px-6 py-4 text-center">คิดภาษี</th>
<th class="px-6 py-4 text-center">สถานะ</th>
<th class="px-6 py-4 text-right">จัดการ</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-100 dark:divide-slate-700">
<?php if (empty($incomes)): ?>
<tr>
<td colspan="6" class="px-6 py-8 text-center text-slate-500 dark:text-slate-400">
ยังไม่มีข้อมูลรายการรายรับ
</td>
</tr>
<?php else: ?>
<?php foreach ($incomes as $inc): ?>
<tr class="hover:bg-slate-50 dark:hover:bg-slate-700/50 transition-colors">
<td class="px-6 py-4 font-mono font-bold text-slate-700 dark:text-slate-200">
<?= htmlspecialchars($inc['code']) ?>
</td>
<td class="px-6 py-4">
<div class="font-medium text-slate-800 dark:text-slate-200"><?= htmlspecialchars($inc['name']) ?></div>
<?php if (!empty($inc['description'])): ?>
<div class="text-xs text-slate-500 dark:text-slate-400 mt-1"><?= htmlspecialchars($inc['description']) ?></div>
<?php endif; ?>
</td>
<td class="px-6 py-4 text-center font-medium text-slate-700 dark:text-slate-200">
<?= $inc['fund_source'] === 'CGD' ? 'กรมบัญชีกลาง' : 'โรงพยาบาล' ?>
</td>
<td class="px-6 py-4 text-center">
<?php if ($inc['is_taxable']): ?>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400">ใช่</span>
<?php else: ?>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-slate-100 text-slate-700 dark:bg-slate-700 dark:text-slate-300">ไม่</span>
<?php endif; ?>
</td>
<td class="px-6 py-4 text-center">
<?php if ($inc['is_active']): ?>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400">ใช้งาน</span>
<?php else: ?>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400">ปิดใช้งาน</span>
<?php endif; ?>
</td>
<td class="px-6 py-4 text-right">
<button onclick='openEditIncomeModal(<?= json_encode($inc) ?>)' class="inline-flex items-center px-3 py-1.5 border border-slate-300 dark:border-slate-600 rounded-lg text-xs font-medium text-slate-700 dark:text-slate-300 hover:bg-slate-50 dark:hover:bg-slate-700 transition-colors">
แก้ไข
</button>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
<!-- Create Modal -->
<div id="createIncomeModal" class="hidden fixed inset-0 z-50 overflow-y-auto">
<div class="fixed inset-0 bg-slate-900/50 backdrop-blur-sm transition-opacity" onclick="document.getElementById('createIncomeModal').classList.add('hidden')"></div>
<div class="flex min-h-screen items-center justify-center p-4">
<div class="relative transform overflow-hidden rounded-2xl bg-white dark:bg-slate-800 text-left shadow-xl transition-all sm:w-full sm:max-w-lg border border-slate-100 dark:border-slate-700">
<form action="<?= BASE_URL ?>/settings/income" method="POST">
<div class="p-6">
<h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-6">เพิ่มรายการรายรับใหม่</h3>
<div class="space-y-4">
<div>
<label for="code" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">รหัสรายรับ (Code)</label>
<input type="text" id="code" name="code" required class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-sky-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
</div>
<div>
<label for="name" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ชื่อรายการ (Name)</label>
<input type="text" id="name" name="name" required class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-sky-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
</div>
<div>
<label for="description" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">รายละเอียด (Description)</label>
<input type="text" id="description" name="description" class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-sky-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
</div>
<div>
<label for="fund_source" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">แหล่งที่มาเงิน</label>
<select id="fund_source" name="fund_source" class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-sky-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
<option value="HOSPITAL">โรงพยาบาล</option>
<option value="CGD">กรมบัญชีกลาง (CGD)</option>
</select>
</div>
<div class="flex items-center justify-between mt-4">
<label class="flex items-center cursor-pointer">
<div class="relative">
<input type="checkbox" name="is_taxable" class="sr-only" checked>
<div class="block bg-slate-200 dark:bg-slate-700 w-10 h-6 rounded-full transition-colors"></div>
<div class="dot absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform transform translate-x-full"></div>
</div>
<div class="ml-3 text-sm font-medium text-slate-700 dark:text-slate-300">นำไปคำนวณภาษี</div>
</label>
<label class="flex items-center cursor-pointer">
<div class="relative">
<input type="checkbox" name="is_active" class="sr-only" checked>
<div class="block bg-slate-200 dark:bg-slate-700 w-10 h-6 rounded-full transition-colors"></div>
<div class="dot absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform transform translate-x-full"></div>
</div>
<div class="ml-3 text-sm font-medium text-slate-700 dark:text-slate-300">เปิดใช้งาน</div>
</label>
</div>
</div>
</div>
<div class="bg-slate-50 dark:bg-slate-700/50 px-6 py-4 flex justify-end space-x-3">
<button type="button" onclick="document.getElementById('createIncomeModal').classList.add('hidden')" class="px-4 py-2 text-sm font-semibold text-slate-700 dark:text-slate-300 bg-white dark:bg-slate-800 border border-slate-300 dark:border-slate-600 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-700 transition-colors">ยกเลิก</button>
<button type="submit" class="px-4 py-2 text-sm font-semibold text-white bg-sky-500 rounded-xl hover:bg-sky-600 transition-colors">บันทึก</button>
</div>
</form>
</div>
</div>
</div>
<!-- Edit Modal -->
<div id="editIncomeModal" class="hidden fixed inset-0 z-50 overflow-y-auto">
<div class="fixed inset-0 bg-slate-900/50 backdrop-blur-sm transition-opacity" onclick="document.getElementById('editIncomeModal').classList.add('hidden')"></div>
<div class="flex min-h-screen items-center justify-center p-4">
<div class="relative transform overflow-hidden rounded-2xl bg-white dark:bg-slate-800 text-left shadow-xl transition-all sm:w-full sm:max-w-lg border border-slate-100 dark:border-slate-700">
<form action="<?= BASE_URL ?>/settings/income/update" method="POST">
<input type="hidden" id="edit_id" name="id">
<div class="p-6">
<h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-6">แก้ไขรายการรายรับ</h3>
<div class="space-y-4">
<div>
<label for="edit_code" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">รหัสรายรับ (Code)</label>
<input type="text" id="edit_code" name="code" required class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-sky-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
</div>
<div>
<label for="edit_name" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ชื่อรายการ (Name)</label>
<input type="text" id="edit_name" name="name" required class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-sky-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
</div>
<div>
<label for="edit_description" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">รายละเอียด (Description)</label>
<input type="text" id="edit_description" name="description" class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-sky-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
</div>
<div>
<label for="edit_display_order" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ลำดับการแสดงผล</label>
<input type="number" id="edit_display_order" name="display_order" class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-sky-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
</div>
<div>
<label for="edit_fund_source" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">แหล่งที่มาเงิน</label>
<select id="edit_fund_source" name="fund_source" class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-sky-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
<option value="HOSPITAL">โรงพยาบาล</option>
<option value="CGD">กรมบัญชีกลาง (CGD)</option>
</select>
</div>
<div class="flex items-center justify-between mt-4">
<label class="flex items-center cursor-pointer">
<div class="relative">
<input type="checkbox" id="edit_is_taxable" name="is_taxable" class="sr-only">
<div class="block bg-slate-200 dark:bg-slate-700 w-10 h-6 rounded-full transition-colors"></div>
<div class="dot absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform transform translate-x-full"></div>
</div>
<div class="ml-3 text-sm font-medium text-slate-700 dark:text-slate-300">นำไปคำนวณภาษี</div>
</label>
<label class="flex items-center cursor-pointer">
<div class="relative">
<input type="checkbox" id="edit_is_active" name="is_active" class="sr-only">
<div class="block bg-slate-200 dark:bg-slate-700 w-10 h-6 rounded-full transition-colors"></div>
<div class="dot absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform transform translate-x-full"></div>
</div>
<div class="ml-3 text-sm font-medium text-slate-700 dark:text-slate-300">เปิดใช้งาน</div>
</label>
</div>
</div>
</div>
<div class="bg-slate-50 dark:bg-slate-700/50 px-6 py-4 flex justify-end space-x-3">
<button type="button" onclick="document.getElementById('editIncomeModal').classList.add('hidden')" class="px-4 py-2 text-sm font-semibold text-slate-700 dark:text-slate-300 bg-white dark:bg-slate-800 border border-slate-300 dark:border-slate-600 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-700 transition-colors">ยกเลิก</button>
<button type="submit" class="px-4 py-2 text-sm font-semibold text-white bg-sky-500 rounded-xl hover:bg-sky-600 transition-colors">บันทึกการแก้ไข</button>
</div>
</form>
</div>
</div>
</div>
<style>
/* Custom Toggle Switch Logic */
input:checked ~ .block { background-color: #0ea5e9; }
input:checked ~ .dot { transform: translateX(100%); }
input:not(:checked) ~ .dot { transform: translateX(0); }
</style>
<!-- jQuery and DataTables JS -->
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://cdn.datatables.net/2.0.8/js/dataTables.js"></script>
<script src="https://cdn.datatables.net/2.0.8/js/dataTables.tailwindcss.js"></script>
<script>
$(document).ready(function() {
$('#incomeTable').DataTable({
"language": {
"sProcessing": "กำลังดำเนินการ...",
"sLengthMenu": "แสดง _MENU_ เรคคอร์ด",
"sZeroRecords": "ไม่พบข้อมูล",
"sInfo": "แสดง _START_ ถึง _END_ จาก _TOTAL_ เรคคอร์ด",
"sInfoEmpty": "แสดง 0 ถึง 0 จาก 0 เรคคอร์ด",
"sInfoFiltered": "(กรองข้อมูล _MAX_ ทุกเรคคอร์ด)",
"sSearch": "ค้นหา:",
"oPaginate": {
"sFirst": "แรกสุด",
"sPrevious": "ก่อนหน้า",
"sNext": "ถัดไป",
"sLast": "สุดท้าย"
}
},
"pageLength": 25,
"columnDefs": [
{ "orderable": false, "targets": 5 } // Disable sorting on Action column
]
});
});
function openEditIncomeModal(income) {
document.getElementById('edit_id').value = income.id;
document.getElementById('edit_code').value = income.code;
document.getElementById('edit_name').value = income.name;
document.getElementById('edit_description').value = income.description;
document.getElementById('edit_fund_source').value = income.fund_source || 'HOSPITAL';
document.getElementById('edit_display_order').value = income.display_order;
document.getElementById('edit_is_taxable').checked = income.is_taxable == 1;
document.getElementById('edit_is_active').checked = income.is_active == 1;
document.getElementById('editIncomeModal').classList.remove('hidden');
}
</script>
<?php require_once APP_ROOT . '/app/Views/layouts/footer.php'; ?>
@@ -0,0 +1,223 @@
<?php require_once APP_ROOT . '/app/Views/layouts/header.php'; ?>
<div class="flex flex-col md:flex-row md:items-center md:justify-between mb-6 gap-4">
<div>
<h2 class="text-2xl font-bold text-slate-800 dark:text-white">ประเภทเจ้าหน้าที่ (Officer Types)</h2>
<p class="text-slate-500 dark:text-slate-400 text-sm mt-1">จัดการประเภทเจ้าหน้าที่สำหรับใช้ในระบบรายงาน</p>
</div>
<button onclick="document.getElementById('createModal').classList.remove('hidden')" class="inline-flex items-center justify-center px-4 py-2.5 bg-sky-500 hover:bg-sky-600 text-white text-sm font-medium rounded-xl transition-colors shadow-sm w-full md:w-auto">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-4 h-4 mr-2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" /></svg>
เพิ่มประเภทเจ้าหน้าที่
</button>
</div>
<!-- DataTables CSS for Tailwind -->
<link rel="stylesheet" href="https://cdn.datatables.net/2.0.8/css/dataTables.tailwindcss.css">
<style>
/* DataTables Dark Mode Overrides */
.dark .dt-container { color: #cbd5e1; }
.dark .dt-length select, .dark .dt-search input {
background-color: #1e293b; border-color: #334155; color: #f8fafc; border-radius: 0.5rem; padding: 0.25rem 0.5rem;
}
.dark .dt-info, .dark .dt-paging-button { color: #94a3b8 !important; }
.dark .dt-paging-button.current { background: #38bdf8 !important; color: #0f172a !important; border-color: #38bdf8 !important; }
.dark .dt-paging-button:hover { background: #334155 !important; color: #f8fafc !important; }
table.dataTable.no-footer { border-bottom: 1px solid #334155 !important; }
</style>
<div class="bg-white dark:bg-slate-800 rounded-2xl shadow-sm border border-slate-100 dark:border-slate-700 overflow-hidden p-6">
<div class="overflow-x-hidden">
<table id="mainTable" class="w-full text-left text-sm text-slate-600 dark:text-slate-300 display">
<thead class="bg-slate-50 dark:bg-slate-900/50 text-slate-500 dark:text-slate-400 text-xs uppercase font-semibold">
<tr>
<th class="px-6 py-4">ID</th>
<th class="px-6 py-4">ชื่อประเภทเจ้าหน้าที่</th>
<th class="px-6 py-4 text-center">สถานะ</th>
<th class="px-6 py-4 text-right">จัดการ</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-100 dark:divide-slate-700">
<?php if (empty($officerTypes)): ?>
<tr>
<td colspan="4" class="px-6 py-8 text-center text-slate-500 dark:text-slate-400">
ยังไม่มีข้อมูล
</td>
</tr>
<?php else: ?>
<?php foreach ($officerTypes as $type): ?>
<tr class="hover:bg-slate-50 dark:hover:bg-slate-700/50 transition-colors">
<td class="px-6 py-4 font-mono text-slate-500 dark:text-slate-400">
<?= $type['id'] ?>
</td>
<td class="px-6 py-4">
<div class="font-medium text-slate-800 dark:text-slate-200"><?= htmlspecialchars($type['name']) ?></div>
</td>
<td class="px-6 py-4 text-center">
<form action="<?= BASE_URL ?>/settings/officer-types/toggle" method="POST" class="inline">
<input type="hidden" name="id" value="<?= $type['id'] ?>">
<input type="hidden" name="status" value="<?= $type['is_active'] ? '0' : '1' ?>">
<button type="submit" class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium <?= $type['is_active'] ? 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400' : 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400' ?>">
<?= $type['is_active'] ? 'ใช้งาน' : 'ปิดใช้งาน' ?>
</button>
</form>
</td>
<td class="px-6 py-4 text-right space-x-2">
<button onclick='openEditModal(<?= json_encode($type) ?>)' class="inline-flex items-center px-3 py-1.5 border border-slate-300 dark:border-slate-600 rounded-lg text-xs font-medium text-slate-700 dark:text-slate-300 hover:bg-slate-50 dark:hover:bg-slate-700 transition-colors">
แก้ไข
</button>
<form action="<?= BASE_URL ?>/settings/officer-types/delete" method="POST" class="inline" onsubmit="return confirm('ยืนยันการลบประเภทเจ้าหน้าที่นี้?');">
<input type="hidden" name="id" value="<?= $type['id'] ?>">
<button type="submit" class="inline-flex items-center px-3 py-1.5 border border-red-300 dark:border-red-600/50 rounded-lg text-xs font-medium text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors">
ลบ
</button>
</form>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
<!-- Create Modal -->
<div id="createModal" class="hidden fixed inset-0 z-50 overflow-y-auto">
<div class="fixed inset-0 bg-slate-900/50 backdrop-blur-sm transition-opacity" onclick="document.getElementById('createModal').classList.add('hidden')"></div>
<div class="flex min-h-screen items-center justify-center p-4">
<div class="relative transform overflow-hidden rounded-2xl bg-white dark:bg-slate-800 text-left shadow-xl transition-all sm:w-full sm:max-w-lg border border-slate-100 dark:border-slate-700">
<form action="<?= BASE_URL ?>/settings/officer-types" method="POST">
<div class="p-6">
<h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-6">เพิ่มประเภทเจ้าหน้าที่ใหม่</h3>
<div class="space-y-4">
<div>
<label for="name" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ชื่อประเภทเจ้าหน้าที่</label>
<input type="text" id="name" name="name" required class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-sky-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
</div>
<div class="flex items-center justify-between mt-4">
<label class="flex items-center cursor-pointer">
<div class="relative">
<input type="checkbox" name="is_active" class="sr-only" checked>
<div class="block bg-slate-200 dark:bg-slate-700 w-10 h-6 rounded-full transition-colors"></div>
<div class="dot absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform transform translate-x-full"></div>
</div>
<div class="ml-3 text-sm font-medium text-slate-700 dark:text-slate-300">เปิดใช้งาน</div>
</label>
</div>
</div>
</div>
<div class="bg-slate-50 dark:bg-slate-700/50 px-6 py-4 flex justify-end space-x-3">
<button type="button" onclick="document.getElementById('createModal').classList.add('hidden')" class="px-4 py-2 text-sm font-semibold text-slate-700 dark:text-slate-300 bg-white dark:bg-slate-800 border border-slate-300 dark:border-slate-600 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-700 transition-colors">ยกเลิก</button>
<button type="submit" class="px-4 py-2 text-sm font-semibold text-white bg-sky-500 rounded-xl hover:bg-sky-600 transition-colors">บันทึก</button>
</div>
</form>
</div>
</div>
</div>
<!-- Edit Modal -->
<div id="editModal" class="hidden fixed inset-0 z-50 overflow-y-auto">
<div class="fixed inset-0 bg-slate-900/50 backdrop-blur-sm transition-opacity" onclick="document.getElementById('editModal').classList.add('hidden')"></div>
<div class="flex min-h-screen items-center justify-center p-4">
<div class="relative transform overflow-hidden rounded-2xl bg-white dark:bg-slate-800 text-left shadow-xl transition-all sm:w-full sm:max-w-lg border border-slate-100 dark:border-slate-700">
<form action="<?= BASE_URL ?>/settings/officer-types/update" method="POST">
<input type="hidden" name="id" id="edit_id">
<div class="p-6">
<h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-6">แก้ไขประเภทเจ้าหน้าที่</h3>
<div class="space-y-4">
<div>
<label for="edit_name" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ชื่อประเภทเจ้าหน้าที่</label>
<input type="text" id="edit_name" name="name" required class="block w-full rounded-xl border-0 py-2.5 px-3 text-slate-900 dark:text-white shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 focus:ring-2 focus:ring-sky-500 bg-slate-50 dark:bg-slate-900 sm:text-sm">
</div>
<div class="flex items-center justify-between mt-4">
<label class="flex items-center cursor-pointer">
<div class="relative">
<input type="checkbox" id="edit_is_active" name="is_active" class="sr-only">
<div class="block bg-slate-200 dark:bg-slate-700 w-10 h-6 rounded-full transition-colors"></div>
<div class="dot absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform transform translate-x-full"></div>
</div>
<div class="ml-3 text-sm font-medium text-slate-700 dark:text-slate-300">เปิดใช้งาน</div>
</label>
</div>
</div>
</div>
<div class="bg-slate-50 dark:bg-slate-700/50 px-6 py-4 flex justify-end space-x-3">
<button type="button" onclick="document.getElementById('editModal').classList.add('hidden')" class="px-4 py-2 text-sm font-semibold text-slate-700 dark:text-slate-300 bg-white dark:bg-slate-800 border border-slate-300 dark:border-slate-600 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-700 transition-colors">ยกเลิก</button>
<button type="submit" class="px-4 py-2 text-sm font-semibold text-white bg-sky-500 rounded-xl hover:bg-sky-600 transition-colors">บันทึกการแก้ไข</button>
</div>
</form>
</div>
</div>
</div>
<!-- DataTables JS -->
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://cdn.datatables.net/2.0.8/js/dataTables.js"></script>
<script src="https://cdn.datatables.net/2.0.8/js/dataTables.tailwindcss.js"></script>
<script>
$(document).ready(function() {
$('#mainTable').DataTable({
"language": {
"lengthMenu": "แสดง _MENU_ รายการต่อหน้า",
"zeroRecords": "ไม่พบข้อมูล",
"info": "แสดงหน้าที่ _PAGE_ จาก _PAGES_",
"infoEmpty": "ไม่มีข้อมูล",
"infoFiltered": "(กรองจากทั้งหมด _MAX_ รายการ)",
"search": "ค้นหา:",
"paginate": {
"first": "หน้าแรก",
"last": "หน้าสุดท้าย",
"next": "ถัดไป",
"previous": "ก่อนหน้า"
}
},
"pageLength": 25,
"columnDefs": [
{ "orderable": false, "targets": [3] }
]
});
});
function openEditModal(data) {
document.getElementById('edit_id').value = data.id;
document.getElementById('edit_name').value = data.name;
const isActiveCheckbox = document.getElementById('edit_is_active');
isActiveCheckbox.checked = data.is_active == 1;
// Update toggle UI
const dot = isActiveCheckbox.nextElementSibling.nextElementSibling;
if (data.is_active == 1) {
dot.classList.add('translate-x-full');
dot.previousElementSibling.classList.replace('bg-slate-200', 'bg-sky-500');
dot.previousElementSibling.classList.replace('dark:bg-slate-700', 'dark:bg-sky-500');
} else {
dot.classList.remove('translate-x-full');
dot.previousElementSibling.classList.replace('bg-sky-500', 'bg-slate-200');
dot.previousElementSibling.classList.replace('dark:bg-sky-500', 'dark:bg-slate-700');
}
document.getElementById('editModal').classList.remove('hidden');
}
// Toggle switch logic for both modals
document.querySelectorAll('input[type="checkbox"]').forEach(checkbox => {
checkbox.addEventListener('change', function() {
const dot = this.nextElementSibling.nextElementSibling;
const bg = this.nextElementSibling;
if (this.checked) {
dot.classList.add('translate-x-full');
bg.classList.replace('bg-slate-200', 'bg-sky-500');
bg.classList.replace('dark:bg-slate-700', 'dark:bg-sky-500');
} else {
dot.classList.remove('translate-x-full');
bg.classList.replace('bg-sky-500', 'bg-slate-200');
bg.classList.replace('dark:bg-sky-500', 'dark:bg-slate-700');
}
});
});
</script>
<?php require_once APP_ROOT . '/app/Views/layouts/footer.php'; ?>
@@ -0,0 +1,423 @@
<?php require_once APP_ROOT . '/app/Views/layouts/header.php'; ?>
<div class="p-6">
<div class="mb-6 flex justify-between items-center">
<div>
<h1 class="text-2xl font-bold text-slate-800 dark:text-white">ตั้งค่าระบบทั่วไป</h1>
<p class="text-slate-500 dark:text-slate-400 text-sm mt-1">ตั้งค่ารูปแบบเอกสาร ลายเซ็น และข้อมูลอื่น ๆ ของระบบ</p>
</div>
</div>
<?php if (isset($_SESSION['success'])): ?>
<div class="mb-4 p-4 bg-emerald-50 dark:bg-emerald-900/30 border border-emerald-200 dark:border-emerald-800 text-emerald-600 dark:text-emerald-400 rounded-xl flex items-center shadow-sm">
<svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path></svg>
<?= htmlspecialchars($_SESSION['success']) ?>
</div>
<?php unset($_SESSION['success']); ?>
<?php endif; ?>
<?php if (isset($_SESSION['error'])): ?>
<div class="mb-4 p-4 bg-rose-50 dark:bg-rose-900/30 border border-rose-200 dark:border-rose-800 text-rose-600 dark:text-rose-400 rounded-xl flex items-center shadow-sm">
<svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
<?= htmlspecialchars($_SESSION['error']) ?>
</div>
<?php unset($_SESSION['error']); ?>
<?php endif; ?>
<!-- Tabs Navigation -->
<div class="bg-white dark:bg-slate-800 rounded-t-2xl px-6 pt-4 border-b border-slate-200 dark:border-slate-700 shadow-sm mt-4">
<nav class="-mb-px flex space-x-8" aria-label="Tabs">
<button onclick="switchTab('tab-general')" id="btn-general" class="tab-btn border-sky-500 text-sky-600 dark:text-sky-400 whitespace-nowrap border-b-2 py-4 px-1 text-base font-semibold transition-colors flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 mr-2"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 21h16.5M4.5 3h15M5.25 3v18m13.5-18v18M9 6.75h1.5m-1.5 3h1.5m-1.5 3h1.5m3-6H15m-1.5 3H15m-1.5 3H15M9 21v-3.375c0-.621.504-1.125 1.125-1.125h3.75c.621 0 1.125.504 1.125 1.125V21" /></svg>
ข้อมูลทั่วไป
</button>
<button onclick="switchTab('tab-slip')" id="btn-slip" class="tab-btn border-transparent text-slate-500 hover:text-slate-700 dark:text-slate-400 dark:hover:text-slate-300 whitespace-nowrap border-b-2 py-4 px-1 text-base font-semibold transition-colors flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 mr-2"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 18.75a60.07 60.07 0 0115.797 2.101c.727.198 1.453-.342 1.453-1.096V18.75M3.75 4.5v.75A.75.75 0 013 6h-.75m0 0v-.375c0-.621.504-1.125 1.125-1.125H20.25M2.25 6v9m18-10.5v.75c0 .414.336.75.75.75h.75m-1.5-1.5h.375c.621 0 1.125.504 1.125 1.125v9.75c0 .621-.504 1.125-1.125 1.125h-.375m1.5-1.5H21a.75.75 0 00-.75.75v.75m0 0H3.75m0 0h-.375a1.125 1.125 0 01-1.125-1.125V15m1.5 1.5v-.75A.75.75 0 003 15h-.75M15 10.5a3 3 0 11-6 0 3 3 0 016 0zm3 0h.008v.008H18V10.5zm-12 0h.008v.008H6V10.5z" /></svg>
สลิปเงินเดือน
</button>
<button onclick="switchTab('tab-tax')" id="btn-tax" class="tab-btn border-transparent text-slate-500 hover:text-slate-700 dark:text-slate-400 dark:hover:text-slate-300 whitespace-nowrap border-b-2 py-4 px-1 text-base font-semibold transition-colors flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 mr-2"><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m3.75 9v6m3-3H9m1.5-12H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /></svg>
ใบเสียภาษี (50 ทวิ)
</button>
</nav>
</div>
<!-- MAIN FORM FOR SAVING TEXT SETTINGS -->
<form action="<?= BASE_URL ?>/settings/system/save" method="POST" id="mainSettingsForm"></form>
<!-- Tab 1: General -->
<div id="tab-general" class="tab-content bg-white dark:bg-slate-800 rounded-b-2xl shadow-sm p-6 mb-8 border border-slate-100 dark:border-slate-700 border-t-0">
<div class="max-w-3xl">
<h3 class="text-lg font-bold text-slate-800 dark:text-white mb-6">ข้อมูลทั่วไปของหน่วยงานและระบบ</h3>
<div class="mb-6">
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">เลขประจำตัวผู้เสียภาษีของหน่วยงาน</label>
<input type="text" name="org_tax_id" form="mainSettingsForm" value="<?= htmlspecialchars($orgTaxId ?? '') ?>" placeholder="เช่น 0994000164801"
class="w-full px-4 py-3 border border-slate-200 dark:border-slate-700 rounded-xl bg-slate-50 dark:bg-slate-900 text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-sky-500 transition-all">
<p class="text-xs text-slate-500 mt-2">ข้อมูลนี้จะถูกนำไปแสดงในหนังสือรับรองการหักภาษี ณ ที่จ่าย (50 ทวิ)</p>
</div>
<div class="mb-6">
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">เวอร์ชันของระบบ (App Version)</label>
<input type="text" name="app_version" form="mainSettingsForm" value="<?= htmlspecialchars($appVersion ?? '1.0.0') ?>" placeholder="เช่น 1.0.0"
class="w-full px-4 py-3 border border-slate-200 dark:border-slate-700 rounded-xl bg-slate-50 dark:bg-slate-900 text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-sky-500 transition-all">
<p class="text-xs text-slate-500 mt-2">เลขเวอร์ชันที่จะแสดงในหน้าต่างๆ ของระบบ เช่น หน้าล็อกอิน หรือส่วนท้ายเว็บ</p>
</div>
<div class="mb-8">
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">แสดงปีย้อนหลังในกราฟ Dashboard (จำนวนปี)</label>
<input type="number" name="chart_history_years" form="mainSettingsForm" value="<?= htmlspecialchars($chartHistoryYears ?? '3') ?>" min="1" max="10"
class="w-full px-4 py-3 border border-slate-200 dark:border-slate-700 rounded-xl bg-slate-50 dark:bg-slate-900 text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-sky-500 transition-all">
</div>
<hr class="border-slate-100 dark:border-slate-700 mb-6">
<button type="submit" form="mainSettingsForm" class="px-6 py-3 bg-sky-600 hover:bg-sky-700 text-white rounded-xl text-sm font-semibold transition-colors shadow flex items-center justify-center w-full md:w-auto">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5 mr-2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" /></svg>
บันทึกการตั้งค่าข้อมูลทั่วไป
</button>
</div>
</div>
<!-- Tab 2: Salary Slip -->
<div id="tab-slip" class="tab-content hidden bg-white dark:bg-slate-800 rounded-b-2xl shadow-sm p-6 mb-8 border border-slate-100 dark:border-slate-700 border-t-0">
<h3 class="text-lg font-bold text-slate-800 dark:text-white mb-6">ตั้งค่าสลิปเงินเดือน</h3>
<div class="mb-8 max-w-xl">
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ขนาดตัวอักษรสลิปเงินเดือน</label>
<select name="slip_font_size" form="mainSettingsForm" class="w-full px-4 py-3 border border-slate-200 dark:border-slate-700 rounded-xl bg-slate-50 dark:bg-slate-900 text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-sky-500 transition-all">
<option value="10pt" <?= ($slipFontSize ?? '11pt') === '10pt' ? 'selected' : '' ?>>10pt (เล็ก)</option>
<option value="11pt" <?= ($slipFontSize ?? '11pt') === '11pt' ? 'selected' : '' ?>>11pt (มาตรฐาน)</option>
<option value="12pt" <?= ($slipFontSize ?? '11pt') === '12pt' ? 'selected' : '' ?>>12pt (ใหญ่)</option>
<option value="14pt" <?= ($slipFontSize ?? '11pt') === '14pt' ? 'selected' : '' ?>>14pt (ใหญ่มาก)</option>
</select>
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<!-- Details & Positioning -->
<div>
<h4 class="text-md font-semibold text-slate-700 dark:text-slate-300 mb-4 border-b border-slate-100 dark:border-slate-700 pb-2">รายละเอียดข้อความใต้ลายเซ็น</h4>
<div class="mb-4 relative">
<label class="block text-xs text-slate-500 mb-1">ค้นหาเจ้าหน้าที่จากระบบ HR (ตัวช่วยเติมคำ)</label>
<input type="text" id="officerSearch" placeholder="พิมพ์ชื่อ, นามสกุล หรือเลขบัตร ปชช. เพื่อค้นหา..."
class="w-full px-4 py-2 border border-slate-200 dark:border-slate-700 rounded-lg bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-sky-500 transition-all">
<ul id="searchResults" class="absolute z-10 w-full bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-lg mt-1 max-h-60 overflow-y-auto hidden shadow-lg"></ul>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ชื่อ-สกุล</label>
<input type="text" id="signature_name" name="signature_name" form="mainSettingsForm" value="<?= htmlspecialchars($signatureName ?? '') ?>" placeholder="เช่น ( นางณัฐฐิณี เรืองทอง )"
class="w-full px-4 py-3 border border-slate-200 dark:border-slate-700 rounded-xl bg-slate-50 dark:bg-slate-900 text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-sky-500 transition-all">
</div>
<div class="mb-8">
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ตำแหน่ง</label>
<input type="text" id="signature_position" name="signature_position" form="mainSettingsForm" value="<?= htmlspecialchars($signaturePosition ?? '') ?>" placeholder="เช่น นักวิชาการเงินและบัญชี"
class="w-full px-4 py-3 border border-slate-200 dark:border-slate-700 rounded-xl bg-slate-50 dark:bg-slate-900 text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-sky-500 transition-all">
</div>
<h4 class="text-md font-semibold text-slate-700 dark:text-slate-300 mb-4 border-b border-slate-100 dark:border-slate-700 pb-2">การจัดตำแหน่งรูปลายเซ็น</h4>
<div class="mb-6">
<label class="flex justify-between items-center text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
<span>ขนาดรูปลายเซ็น (Scale)</span>
<span id="scaleValue" class="text-sky-600 font-bold bg-sky-50 dark:bg-sky-900/40 px-2 py-1 rounded"><?= htmlspecialchars($signatureScale ?? '100') ?>%</span>
</label>
<input type="range" name="signature_scale" form="mainSettingsForm" min="50" max="200" step="5" value="<?= htmlspecialchars($signatureScale ?? '100') ?>"
oninput="document.getElementById('scaleValue').innerText = this.value + '%'"
class="w-full h-2 bg-slate-200 rounded-lg appearance-none cursor-pointer dark:bg-slate-700 accent-sky-500">
</div>
<div class="grid grid-cols-2 gap-4 mb-6">
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ขยับซ้าย-ขวา (px)</label>
<input type="number" name="signature_pos_x" form="mainSettingsForm" value="<?= htmlspecialchars($signaturePosX ?? '0') ?>"
class="w-full px-4 py-3 border border-slate-200 dark:border-slate-700 rounded-xl bg-slate-50 dark:bg-slate-900 text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-sky-500 transition-all">
</div>
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ขยับขึ้น-ลง (px)</label>
<input type="number" name="signature_pos_y" form="mainSettingsForm" value="<?= htmlspecialchars($signaturePosY ?? '0') ?>"
class="w-full px-4 py-3 border border-slate-200 dark:border-slate-700 rounded-xl bg-slate-50 dark:bg-slate-900 text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-sky-500 transition-all">
</div>
</div>
<button type="submit" form="mainSettingsForm" class="w-full px-6 py-3 bg-sky-600 hover:bg-sky-700 text-white rounded-xl text-sm font-semibold transition-colors shadow flex items-center justify-center mt-6">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5 mr-2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" /></svg>
บันทึกการตั้งค่าสลิปเงินเดือน
</button>
</div>
<!-- Upload Signature (Separate Form) -->
<div>
<h4 class="text-md font-semibold text-slate-700 dark:text-slate-300 mb-4 border-b border-slate-100 dark:border-slate-700 pb-2">อัปโหลดลายเซ็นใหม่</h4>
<div class="mb-6">
<p class="text-sm text-slate-600 dark:text-slate-400 mb-2">รูปลายเซ็นปัจจุบัน</p>
<div class="border-2 border-dashed border-slate-300 dark:border-slate-600 rounded-xl p-4 flex justify-center items-center bg-slate-50 dark:bg-slate-900/50 min-h-[150px]">
<?php
$sigPath = APP_ROOT . '/public/img/signature.png';
if (file_exists($sigPath)):
$modTime = filemtime($sigPath);
?>
<img src="<?= BASE_URL ?>/public/img/signature.png?t=<?= $modTime ?>" alt="Current Signature" class="max-h-32 object-contain mix-blend-multiply dark:mix-blend-normal">
<?php else: ?>
<div class="text-slate-400 dark:text-slate-500 flex flex-col items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-8 h-8 mb-2"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg>
<span>ยังไม่มีรูปภาพลายเซ็น</span>
</div>
<?php endif; ?>
</div>
</div>
<form action="<?= BASE_URL ?>/settings/system" method="POST" enctype="multipart/form-data" class="bg-slate-50 dark:bg-slate-800/50 p-4 rounded-xl border border-slate-200 dark:border-slate-700">
<div class="mb-4">
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">เลือกไฟล์รูปภาพ (JPG/PNG)</label>
<input type="file" name="signature" accept="image/jpeg, image/png" required
class="block w-full text-sm text-slate-500 dark:text-slate-400
file:mr-4 file:py-2 file:px-4
file:rounded-lg file:border-0
file:text-sm file:font-medium
file:bg-sky-50 file:text-sky-700
dark:file:bg-sky-900/30 dark:file:text-sky-400
hover:file:bg-sky-100 dark:hover:file:bg-sky-900/50
transition-colors cursor-pointer border border-slate-200 dark:border-slate-700 rounded-lg p-2 bg-white dark:bg-slate-900">
</div>
<button type="submit" class="w-full px-4 py-2 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg text-sm font-medium transition-colors shadow-sm flex justify-center items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" 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 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5" /></svg>
อัปโหลดลายเซ็นสลิป
</button>
</form>
</div>
</div>
</div>
<!-- Tab 3: Tax Certificate -->
<div id="tab-tax" class="tab-content hidden bg-white dark:bg-slate-800 rounded-b-2xl shadow-sm p-6 mb-8 border border-slate-100 dark:border-slate-700 border-t-0">
<h3 class="text-lg font-bold text-slate-800 dark:text-white mb-6">ตั้งค่าหนังสือรับรองการหักภาษี ณ ที่จ่าย (50 ทวิ)</h3>
<div class="mb-8 max-w-xl">
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ขนาดตัวอักษรใบเสียภาษี</label>
<select name="tax_font_size" form="mainSettingsForm" class="w-full px-4 py-3 border border-slate-200 dark:border-slate-700 rounded-xl bg-slate-50 dark:bg-slate-900 text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-sky-500 transition-all">
<option value="10pt" <?= ($taxFontSize ?? '11pt') === '10pt' ? 'selected' : '' ?>>10pt (เล็ก)</option>
<option value="11pt" <?= ($taxFontSize ?? '11pt') === '11pt' ? 'selected' : '' ?>>11pt (มาตรฐาน)</option>
<option value="12pt" <?= ($taxFontSize ?? '11pt') === '12pt' ? 'selected' : '' ?>>12pt (ใหญ่)</option>
<option value="14pt" <?= ($taxFontSize ?? '11pt') === '14pt' ? 'selected' : '' ?>>14pt (ใหญ่มาก)</option>
</select>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ที่อยู่ผู้มีหน้าที่หักภาษี (หน่วยงาน)</label>
<textarea name="org_address" form="mainSettingsForm" rows="2" placeholder="ต.อ่างทอง อ.เกาะสมุย จ.สุราษฎร์ธานี 84140"
class="w-full px-4 py-3 border border-slate-200 dark:border-slate-700 rounded-xl bg-slate-50 dark:bg-slate-900 text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-sky-500 transition-all"><?= htmlspecialchars($orgAddress ?? '') ?></textarea>
</div>
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ที่อยู่ผู้ถูกหักภาษี (ค่าเริ่มต้น)</label>
<textarea name="tax_payee_address" form="mainSettingsForm" rows="2" placeholder="ต.อ่างทอง อ.เกาะสมุย จ.สุราษฎร์ธานี 84140"
class="w-full px-4 py-3 border border-slate-200 dark:border-slate-700 rounded-xl bg-slate-50 dark:bg-slate-900 text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-sky-500 transition-all"><?= htmlspecialchars($taxPayeeAddress ?? '') ?></textarea>
</div>
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<!-- Details & Positioning -->
<div>
<h4 class="text-md font-semibold text-slate-700 dark:text-slate-300 mb-4 border-b border-slate-100 dark:border-slate-700 pb-2">รายละเอียดข้อความใต้ลายเซ็น</h4>
<div class="mb-4 relative">
<label class="block text-xs text-slate-500 mb-1">ค้นหาเจ้าหน้าที่จากระบบ HR (ตัวช่วยเติมคำ)</label>
<input type="text" id="taxOfficerSearch" placeholder="พิมพ์ชื่อ, นามสกุล หรือเลขบัตร ปชช. เพื่อค้นหา..."
class="w-full px-4 py-2 border border-slate-200 dark:border-slate-700 rounded-lg bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-sky-500 transition-all">
<ul id="taxSearchResults" class="absolute z-10 w-full bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-lg mt-1 max-h-60 overflow-y-auto hidden shadow-lg"></ul>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ชื่อ-สกุล</label>
<input type="text" id="tax_signature_name" name="tax_signature_name" form="mainSettingsForm" value="<?= htmlspecialchars($taxSignatureName ?? '') ?>" placeholder="เช่น ( นางสาวกมลวรรณ บุญบวร )"
class="w-full px-4 py-3 border border-slate-200 dark:border-slate-700 rounded-xl bg-slate-50 dark:bg-slate-900 text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-sky-500 transition-all">
</div>
<div class="mb-8">
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ตำแหน่ง</label>
<input type="text" id="tax_signature_position" name="tax_signature_position" form="mainSettingsForm" value="<?= htmlspecialchars($taxSignaturePosition ?? '') ?>" placeholder="เช่น นักวิชาการเงินและบัญชีปฏิบัติการ"
class="w-full px-4 py-3 border border-slate-200 dark:border-slate-700 rounded-xl bg-slate-50 dark:bg-slate-900 text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-sky-500 transition-all">
</div>
<h4 class="text-md font-semibold text-slate-700 dark:text-slate-300 mb-4 border-b border-slate-100 dark:border-slate-700 pb-2">การจัดตำแหน่งรูปลายเซ็น</h4>
<div class="mb-6">
<label class="flex justify-between items-center text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
<span>ขนาดรูปลายเซ็น (Scale)</span>
<span id="taxScaleValue" class="text-sky-600 font-bold bg-sky-50 dark:bg-sky-900/40 px-2 py-1 rounded"><?= htmlspecialchars($taxSignatureScale ?? '100') ?>%</span>
</label>
<input type="range" name="tax_signature_scale" form="mainSettingsForm" min="50" max="200" step="5" value="<?= htmlspecialchars($taxSignatureScale ?? '100') ?>"
oninput="document.getElementById('taxScaleValue').innerText = this.value + '%'"
class="w-full h-2 bg-slate-200 rounded-lg appearance-none cursor-pointer dark:bg-slate-700 accent-sky-500">
</div>
<div class="grid grid-cols-2 gap-4 mb-6">
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ขยับซ้าย-ขวา (px)</label>
<input type="number" name="tax_signature_pos_x" form="mainSettingsForm" value="<?= htmlspecialchars($taxSignaturePosX ?? '0') ?>"
class="w-full px-4 py-3 border border-slate-200 dark:border-slate-700 rounded-xl bg-slate-50 dark:bg-slate-900 text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-sky-500 transition-all">
</div>
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">ขยับขึ้น-ลง (px)</label>
<input type="number" name="tax_signature_pos_y" form="mainSettingsForm" value="<?= htmlspecialchars($taxSignaturePosY ?? '0') ?>"
class="w-full px-4 py-3 border border-slate-200 dark:border-slate-700 rounded-xl bg-slate-50 dark:bg-slate-900 text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-sky-500 transition-all">
</div>
</div>
<button type="submit" form="mainSettingsForm" class="w-full px-6 py-3 bg-sky-600 hover:bg-sky-700 text-white rounded-xl text-sm font-semibold transition-colors shadow flex items-center justify-center mt-6">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5 mr-2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" /></svg>
บันทึกการตั้งค่าใบเสียภาษี
</button>
</div>
<!-- Upload Signature (Separate Form) -->
<div>
<h4 class="text-md font-semibold text-slate-700 dark:text-slate-300 mb-4 border-b border-slate-100 dark:border-slate-700 pb-2">อัปโหลดลายเซ็นใหม่</h4>
<div class="mb-6">
<p class="text-sm text-slate-600 dark:text-slate-400 mb-2">รูปลายเซ็นปัจจุบัน</p>
<div class="border-2 border-dashed border-slate-300 dark:border-slate-600 rounded-xl p-4 flex justify-center items-center bg-slate-50 dark:bg-slate-900/50 min-h-[150px]">
<?php
$taxSigPath = APP_ROOT . '/public/img/tax_signature.png';
if (file_exists($taxSigPath)):
$modTime = filemtime($taxSigPath);
?>
<img src="<?= BASE_URL ?>/public/img/tax_signature.png?t=<?= $modTime ?>" alt="Tax Signature" class="max-h-32 object-contain mix-blend-multiply dark:mix-blend-normal">
<?php else: ?>
<div class="text-slate-400 dark:text-slate-500 flex flex-col items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-8 h-8 mb-2"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg>
<span>ยังไม่มีรูปภาพลายเซ็นใบเสียภาษี</span>
</div>
<?php endif; ?>
</div>
</div>
<form action="<?= BASE_URL ?>/settings/system/upload-tax-signature" method="POST" enctype="multipart/form-data" class="bg-slate-50 dark:bg-slate-800/50 p-4 rounded-xl border border-slate-200 dark:border-slate-700">
<div class="mb-4">
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">เลือกไฟล์รูปภาพ (JPG/PNG)</label>
<input type="file" name="tax_signature" accept="image/jpeg, image/png" required
class="block w-full text-sm text-slate-500 dark:text-slate-400
file:mr-4 file:py-2 file:px-4
file:rounded-lg file:border-0
file:text-sm file:font-medium
file:bg-sky-50 file:text-sky-700
dark:file:bg-sky-900/30 dark:file:text-sky-400
hover:file:bg-sky-100 dark:hover:file:bg-sky-900/50
transition-colors cursor-pointer border border-slate-200 dark:border-slate-700 rounded-lg p-2 bg-white dark:bg-slate-900">
</div>
<button type="submit" class="w-full px-4 py-2 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg text-sm font-medium transition-colors shadow-sm flex justify-center items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" 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 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5" /></svg>
อัปโหลดลายเซ็นใบเสียภาษี
</button>
</form>
</div>
</div>
</div>
</div>
<script>
// Tab Switching Logic
function switchTab(tabId) {
// Hide all tab contents
document.querySelectorAll('.tab-content').forEach(el => el.classList.add('hidden'));
// Show target tab
document.getElementById(tabId).classList.remove('hidden');
// Reset all buttons
document.querySelectorAll('.tab-btn').forEach(el => {
el.classList.remove('border-sky-500', 'text-sky-600', 'dark:text-sky-400');
el.classList.add('border-transparent', 'text-slate-500');
});
// Activate target button
const activeBtn = document.getElementById(tabId.replace('tab-', 'btn-'));
if (activeBtn) {
activeBtn.classList.remove('border-transparent', 'text-slate-500');
activeBtn.classList.add('border-sky-500', 'text-sky-600', 'dark:text-sky-400');
}
// Save state to localStorage to remember tab after form submit
localStorage.setItem('activeSettingsTab', tabId);
}
document.addEventListener('DOMContentLoaded', function() {
// Restore active tab
const savedTab = localStorage.getItem('activeSettingsTab') || 'tab-general';
switchTab(savedTab);
// HR Search logic
const searchInput = document.getElementById('officerSearch');
const searchResults = document.getElementById('searchResults');
const nameInput = document.getElementById('signature_name');
const positionInput = document.getElementById('signature_position');
const taxSearchInput = document.getElementById('taxOfficerSearch');
const taxSearchResults = document.getElementById('taxSearchResults');
const taxNameInput = document.getElementById('tax_signature_name');
const taxPositionInput = document.getElementById('tax_signature_position');
let debounceTimer;
let taxDebounceTimer;
function setupSearch(inputEl, resultsEl, nameEl, posEl, timer) {
inputEl.addEventListener('input', function() {
clearTimeout(timer);
const keyword = this.value.trim();
if (keyword.length < 2) {
resultsEl.classList.add('hidden');
return;
}
timer = setTimeout(function() {
fetch('<?= BASE_URL ?>/settings/system/search-officer?q=' + encodeURIComponent(keyword))
.then(response => {
if (!response.ok) throw new Error('Network error ' + response.status);
return response.text();
})
.then(text => {
let res;
try {
res = JSON.parse(text);
} catch (e) {
console.error('Invalid JSON from server:', text);
alert('เกิดข้อผิดพลาดในการดึงข้อมูลจากเซิร์ฟเวอร์\nกรุณาดูรายละเอียดใน Console');
return;
}
resultsEl.innerHTML = '';
if (res.status === 'success' && res.data && res.data.length > 0) {
res.data.forEach(item => {
const li = document.createElement('li');
li.className = 'px-4 py-2 hover:bg-sky-50 dark:hover:bg-slate-700 cursor-pointer text-sm text-slate-700 dark:text-slate-300 border-b border-slate-100 dark:border-slate-700 last:border-0';
li.textContent = item.text;
li.addEventListener('click', function() {
nameEl.value = '( ' + item.name + ' )';
posEl.value = item.position;
inputEl.value = '';
resultsEl.classList.add('hidden');
});
resultsEl.appendChild(li);
});
resultsEl.classList.remove('hidden');
} else {
const li = document.createElement('li');
li.className = 'px-4 py-2 text-sm text-slate-500 dark:text-slate-400 italic';
li.textContent = res.message || 'ไม่พบข้อมูล';
resultsEl.appendChild(li);
resultsEl.classList.remove('hidden');
}
})
.catch(error => {
console.error('Error searching:', error);
});
}, 300);
});
document.addEventListener('click', function(e) {
if (!inputEl.contains(e.target) && !resultsEl.contains(e.target)) {
resultsEl.classList.add('hidden');
}
});
}
if (searchInput) setupSearch(searchInput, searchResults, nameInput, positionInput, debounceTimer);
if (taxSearchInput) setupSearch(taxSearchInput, taxSearchResults, taxNameInput, taxPositionInput, taxDebounceTimer);
});
</script>
<?php require_once APP_ROOT . '/app/Views/layouts/footer.php'; ?>