906 lines
57 KiB
HTML
906 lines
57 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="th">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>HR System Dashboard</title>
|
|
|
|
<!-- Google Fonts: Sarabun -->
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Sarabun:wght@300;400;500;600;700&display=swap"
|
|
rel="stylesheet">
|
|
|
|
<!-- Material Symbols Outlined (Stable icons alternative) -->
|
|
<link rel="stylesheet"
|
|
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
|
|
|
|
<!-- Tailwind CSS -->
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
|
|
<!-- Tailwind Config & Custom CSS -->
|
|
<script>
|
|
tailwind.config = {
|
|
theme: {
|
|
extend: {
|
|
fontFamily: {
|
|
sans: ['Sarabun', 'sans-serif'],
|
|
},
|
|
colors: {
|
|
brand: {
|
|
dark: '#144b94', /* สีน้ำเงินเข้ม */
|
|
primary: '#1e68c9', /* สีน้ำเงินเมนู */
|
|
light: '#f4f6f9', /* สีเทาอ่อน */
|
|
bg: '#eef2f6' /* สีพื้นหลัง */
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
<style type="text/tailwindcss">
|
|
@layer utilities {
|
|
/* ซ่อน Scrollbar */
|
|
.no-scrollbar::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
.no-scrollbar {
|
|
-ms-overflow-style: none; /* IE and Edge */
|
|
scrollbar-width: none; /* Firefox */
|
|
}
|
|
|
|
/* Logo Shine Effect */
|
|
@keyframes shine {
|
|
0% { left: -100%; }
|
|
20% { left: 100%; }
|
|
100% { left: 100%; }
|
|
}
|
|
.shine-effect {
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
.shine-effect::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: -100%;
|
|
width: 50%;
|
|
height: 100%;
|
|
background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.6) 50%, rgba(255,255,255,0) 100%);
|
|
transform: skewX(-25deg);
|
|
animation: shine 4s infinite;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body class="bg-brand-bg font-sans h-screen flex flex-col overflow-hidden text-gray-800 text-sm">
|
|
|
|
<!-- ================= STREAMING_CHUNK:Rendering Header ================= -->
|
|
<header class="bg-brand-dark text-white h-[45px] shrink-0 flex items-center px-4 justify-between shadow-md z-30">
|
|
<!-- Logo System -->
|
|
<div class="flex items-center gap-3">
|
|
<div class="bg-white px-2 py-0.5 rounded-sm shine-effect flex items-center justify-center">
|
|
<img src="https://samuihospital.moph.go.th/dashboard/waiting/assets/img/logo.png" alt="Logo"
|
|
class="h-8 object-contain drop-shadow-sm">
|
|
</div>
|
|
<span class="font-semibold text-[15px] tracking-wide">ระบบ HR • HR System</span>
|
|
</div>
|
|
|
|
<!-- User Profile & Notifications -->
|
|
<div class="flex items-center gap-4">
|
|
<div class="relative cursor-pointer hover:text-gray-200 transition">
|
|
<span class="material-symbols-outlined text-xl">notifications</span>
|
|
<span
|
|
class="absolute -top-1 -right-1 bg-red-500 text-white text-[10px] w-4 h-4 rounded-full flex items-center justify-center font-bold">1</span>
|
|
</div>
|
|
<div
|
|
class="flex items-center gap-2 bg-black/10 px-3 py-1 rounded cursor-pointer hover:bg-black/20 transition">
|
|
<div
|
|
class="w-6 h-6 bg-white text-brand-dark flex items-center justify-center rounded text-xs font-bold">
|
|
A</div>
|
|
<span class="text-sm">admin admin</span>
|
|
<span class="material-symbols-outlined text-sm">expand_more</span>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- ================= STREAMING_CHUNK:Rendering Sub Menu Bar ================= -->
|
|
<div class="bg-brand-light border-b border-gray-300 flex w-full shrink-0 z-20 h-fit overflow-x-auto no-scrollbar">
|
|
|
|
<!-- Group 1: เริ่มต้นใช้งาน (Fix width 240px เพื่อให้เส้นคั่นตรงกับ Sidebar ซ้าย) -->
|
|
<div
|
|
class="w-[240px] shrink-0 border-r border-gray-300 flex flex-col py-1.5 items-center justify-center bg-white/50">
|
|
<div class="flex gap-6 pt-1">
|
|
<div class="group flex flex-col items-center cursor-pointer text-brand-primary">
|
|
<span
|
|
class="material-symbols-outlined text-3xl mb-1 transition-all duration-300 group-hover:-translate-y-1 group-hover:scale-110 group-hover:drop-shadow-md">home</span>
|
|
<span class="text-[11px] group-hover:font-semibold">หน้าหลัก</span>
|
|
</div>
|
|
<div
|
|
class="group flex flex-col items-center cursor-pointer text-gray-500 hover:text-brand-primary transition-colors">
|
|
<span
|
|
class="material-symbols-outlined text-3xl mb-1 transition-all duration-300 group-hover:-translate-y-1 group-hover:scale-110 group-hover:drop-shadow-md">person_add</span>
|
|
<span class="text-[11px]">เพิ่มพนักงาน</span>
|
|
</div>
|
|
<div
|
|
class="group flex flex-col items-center cursor-pointer text-gray-500 hover:text-brand-primary transition-colors">
|
|
<span
|
|
class="material-symbols-outlined text-3xl mb-1 transition-all duration-300 group-hover:-translate-y-1 group-hover:scale-110 group-hover:drop-shadow-md">schedule</span>
|
|
<span class="text-[11px]">เช็คอิน</span>
|
|
</div>
|
|
</div>
|
|
<div class="text-[10px] text-gray-400 mt-1 uppercase tracking-wide">เริ่มต้นใช้งาน</div>
|
|
</div>
|
|
|
|
<!-- Group 2: การเงิน-เอกสาร -->
|
|
<div class="flex-1 min-w-max border-r border-gray-300 flex flex-col py-1.5 items-center px-6">
|
|
<div class="flex gap-8 pt-1">
|
|
<div
|
|
class="group flex flex-col items-center cursor-pointer text-gray-500 hover:text-brand-primary transition-colors">
|
|
<span
|
|
class="material-symbols-outlined text-3xl mb-1 transition-all duration-300 group-hover:-translate-y-1 group-hover:scale-110 group-hover:drop-shadow-md">assignment</span>
|
|
<span class="text-[11px]">ขอลา</span>
|
|
</div>
|
|
<div
|
|
class="group flex flex-col items-center cursor-pointer text-gray-500 hover:text-brand-primary transition-colors">
|
|
<span
|
|
class="material-symbols-outlined text-3xl mb-1 transition-all duration-300 group-hover:-translate-y-1 group-hover:scale-110 group-hover:drop-shadow-md">payments</span>
|
|
<span class="text-[11px]">เงินเดือน</span>
|
|
</div>
|
|
<div
|
|
class="group flex flex-col items-center cursor-pointer text-gray-500 hover:text-brand-primary transition-colors">
|
|
<span
|
|
class="material-symbols-outlined text-3xl mb-1 transition-all duration-300 group-hover:-translate-y-1 group-hover:scale-110 group-hover:drop-shadow-md">receipt_long</span>
|
|
<span class="text-[11px]">สลิป</span>
|
|
</div>
|
|
<div
|
|
class="group flex flex-col items-center cursor-pointer text-gray-500 hover:text-brand-primary transition-colors">
|
|
<span
|
|
class="material-symbols-outlined text-3xl mb-1 transition-all duration-300 group-hover:-translate-y-1 group-hover:scale-110 group-hover:drop-shadow-md">folder_open</span>
|
|
<span class="text-[11px]">เอกสาร</span>
|
|
</div>
|
|
<div
|
|
class="group flex flex-col items-center cursor-pointer text-gray-500 hover:text-brand-primary transition-colors">
|
|
<span
|
|
class="material-symbols-outlined text-3xl mb-1 transition-all duration-300 group-hover:-translate-y-1 group-hover:scale-110 group-hover:drop-shadow-md">account_balance</span>
|
|
<span class="text-[11px]">ภาครัฐ</span>
|
|
</div>
|
|
</div>
|
|
<div class="text-[10px] text-gray-400 mt-1 uppercase tracking-wide">การเงิน-เอกสาร</div>
|
|
</div>
|
|
|
|
<!-- Group 3: รายงาน-ตั้งค่า -->
|
|
<div class="border-r border-gray-300 flex flex-col py-1.5 items-center px-6 shrink-0">
|
|
<div class="flex gap-6 pt-1">
|
|
<div
|
|
class="group flex flex-col items-center cursor-pointer text-gray-500 hover:text-brand-primary transition-colors">
|
|
<span
|
|
class="material-symbols-outlined text-3xl mb-1 transition-all duration-300 group-hover:-translate-y-1 group-hover:scale-110 group-hover:drop-shadow-md">bar_chart</span>
|
|
<span class="text-[11px]">รายงาน</span>
|
|
</div>
|
|
<div
|
|
class="group flex flex-col items-center cursor-pointer text-gray-500 hover:text-brand-primary transition-colors">
|
|
<span
|
|
class="material-symbols-outlined text-3xl mb-1 transition-all duration-300 group-hover:-translate-y-1 group-hover:scale-110 group-hover:drop-shadow-md">account_tree</span>
|
|
<span class="text-[11px]">ผังองค์กร</span>
|
|
</div>
|
|
<div
|
|
class="group flex flex-col items-center cursor-pointer text-gray-500 hover:text-brand-primary transition-colors">
|
|
<span
|
|
class="material-symbols-outlined text-3xl mb-1 transition-all duration-300 group-hover:-translate-y-1 group-hover:scale-110 group-hover:drop-shadow-md">settings</span>
|
|
<span class="text-[11px]">ตั้งค่า</span>
|
|
</div>
|
|
</div>
|
|
<div class="text-[10px] text-gray-400 mt-1 uppercase tracking-wide">รายงาน-ตั้งค่า</div>
|
|
</div>
|
|
|
|
<!-- Group 4 & 5: คู่มือ, บัญชี -->
|
|
<div class="flex items-stretch shrink-0">
|
|
<div class="border-r border-gray-300 flex flex-col py-1.5 items-center px-4">
|
|
<div
|
|
class="group flex flex-col items-center cursor-pointer text-gray-500 hover:text-brand-primary transition-colors pt-1">
|
|
<span
|
|
class="material-symbols-outlined text-3xl mb-1 transition-all duration-300 group-hover:-translate-y-1 group-hover:scale-110 group-hover:drop-shadow-md">menu_book</span>
|
|
<span class="text-[11px]">คู่มือระบบ HR</span>
|
|
</div>
|
|
<div class="text-[10px] text-gray-400 mt-1 uppercase tracking-wide">คู่มือ</div>
|
|
</div>
|
|
<div class="flex flex-col py-1.5 items-center px-4">
|
|
<div
|
|
class="group flex flex-col items-center cursor-pointer text-red-500 hover:text-red-700 transition-colors pt-1">
|
|
<span
|
|
class="material-symbols-outlined text-3xl mb-1 transition-all duration-300 group-hover:-translate-y-1 group-hover:scale-110 group-hover:drop-shadow-md">logout</span>
|
|
<span class="text-[11px]">ออกจากระบบ</span>
|
|
</div>
|
|
<div class="text-[10px] text-gray-400 mt-1 uppercase tracking-wide">บัญชี</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ================= STREAMING_CHUNK:Rendering Main Content Area ================= -->
|
|
<main class="flex-1 flex overflow-hidden">
|
|
|
|
<!-- ======= Left Sidebar (240px Fixed) ======= -->
|
|
<aside
|
|
class="w-[240px] shrink-0 bg-[#fbfcfd] border-r border-gray-300 flex flex-col overflow-y-auto no-scrollbar">
|
|
<!-- Header -->
|
|
<div
|
|
class="p-2 border-b border-gray-300 bg-gray-100 flex items-center gap-2 text-brand-dark font-medium font-semibold text-sm">
|
|
<span class="material-symbols-outlined text-lg">apps</span> เมนูหลัก
|
|
</div>
|
|
|
|
<!-- Menu Accordion -->
|
|
<div class="flex flex-col text-[13px]">
|
|
|
|
<!-- Item 1: หน้าหลัก -->
|
|
<div class="border-b border-gray-300">
|
|
<div class="flex items-center justify-between px-3 py-2 cursor-pointer bg-brand-primary text-white">
|
|
<div class="flex items-center gap-2">
|
|
<span class="material-symbols-outlined text-sm border-l-2 border-white pl-1">home</span>
|
|
หน้าหลัก
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Item 2 -->
|
|
<div class="border-b border-gray-300">
|
|
<div class="flex items-center px-3 py-2 cursor-pointer hover:bg-gray-100 text-gray-700 transition">
|
|
<div class="flex items-center gap-2">
|
|
<span class="material-symbols-outlined text-sm text-gray-400">badge</span> ข้อมูลประจำตัว
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Item 3: โมดูลพนักงาน (Accordion เปิดอยู่) -->
|
|
<div class="border-b border-gray-300">
|
|
<div class="flex items-center justify-between px-3 py-2 cursor-pointer bg-gray-200/50 text-gray-800 font-medium"
|
|
onclick="toggleMenu('submenu-emp')">
|
|
<div class="flex items-center gap-2 border-l-2 border-brand-primary pl-1">
|
|
โมดูลพนักงาน
|
|
</div>
|
|
<span class="material-symbols-outlined text-sm text-gray-500"
|
|
id="icon-submenu-emp">arrow_drop_up</span>
|
|
</div>
|
|
<div id="submenu-emp" class="flex flex-col bg-white">
|
|
<a href="#"
|
|
class="flex items-center gap-2 px-6 py-2 hover:bg-brand-light text-gray-700 transition">
|
|
<span class="material-symbols-outlined text-sm text-gray-400">group</span> 1. ข้อมูลพนักงาน
|
|
</a>
|
|
<a href="#"
|
|
class="flex items-center gap-2 px-6 py-2 bg-brand-light text-brand-primary font-medium border-r-2 border-brand-primary transition">
|
|
<span class="material-symbols-outlined text-sm">schedule</span> 2. เช็คอิน/เช็คเอ้าท์
|
|
</a>
|
|
<div class="flex flex-col ml-10 border-l border-gray-200 my-1 py-1">
|
|
<a href="#"
|
|
class="flex items-center gap-2 px-4 py-1.5 hover:bg-gray-50 text-gray-600 text-[12px] transition">
|
|
<span
|
|
class="material-symbols-outlined text-xs text-gray-400">format_list_bulleted</span>
|
|
ดูประวัติย้อนหลัง
|
|
</a>
|
|
<a href="#"
|
|
class="flex items-center gap-2 px-4 py-1.5 hover:bg-gray-50 text-gray-600 text-[12px] transition">
|
|
<span class="material-symbols-outlined text-xs text-gray-400">calendar_month</span>
|
|
ตารางกะการทำงาน
|
|
</a>
|
|
<a href="#"
|
|
class="flex items-center gap-2 px-4 py-1.5 hover:bg-gray-50 text-gray-600 text-[12px] transition">
|
|
<span class="material-symbols-outlined text-xs text-gray-400">edit_square</span>
|
|
คำขอปรับปรุงเวลา
|
|
</a>
|
|
<a href="#"
|
|
class="flex items-center gap-2 px-4 py-1.5 hover:bg-gray-50 text-gray-600 text-[12px] transition">
|
|
<span class="material-symbols-outlined text-xs text-gray-400">group_work</span>
|
|
รายงานเข้างานวันนี้
|
|
</a>
|
|
<a href="#"
|
|
class="flex items-center gap-2 px-4 py-1.5 hover:bg-gray-50 text-gray-600 text-[12px] transition">
|
|
<span class="material-symbols-outlined text-xs text-gray-400">pie_chart</span>
|
|
ประมวลผลสาย/ขาด (รอบเดือน)
|
|
</a>
|
|
</div>
|
|
<a href="#"
|
|
class="flex items-center gap-2 px-6 py-2 hover:bg-brand-light text-gray-700 transition">
|
|
<span class="material-symbols-outlined text-sm text-gray-400">analytics</span> รายงานพนักงาน
|
|
</a>
|
|
<a href="#"
|
|
class="flex items-center gap-2 px-6 py-2 hover:bg-brand-light text-gray-700 transition">
|
|
<span class="material-symbols-outlined text-sm text-gray-400">event_note</span> 3.1 การลา
|
|
</a>
|
|
<a href="#"
|
|
class="flex items-center justify-between px-6 py-2 hover:bg-brand-light text-gray-700 transition">
|
|
<div class="flex items-center gap-2">
|
|
<span class="material-symbols-outlined text-sm text-gray-400">more_time</span> 3.2 ขอ OT
|
|
</div>
|
|
<span class="bg-red-500 text-white text-[10px] px-1.5 rounded">1</span>
|
|
</a>
|
|
<a href="#"
|
|
class="flex items-center gap-2 px-6 py-2 hover:bg-brand-light text-gray-700 transition">
|
|
<span class="material-symbols-outlined text-sm text-gray-400">home_work</span> 3.3 ขอ WFH
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Item 4 (Collapsed) -->
|
|
<div class="border-b border-gray-300">
|
|
<div class="flex items-center justify-between px-3 py-2 cursor-pointer hover:bg-gray-100 text-gray-800 transition"
|
|
onclick="toggleMenu('submenu-finance')">
|
|
<div class="flex items-center gap-2 border-l-2 border-transparent pl-1">
|
|
การเงิน-เอกสาร
|
|
</div>
|
|
<span class="material-symbols-outlined text-sm text-gray-500"
|
|
id="icon-submenu-finance">arrow_drop_down</span>
|
|
</div>
|
|
<div id="submenu-finance" class="hidden flex-col bg-white">
|
|
<a href="#" class="px-8 py-2 hover:bg-brand-light text-gray-600 transition">เงินเดือน</a>
|
|
<a href="#" class="px-8 py-2 hover:bg-brand-light text-gray-600 transition">ภาษี/ประกันสังคม</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Item 5 (Collapsed) -->
|
|
<div class="border-b border-gray-300">
|
|
<div
|
|
class="flex items-center justify-between px-3 py-2 cursor-pointer hover:bg-gray-100 text-gray-800 transition">
|
|
<div class="flex items-center gap-2 border-l-2 border-transparent pl-1">
|
|
ราชการ
|
|
</div>
|
|
<span class="material-symbols-outlined text-sm text-gray-500">arrow_drop_down</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Item 6 (Collapsed) -->
|
|
<div class="border-b border-gray-300">
|
|
<div
|
|
class="flex items-center justify-between px-3 py-2 cursor-pointer hover:bg-gray-100 text-gray-800 transition">
|
|
<div class="flex items-center gap-2 border-l-2 border-transparent pl-1">
|
|
ระบบ
|
|
</div>
|
|
<span class="material-symbols-outlined text-sm text-gray-500">arrow_drop_down</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
|
|
<!-- ======= Center Content ======= -->
|
|
<section class="flex-1 overflow-y-auto p-4 flex flex-col gap-4">
|
|
|
|
<!-- Breadcrumb -->
|
|
<div
|
|
class="flex items-center gap-2 text-brand-primary text-xs bg-white py-2 px-4 rounded-lg shadow-sm border border-gray-200">
|
|
<span class="material-symbols-outlined text-sm">home</span>
|
|
หน้าหลัก <span class="text-gray-400">></span> <span
|
|
class="text-gray-500 font-medium">Dashboard</span>
|
|
</div>
|
|
|
|
<!-- Welcome Banner -->
|
|
<div
|
|
class="bg-white rounded-xl border border-gray-200 shadow-sm p-5 flex flex-wrap justify-between items-center gap-4">
|
|
<div class="flex items-center gap-4">
|
|
<div
|
|
class="w-[54px] h-[54px] rounded-2xl bg-gradient-to-br from-brand-primary to-brand-dark flex justify-center items-center text-white text-3xl shadow-md">
|
|
<span class="material-symbols-outlined text-3xl">mood</span>
|
|
</div>
|
|
<div>
|
|
<h2 class="text-xl font-bold text-gray-800 tracking-wide">สวัสดีคุณ admin admin</h2>
|
|
<p class="text-gray-500 mt-1 text-xs">วันนี้ 12 สิงหาคม 2026 • สวัสดีบ่ายโมงตรง • การตลาด</p>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<button
|
|
class="bg-brand-dark hover:bg-blue-800 text-white px-5 py-2.5 rounded-xl shadow-md flex items-center gap-2 transition-all active:scale-95 font-medium">
|
|
<span class="material-symbols-outlined text-lg">schedule</span> เช็คอินวันนี้
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Dashboard Stats -->
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
|
<div
|
|
class="bg-white rounded-xl border border-gray-200 shadow-sm p-4 flex items-center gap-4 border-l-4 border-l-brand-primary hover:shadow-md transition">
|
|
<div
|
|
class="w-12 h-12 rounded-xl bg-blue-50 text-brand-primary flex items-center justify-center shrink-0">
|
|
<span class="material-symbols-outlined text-2xl">groups</span>
|
|
</div>
|
|
<div>
|
|
<div class="text-[11px] text-gray-500 font-medium">พนักงานที่ยังทำงาน</div>
|
|
<div class="text-2xl font-bold text-gray-800 mt-0.5">30</div>
|
|
</div>
|
|
</div>
|
|
<div
|
|
class="bg-white rounded-xl border border-gray-200 shadow-sm p-4 flex items-center gap-4 border-l-4 border-l-green-600 hover:shadow-md transition">
|
|
<div
|
|
class="w-12 h-12 rounded-xl bg-green-50 text-green-600 flex items-center justify-center shrink-0">
|
|
<span class="material-symbols-outlined text-2xl">corporate_fare</span>
|
|
</div>
|
|
<div>
|
|
<div class="text-[11px] text-gray-500 font-medium">แผนก</div>
|
|
<div class="text-2xl font-bold text-gray-800 mt-0.5">9</div>
|
|
</div>
|
|
</div>
|
|
<div
|
|
class="bg-white rounded-xl border border-gray-200 shadow-sm p-4 flex items-center gap-4 border-l-4 border-l-orange-500 hover:shadow-md transition">
|
|
<div
|
|
class="w-12 h-12 rounded-xl bg-orange-50 text-orange-500 flex items-center justify-center shrink-0">
|
|
<span class="material-symbols-outlined text-2xl">event_available</span>
|
|
</div>
|
|
<div>
|
|
<div class="text-[11px] text-gray-500 font-medium">ใบลาอนุมัติ</div>
|
|
<div class="text-2xl font-bold text-gray-800 mt-0.5">0</div>
|
|
</div>
|
|
</div>
|
|
<div
|
|
class="bg-white rounded-xl border border-gray-200 shadow-sm p-4 flex items-center gap-4 border-l-4 border-l-red-500 hover:shadow-md transition">
|
|
<div class="w-12 h-12 rounded-xl bg-red-50 text-red-500 flex items-center justify-center shrink-0">
|
|
<span class="material-symbols-outlined text-2xl">description</span>
|
|
</div>
|
|
<div>
|
|
<div class="text-[11px] text-gray-500 font-medium">คำขอเอกสารรออนุมัติ</div>
|
|
<div class="text-2xl font-bold text-gray-800 mt-0.5">0</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Attendance Info -->
|
|
<div class="bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden flex flex-col">
|
|
<div
|
|
class="bg-brand-primary text-white py-2.5 px-4 flex items-center gap-2 text-sm font-semibold tracking-wide">
|
|
<span class="material-symbols-outlined text-base">schedule</span> การเข้างานวันนี้
|
|
</div>
|
|
<div class="flex divide-x divide-gray-200 p-6">
|
|
<div class="flex-1 flex flex-col items-center justify-center">
|
|
<div class="text-gray-500 text-sm font-medium">เช็คอินแล้ว</div>
|
|
<div class="mt-2"><span class="text-4xl font-bold text-green-600">0</span> <span
|
|
class="text-gray-400 font-normal">/ 30</span></div>
|
|
</div>
|
|
<div class="flex-1 flex flex-col items-center justify-center">
|
|
<div class="text-gray-500 text-sm font-medium">เช็คเอาท์แล้ว</div>
|
|
<div class="mt-2 text-4xl font-bold text-red-600">0</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick Access -->
|
|
<div class="bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden flex flex-col">
|
|
<div
|
|
class="bg-brand-primary text-white py-2.5 px-4 flex items-center gap-2 text-sm font-semibold tracking-wide">
|
|
<span class="material-symbols-outlined text-base">grid_view</span> Quick Access
|
|
</div>
|
|
<div class="p-5 bg-gray-50/60 flex gap-4 overflow-x-auto no-scrollbar">
|
|
<div
|
|
class="bg-white border border-gray-200/80 rounded-xl p-4 flex flex-col items-center justify-center min-w-[105px] cursor-pointer hover:shadow-md hover:border-brand-primary transition-all duration-200 group">
|
|
<div
|
|
class="w-12 h-12 rounded-xl bg-blue-50 text-brand-primary flex items-center justify-center mb-2 group-hover:scale-110 transition-transform">
|
|
<span class="material-symbols-outlined text-2xl">group</span>
|
|
</div>
|
|
<span class="text-xs font-semibold text-gray-700">พนักงาน</span>
|
|
</div>
|
|
<div
|
|
class="bg-white border border-gray-200/80 rounded-xl p-4 flex flex-col items-center justify-center min-w-[105px] cursor-pointer hover:shadow-md hover:border-brand-primary transition-all duration-200 group">
|
|
<div
|
|
class="w-12 h-12 rounded-xl bg-blue-50 text-brand-primary flex items-center justify-center mb-2 group-hover:scale-110 transition-transform">
|
|
<span class="material-symbols-outlined text-2xl">schedule</span>
|
|
</div>
|
|
<span class="text-xs font-semibold text-gray-700">เวลา</span>
|
|
</div>
|
|
<div
|
|
class="bg-white border border-gray-200/80 rounded-xl p-4 flex flex-col items-center justify-center min-w-[105px] cursor-pointer hover:shadow-md hover:border-brand-primary transition-all duration-200 group">
|
|
<div
|
|
class="w-12 h-12 rounded-xl bg-blue-50 text-brand-primary flex items-center justify-center mb-2 group-hover:scale-110 transition-transform">
|
|
<span class="material-symbols-outlined text-2xl">event_note</span>
|
|
</div>
|
|
<span class="text-xs font-semibold text-gray-700">ลา</span>
|
|
</div>
|
|
<div
|
|
class="bg-white border border-gray-200/80 rounded-xl p-4 flex flex-col items-center justify-center min-w-[105px] cursor-pointer hover:shadow-md hover:border-brand-primary transition-all duration-200 group">
|
|
<div
|
|
class="w-12 h-12 rounded-xl bg-blue-50 text-brand-primary flex items-center justify-center mb-2 group-hover:scale-110 transition-transform">
|
|
<span class="material-symbols-outlined text-2xl">payments</span>
|
|
</div>
|
|
<span class="text-xs font-semibold text-gray-700">เงินเดือน</span>
|
|
</div>
|
|
<div
|
|
class="bg-white border border-gray-200/80 rounded-xl p-4 flex flex-col items-center justify-center min-w-[105px] cursor-pointer hover:shadow-md hover:border-brand-primary transition-all duration-200 group">
|
|
<div
|
|
class="w-12 h-12 rounded-xl bg-blue-50 text-brand-primary flex items-center justify-center mb-2 group-hover:scale-110 transition-transform">
|
|
<span class="material-symbols-outlined text-2xl">receipt_long</span>
|
|
</div>
|
|
<span class="text-xs font-semibold text-gray-700">สลิป</span>
|
|
</div>
|
|
<div
|
|
class="bg-white border border-gray-200/80 rounded-xl p-4 flex flex-col items-center justify-center min-w-[105px] cursor-pointer hover:shadow-md hover:border-brand-primary transition-all duration-200 group">
|
|
<div
|
|
class="w-12 h-12 rounded-xl bg-blue-50 text-brand-primary flex items-center justify-center mb-2 group-hover:scale-110 transition-transform">
|
|
<span class="material-symbols-outlined text-2xl">folder_open</span>
|
|
</div>
|
|
<span class="text-xs font-semibold text-gray-700">เอกสาร</span>
|
|
</div>
|
|
<div
|
|
class="bg-white border border-gray-200/80 rounded-xl p-4 flex flex-col items-center justify-center min-w-[105px] cursor-pointer hover:shadow-md hover:border-brand-primary transition-all duration-200 group">
|
|
<div
|
|
class="w-12 h-12 rounded-xl bg-blue-50 text-brand-primary flex items-center justify-center mb-2 group-hover:scale-110 transition-transform">
|
|
<span class="material-symbols-outlined text-2xl">account_balance</span>
|
|
</div>
|
|
<span class="text-xs font-semibold text-gray-700">ภาครัฐ</span>
|
|
</div>
|
|
<div
|
|
class="bg-white border border-gray-200/80 rounded-xl p-4 flex flex-col items-center justify-center min-w-[105px] cursor-pointer hover:shadow-md hover:border-brand-primary transition-all duration-200 group">
|
|
<div
|
|
class="w-12 h-12 rounded-xl bg-blue-50 text-brand-primary flex items-center justify-center mb-2 group-hover:scale-110 transition-transform">
|
|
<span class="material-symbols-outlined text-2xl">settings</span>
|
|
</div>
|
|
<span class="text-xs font-semibold text-gray-700">ตั้งค่า</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- New Datatable Section with Filter and Sort -->
|
|
<div class="bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden flex flex-col">
|
|
<div
|
|
class="bg-brand-primary text-white py-3 px-4 flex flex-wrap items-center justify-between gap-3 text-sm font-semibold tracking-wide">
|
|
<div class="flex items-center gap-2">
|
|
<span class="material-symbols-outlined text-base">table_view</span> รายชื่อพนักงานทั้งหมดในระบบ
|
|
(Datatable)
|
|
</div>
|
|
<!-- Filter and Search Controls -->
|
|
<div class="flex items-center gap-2">
|
|
<select id="filter-dept" onchange="handleFilterChange()"
|
|
class="bg-white text-gray-700 text-xs px-3 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-white/50">
|
|
<option value="">ทุกแผนก</option>
|
|
<option value="การตลาด">การตลาด</option>
|
|
<option value="บุคคล (HR)">บุคคล (HR)</option>
|
|
<option value="ไอที (IT)">ไอที (IT)</option>
|
|
<option value="การเงิน">การเงิน</option>
|
|
<option value="จัดซื้อ">จัดซื้อ</option>
|
|
<option value="บริหาร">บริหาร</option>
|
|
<option value="คลังสินค้า">คลังสินค้า</option>
|
|
<option value="ประชาสัมพันธ์">ประชาสัมพันธ์</option>
|
|
</select>
|
|
<input type="text" id="search-input" oninput="handleSearch()" placeholder="ค้นหาชื่อ, รหัส..."
|
|
class="bg-white text-gray-800 text-xs px-3.5 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-white/50 w-48">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Table Wrapper (Sticky Table Header) -->
|
|
<div class="overflow-x-auto max-h-[380px] relative">
|
|
<table class="w-full text-left border-collapse">
|
|
<thead class="sticky top-0 z-10 bg-gray-100 shadow-sm">
|
|
<tr class="text-gray-600 text-xs uppercase border-b border-gray-200 select-none">
|
|
<th class="py-3 px-4 font-semibold cursor-pointer hover:bg-gray-200 transition bg-gray-100"
|
|
onclick="handleSort('id')">
|
|
<div class="flex items-center gap-1">รหัสพนักงาน <span id="sort-icon-id"
|
|
class="text-gray-400 material-symbols-outlined text-sm">unfold_more</span>
|
|
</div>
|
|
</th>
|
|
<th class="py-3 px-4 font-semibold cursor-pointer hover:bg-gray-200 transition bg-gray-100"
|
|
onclick="handleSort('name')">
|
|
<div class="flex items-center gap-1">ชื่อ - นามสกุล <span id="sort-icon-name"
|
|
class="text-gray-400 material-symbols-outlined text-sm">unfold_more</span>
|
|
</div>
|
|
</th>
|
|
<th class="py-3 px-4 font-semibold cursor-pointer hover:bg-gray-200 transition bg-gray-100"
|
|
onclick="handleSort('dept')">
|
|
<div class="flex items-center gap-1">แผนก <span id="sort-icon-dept"
|
|
class="text-gray-400 material-symbols-outlined text-sm">unfold_more</span>
|
|
</div>
|
|
</th>
|
|
<th class="py-3 px-4 font-semibold bg-gray-100">ตำแหน่ง</th>
|
|
<th class="py-3 px-4 font-semibold text-center bg-gray-100">สถานะ</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="datatable-body" class="divide-y divide-gray-200 text-xs bg-white">
|
|
<!-- Data rows will be injected by JavaScript -->
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Pagination Footer -->
|
|
<div class="bg-gray-50 px-4 py-3 border-t border-gray-200 flex items-center justify-between text-xs">
|
|
<div id="pagination-info" class="text-gray-500 font-medium">
|
|
แสดง 0 ถึง 0 จากทั้งหมด 0 รายการ
|
|
</div>
|
|
<div class="flex items-center gap-1.5" id="pagination-buttons">
|
|
<!-- Pagination buttons generated by JS -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="h-4 shrink-0"></div>
|
|
</section>
|
|
|
|
<!-- ======= Right Sidebar (Hover to Expand, Default Collapsed) ======= -->
|
|
<aside
|
|
class="w-[45px] hover:w-[280px] shrink-0 bg-white border-l border-gray-300 relative transition-all duration-300 ease-in-out group shadow-[-2px_0_10px_rgba(0,0,0,0.05)] overflow-hidden z-20">
|
|
<div class="w-[280px] h-full flex flex-col">
|
|
<!-- Header -->
|
|
<div class="h-[40px] bg-[#144b94] text-white flex items-center px-3 shrink-0 cursor-default">
|
|
<span class="material-symbols-outlined text-[20px] shrink-0">schedule</span>
|
|
<span
|
|
class="ml-3 font-medium text-sm whitespace-nowrap opacity-0 group-hover:opacity-100 transition-opacity duration-300">ประวัติล่าสุด</span>
|
|
</div>
|
|
|
|
<!-- Content List -->
|
|
<div class="flex-1 overflow-y-auto no-scrollbar p-2 bg-gray-50 flex flex-col gap-2">
|
|
<div
|
|
class="bg-white border border-gray-200 p-2.5 rounded-xl flex gap-3 opacity-0 group-hover:opacity-100 transition-opacity duration-300 delay-100 hover:border-brand-primary hover:shadow-sm">
|
|
<span class="material-symbols-outlined text-brand-primary text-xl mt-0.5 shrink-0">login</span>
|
|
<div class="flex flex-col">
|
|
<span class="text-gray-800 text-xs font-semibold">LOGIN โดย user1</span>
|
|
<span class="text-gray-500 text-[10px]">login success</span>
|
|
<span class="text-gray-400 text-[10px] mt-1">12 สิงหาคม 2026, 12:01</span>
|
|
</div>
|
|
</div>
|
|
<div
|
|
class="bg-white border border-gray-200 p-2.5 rounded-xl flex gap-3 opacity-0 group-hover:opacity-100 transition-opacity duration-300 delay-100 hover:border-red-400 hover:shadow-sm">
|
|
<span class="material-symbols-outlined text-red-500 text-xl mt-0.5 shrink-0">logout</span>
|
|
<div class="flex flex-col">
|
|
<span class="text-gray-800 text-xs font-semibold">LOGOUT โดย EMP9001</span>
|
|
<span class="text-gray-500 text-[10px]">logout</span>
|
|
<span class="text-gray-400 text-[10px] mt-1">12 สิงหาคม 2026, 11:30</span>
|
|
</div>
|
|
</div>
|
|
<div
|
|
class="bg-white border border-gray-200 p-2.5 rounded-xl flex gap-3 opacity-0 group-hover:opacity-100 transition-opacity duration-300 delay-100 hover:border-orange-400 hover:shadow-sm">
|
|
<span class="material-symbols-outlined text-orange-500 text-xl mt-0.5 shrink-0">key</span>
|
|
<div class="flex flex-col">
|
|
<span class="text-gray-800 text-xs font-semibold">PASSWORD_CHANGE โดย EMP9001</span>
|
|
<span class="text-gray-500 text-[10px]">change password</span>
|
|
<span class="text-gray-400 text-[10px] mt-1">12 สิงหาคม 2026, 11:00</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
|
|
</main>
|
|
|
|
<!-- ================= STREAMING_CHUNK:Rendering Footer ================= -->
|
|
<footer class="bg-brand-dark text-white text-[11px] h-[28px] shrink-0 flex items-center justify-between px-4 z-30">
|
|
<div class="flex items-center gap-4">
|
|
<div class="flex items-center gap-1.5"><span class="w-2 h-2 rounded-full bg-green-400"></span> พร้อมใช้งาน
|
|
</div>
|
|
<div class="flex items-center gap-1.5 border-l border-white/20 pl-4"><span
|
|
class="material-symbols-outlined text-[13px]">person</span> admin (ผู้ดูแลระบบ)</div>
|
|
<div class="flex items-center gap-1.5 border-l border-white/20 pl-4"><span
|
|
class="material-symbols-outlined text-[13px]">database</span> HR_System</div>
|
|
</div>
|
|
<div class="flex items-center gap-1.5 text-white/80">
|
|
<span class="material-symbols-outlined text-[13px]">schedule</span>
|
|
<span id="realtime-clock">12/08/2026 13:00:00</span>
|
|
</div>
|
|
</footer>
|
|
|
|
<!-- ================= STREAMING_CHUNK:Initializing Application Scripts ================= -->
|
|
<script>
|
|
// ควบคุม Accordion เมนูด้านซ้าย
|
|
function toggleMenu(menuId) {
|
|
const menu = document.getElementById(menuId);
|
|
const iconId = 'icon-' + menuId;
|
|
const icon = document.getElementById(iconId);
|
|
|
|
if (menu.classList.contains('hidden')) {
|
|
menu.classList.remove('hidden');
|
|
menu.classList.add('flex');
|
|
if (icon) icon.innerText = 'arrow_drop_up';
|
|
} else {
|
|
menu.classList.add('hidden');
|
|
menu.classList.remove('flex');
|
|
if (icon) icon.innerText = 'arrow_drop_down';
|
|
}
|
|
}
|
|
|
|
// ฟังก์ชันอัปเดตเวลา Realtime ใน Footer
|
|
function updateClock() {
|
|
const now = new Date();
|
|
const day = String(now.getDate()).padStart(2, '0');
|
|
const month = String(now.getMonth() + 1).padStart(2, '0');
|
|
const year = now.getFullYear();
|
|
const hours = String(now.getHours()).padStart(2, '0');
|
|
const minutes = String(now.getMinutes()).padStart(2, '0');
|
|
const seconds = String(now.getSeconds()).padStart(2, '0');
|
|
|
|
const timeString = `${day}/${month}/${year} ${hours}:${minutes}:${seconds}`;
|
|
const clockElement = document.getElementById('realtime-clock');
|
|
if (clockElement) {
|
|
clockElement.innerText = timeString;
|
|
}
|
|
}
|
|
updateClock();
|
|
setInterval(updateClock, 1000);
|
|
|
|
// --- Mockup Datatable Data & Filtering/Sorting ---
|
|
const mockupEmployees = [
|
|
{id: 'EMP-1001', name: 'สมชาย ใจดี', dept: 'การตลาด', pos: 'หัวหน้าทีมการตลาด', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1002', name: 'สมหญิง รักสงบ', dept: 'บุคคล (HR)', pos: 'เจ้าหน้าที่ HR', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1003', name: 'ประเสริฐ มั่นคง', dept: 'ไอที (IT)', pos: 'System Admin', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1004', name: 'กนกวรรณ ศรีสุข', dept: 'การเงิน', pos: 'นักบัญชีอาวุโส', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1005', name: 'วิชัย พัฒนากุล', dept: 'การตลาด', pos: 'Marketing Manager', status: 'ลาพักร้อน'},
|
|
{id: 'EMP-1006', name: 'สุดา ฤทธิ์รอน', dept: 'จัดซื้อ', pos: 'เจ้าหน้าที่จัดซื้อ', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1007', name: 'ธนพล กล้าหาญ', dept: 'ไอที (IT)', pos: 'Developer', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1008', name: 'นิกดา แสงอรุณ', dept: 'ประชาสัมพันธ์', pos: 'เจ้าหน้าที่ PR', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1009', name: 'อนุชา วงศ์สวัสดิ์', dept: 'บริหาร', pos: 'Director', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1010', name: 'จิราภรณ์ เขียวอ้น', dept: 'การเงิน', pos: 'Cashier', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1011', name: 'กิตติ สุขสวัสดิ์', dept: 'ไอที (IT)', pos: 'Support Engineer', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1012', name: 'รัตนาภรณ์ ดีงาม', dept: 'บุคคล (HR)', pos: 'Recruiter', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1013', name: 'มงคล ชัยวัฒน์', dept: 'การตลาด', pos: 'Sales Executive', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1014', name: 'วรรณา สุขใจ', dept: 'บริหาร', pos: 'Secretary', status: 'ลาป่วย'},
|
|
{id: 'EMP-1015', name: 'ชัย ภูมิภาค', dept: 'คลังสินค้า', pos: 'Warehouse Staff', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1016', name: 'กมล ธรรมนูญ', dept: 'การตลาด', pos: 'Staff', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1017', name: 'ณัฐ ธีระกุล', dept: 'ไอที (IT)', pos: 'Staff', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1018', name: 'ดนัย นพรัตน์', dept: 'การเงิน', pos: 'Staff', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1019', name: 'ทิพย์ มณีรัตน์', dept: 'บุคคล (HR)', pos: 'Staff', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1020', name: 'ธนภัทร ภูวดล', dept: 'จัดซื้อ', pos: 'Staff', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1021', name: 'นันทรัตน์ คงคา', dept: 'บริหาร', pos: 'Staff', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1022', name: 'บวร เรืองรอง', dept: 'การตลาด', pos: 'Staff', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1023', name: 'ปวีณา ศิริพงษ์', dept: 'ไอที (IT)', pos: 'Staff', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1024', name: 'พงศธร วงศ์ไทย', dept: 'การเงิน', pos: 'Staff', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1025', name: 'ภัทรา สุวรรณ', dept: 'บุคคล (HR)', pos: 'Staff', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1026', name: 'ยุทธนา ฤทธิ์เดช', dept: 'จัดซื้อ', pos: 'Staff', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1027', name: 'ลลิตา วงศ์สวัสดิ์', dept: 'คลังสินค้า', pos: 'Staff', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1028', name: 'วรพงษ์ แสงทอง', dept: 'ประชาสัมพันธ์', pos: 'Staff', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1029', name: 'ศิริพร อุ่นเรือน', dept: 'ไอที (IT)', pos: 'Staff', status: 'ปฏิบัติงาน'},
|
|
{id: 'EMP-1030', name: 'อภิชาต ยิ้มแย้ม', dept: 'บริหาร', pos: 'Executive', status: 'ปฏิบัติงาน'}
|
|
];
|
|
|
|
let currentPage = 1;
|
|
const rowsPerPage = 10;
|
|
let currentSearch = '';
|
|
let currentDept = '';
|
|
let sortColumn = '';
|
|
let sortDirection = 'asc'; // 'asc' or 'desc'
|
|
|
|
function getFilteredAndSortedData() {
|
|
let data = [...mockupEmployees];
|
|
|
|
// 1. Filter by Search Query
|
|
if (currentSearch.trim() !== '') {
|
|
const keyword = currentSearch.toLowerCase();
|
|
data = data.filter(emp =>
|
|
emp.id.toLowerCase().includes(keyword) ||
|
|
emp.name.toLowerCase().includes(keyword) ||
|
|
emp.pos.toLowerCase().includes(keyword)
|
|
);
|
|
}
|
|
|
|
// 2. Filter by Department
|
|
if (currentDept !== '') {
|
|
data = data.filter(emp => emp.dept === currentDept);
|
|
}
|
|
|
|
// 3. Sort Data
|
|
if (sortColumn !== '') {
|
|
data.sort((a, b) => {
|
|
let valA = a[sortColumn];
|
|
let valB = b[sortColumn];
|
|
if (valA < valB) return sortDirection === 'asc' ? -1 : 1;
|
|
if (valA > valB) return sortDirection === 'asc' ? 1 : -1;
|
|
return 0;
|
|
});
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
function renderTable() {
|
|
const filteredData = getFilteredAndSortedData();
|
|
const totalPages = Math.ceil(filteredData.length / rowsPerPage) || 1;
|
|
|
|
// Adjust current page if out of bounds
|
|
if (currentPage > totalPages) currentPage = totalPages;
|
|
if (currentPage < 1) currentPage = 1;
|
|
|
|
const tbody = document.getElementById('datatable-body');
|
|
tbody.innerHTML = '';
|
|
|
|
const start = (currentPage - 1) * rowsPerPage;
|
|
const end = start + rowsPerPage;
|
|
const paginatedItems = filteredData.slice(start, end);
|
|
|
|
if (paginatedItems.length === 0) {
|
|
tbody.innerHTML = `<tr><td colspan="5" class="py-6 text-center text-gray-400">ไม่พบข้อมูลพนักงานในระบบ</td></tr>`;
|
|
} else {
|
|
paginatedItems.forEach((emp) => {
|
|
const tr = document.createElement('tr');
|
|
tr.className = 'hover:bg-gray-50/80 transition';
|
|
|
|
const statusBadge = emp.status === 'ปฏิบัติงาน'
|
|
? '<span class="bg-green-100 text-green-700 px-2.5 py-1 rounded-full font-medium inline-block text-[11px]">ปฏิบัติงาน</span>'
|
|
: '<span class="bg-orange-100 text-orange-700 px-2.5 py-1 rounded-full font-medium inline-block text-[11px]">' + emp.status + '</span>';
|
|
|
|
tr.innerHTML = `
|
|
<td class="py-3 px-4 font-semibold text-brand-dark">${emp.id}</td>
|
|
<td class="py-3 px-4 font-medium text-gray-800">${emp.name}</td>
|
|
<td class="py-3 px-4 text-gray-600">${emp.dept}</td>
|
|
<td class="py-3 px-4 text-gray-600">${emp.pos}</td>
|
|
<td class="py-3 px-4 text-center">${statusBadge}</td>
|
|
`;
|
|
tbody.appendChild(tr);
|
|
});
|
|
}
|
|
|
|
// Update info text
|
|
const total = filteredData.length;
|
|
const displayStart = total > 0 ? start + 1 : 0;
|
|
const displayEnd = Math.min(end, total);
|
|
document.getElementById('pagination-info').innerText = `แสดง ${displayStart} ถึง ${displayEnd} จากทั้งหมด ${total} รายการ`;
|
|
|
|
renderPaginationControls(totalPages);
|
|
}
|
|
|
|
function renderPaginationControls(totalPages) {
|
|
const container = document.getElementById('pagination-buttons');
|
|
container.innerHTML = '';
|
|
|
|
// Previous Button
|
|
const prevBtn = document.createElement('button');
|
|
prevBtn.className = `px-3 py-1.5 rounded-lg border text-xs font-medium transition ${currentPage === 1 ? 'bg-gray-100 text-gray-400 border-gray-200 cursor-not-allowed' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`;
|
|
prevBtn.innerText = 'ก่อนหน้า';
|
|
prevBtn.disabled = currentPage === 1;
|
|
prevBtn.onclick = () => {if (currentPage > 1) {currentPage--; renderTable();} };
|
|
container.appendChild(prevBtn);
|
|
|
|
// Page Number Buttons
|
|
for (let i = 1; i <= totalPages; i++) {
|
|
const pageBtn = document.createElement('button');
|
|
pageBtn.className = `w-7 h-7 rounded-lg border text-xs font-medium flex items-center justify-center transition ${currentPage === i ? 'bg-brand-primary text-white border-brand-primary shadow-sm' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`;
|
|
pageBtn.innerText = i;
|
|
pageBtn.onclick = () => {currentPage = i; renderTable();};
|
|
container.appendChild(pageBtn);
|
|
}
|
|
|
|
// Next Button
|
|
const nextBtn = document.createElement('button');
|
|
nextBtn.className = `px-3 py-1.5 rounded-lg border text-xs font-medium transition ${currentPage === totalPages ? 'bg-gray-100 text-gray-400 border-gray-200 cursor-not-allowed' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`;
|
|
nextBtn.innerText = 'ถัดไป';
|
|
nextBtn.disabled = currentPage === totalPages;
|
|
nextBtn.onclick = () => {if (currentPage < totalPages) {currentPage++; renderTable();} };
|
|
container.appendChild(nextBtn);
|
|
}
|
|
|
|
// Event Handlers
|
|
function handleSearch() {
|
|
currentSearch = document.getElementById('search-input').value;
|
|
currentPage = 1;
|
|
renderTable();
|
|
}
|
|
|
|
function handleFilterChange() {
|
|
currentDept = document.getElementById('filter-dept').value;
|
|
currentPage = 1;
|
|
renderTable();
|
|
}
|
|
|
|
function handleSort(column) {
|
|
if (sortColumn === column) {
|
|
if (sortDirection === 'asc') {
|
|
sortDirection = 'desc';
|
|
} else if (sortDirection === 'desc') {
|
|
sortColumn = '';
|
|
sortDirection = 'asc';
|
|
}
|
|
} else {
|
|
sortColumn = column;
|
|
sortDirection = 'asc';
|
|
}
|
|
|
|
// Update Sort Icons
|
|
['id', 'name', 'dept'].forEach(col => {
|
|
const icon = document.getElementById(`sort-icon-${col}`);
|
|
if (col === sortColumn) {
|
|
icon.innerText = sortDirection === 'asc' ? 'arrow_upward' : 'arrow_downward';
|
|
icon.className = 'text-brand-dark material-symbols-outlined text-sm font-bold';
|
|
} else {
|
|
icon.innerText = 'unfold_more';
|
|
icon.className = 'text-gray-400 material-symbols-outlined text-sm';
|
|
}
|
|
});
|
|
|
|
renderTable();
|
|
}
|
|
|
|
// Initial render table on load
|
|
renderTable();
|
|
</script>
|
|
</body>
|
|
|
|
</html> |