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,429 @@
<?php
session_start();
if (!isset($_SESSION["loggedin"]) || $_SESSION["loggedin"] !== true) {
header("location: index.php");
exit;
}
require_once 'includes/db_assessment.php';
$cid = $_SESSION['cid'];
// ดึงปีปัจจุบันจากตาราง it_years
$stmt = $pdo_assess->query("SELECT year_text FROM it_years WHERE is_active = 1 LIMIT 1");
$current_year = $stmt->fetchColumn();
if (!$current_year) {
echo "<!DOCTYPE html><html lang='th'><head><meta charset='UTF-8'><title>ระบบประเมิน</title><link href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css' rel='stylesheet'></head><body class='bg-light d-flex align-items-center justify-content-center vh-100'><div class='text-center'><h3>ขณะนี้ยังไม่มีการเปิดรับทำแบบประเมินประจำปี</h3><a href='actions/logout.php' class='btn btn-secondary mt-3'>ออกจากระบบ</a></div></body></html>";
exit;
}
// ตรวจสอบว่าเคยทำประเมินในปีนี้หรือยัง
$has_assessed = false;
$assessed_date = null;
try {
$stmt = $pdo_assess->prepare("SELECT created_at FROM it_assessments WHERE hr_cid = :cid AND assess_year = :year LIMIT 1");
$stmt->execute(['cid' => $cid, 'year' => $current_year]);
$result = $stmt->fetch();
if ($result) {
$has_assessed = true;
$assessed_date = date('d/m/Y H:i', strtotime($result['created_at']));
}
} catch (PDOException $e) {
}
?>
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>แบบประเมิน - หน่วยงานสุขภาพดิจิทัล</title>
<!-- Favicon -->
<link rel="icon" type="image/png" href="assets/images/logo.png">
<!-- Bootstrap 5 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Sarabun:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<!-- SweetAlert2 -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<style>
body {
font-family: 'Sarabun', sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
color: #333;
min-height: 100vh;
}
.navbar-custom {
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(10px);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
}
.form-container {
background: #ffffff;
border-radius: 20px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
padding: 3rem;
margin-top: 2rem;
margin-bottom: 3rem;
border: 1px solid rgba(255, 255, 255, 0.4);
}
.header-title {
background: linear-gradient(135deg, #008f91, #005d68);
color: white;
padding: 2rem;
border-radius: 15px;
text-align: center;
margin-bottom: 2rem;
box-shadow: 0 8px 20px rgba(0, 143, 145, 0.2);
}
.section-title {
color: #007f8b;
font-weight: 700;
border-left: 5px solid #007f8b;
padding-left: 15px;
margin-top: 2.5rem;
margin-bottom: 1.5rem;
}
.table-custom th {
background: #12344d;
color: white;
text-align: center;
vertical-align: middle;
}
.table-custom td {
vertical-align: middle;
}
.table-custom tbody tr:hover {
background-color: #f0faf9;
}
.radio-custom input[type="radio"] {
width: 20px;
height: 20px;
accent-color: #007f8b;
}
.btn-submit {
background: linear-gradient(135deg, #008f91, #005d68);
color: white;
border: none;
padding: 12px 30px;
font-size: 1.1rem;
border-radius: 50px;
font-weight: 600;
transition: all 0.3s ease;
}
.btn-submit:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(0, 143, 145, 0.3);
color: white;
}
.card-done {
background: white;
border-radius: 15px;
padding: 3rem;
text-align: center;
margin-top: 5rem;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
}
.card-done h3 {
color: #28a745;
font-weight: 700;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-custom sticky-top">
<div class="container">
<a class="navbar-brand fw-bold text-dark d-flex align-items-center" href="#">
<img src="assets/images/logo.png" alt="Logo" width="40" height="40" class="d-inline-block align-text-top me-2">
<span>IT Assessment System</span>
</a>
<div class="d-flex align-items-center">
<span class="me-3 fw-bold text-muted">ยินดีต้อนรับ, <?php echo htmlspecialchars($_SESSION['fullname']); ?></span>
<a href="actions/logout.php" class="btn btn-outline-danger btn-sm rounded-pill px-3">ออกจากระบบ</a>
<?php if(isset($_SESSION['is_admin']) && $_SESSION['is_admin']): ?>
<a href="summary.php" class="btn btn-outline-primary btn-sm rounded-pill px-3 ms-2">หน้าสรุปผล (Admin)</a>
<?php endif; ?>
</div>
</div>
</nav>
<div class="container">
<?php if ($has_assessed): ?>
<div class="card-done">
<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" fill="currentColor" class="bi bi-check-circle-fill text-success mb-3" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z" />
</svg>
<h3>ท่านได้ทำแบบประเมินประจำปี <?php echo $current_year; ?> เรียบร้อยแล้ว</h3>
<p class="text-muted fs-5 mt-3">ทำรายการเมื่อวันที่: <strong><?php echo $assessed_date; ?></strong></p>
<p class="text-muted">ขอขอบคุณที่ให้ความร่วมมือในการทำแบบประเมินของหน่วยงานสุขภาพดิจิทัล</p>
</div>
<?php else: ?>
<div class="form-container">
<div class="header-title">
<h2 class="fw-bold mb-2">แบบประเมินระเบียบปฏิบัติในการรักษาความมั่นคงปลอดภัย<br>ระบบเทคโนโลยีสารสนเทศ</h2>
<h5 class="mb-0">โรงพยาบาลเกาะสมุย ประจำปี <?php echo $current_year; ?></h5>
</div>
<div class="alert alert-info border-0 bg-info bg-opacity-10 text-dark">
<strong>คำอธิบาย:</strong> แบบประเมินมี 4 ส่วน กรุณาตอบตามความเป็นจริงเพื่อกลุ่มงานสุขภาพดิจิทัลจะนำผลการประเมินไปวิเคราะห์เพื่อจัดการความมั่นคงปลอดภัยระบบเทคโนโลยีสารสนเทศของโรงพยาบาลเกาะสมุย ให้เกิดประโยชน์สูงสุด
</div>
<form id="assessmentForm" action="actions/save_assessment.php" method="POST">
<input type="hidden" name="assess_year" value="<?php echo $current_year; ?>">
<h4 class="section-title">ส่วนที่ 1 ข้อมูลผู้รับการประเมิน</h4>
<div class="row g-3">
<div class="col-md-4">
<label class="form-label fw-bold">ชื่อ-สกุล</label>
<input type="text" class="form-control" name="fullname" value="<?php echo htmlspecialchars($_SESSION['fullname']); ?>" readonly>
</div>
<div class="col-md-4">
<label class="form-label fw-bold">ตำแหน่ง</label>
<input type="text" class="form-control bg-light" name="position" value="<?php echo htmlspecialchars($_SESSION['position'] ?? ''); ?>" readonly>
</div>
<div class="col-md-4">
<label class="form-label fw-bold">หน่วยงาน</label>
<input type="text" class="form-control bg-light" name="department" value="<?php echo htmlspecialchars($_SESSION['department'] ?? ''); ?>" readonly>
</div>
</div>
<h4 class="section-title">ส่วนที่ 2 การใช้งานคอมพิวเตอร์</h4>
<div class="card border-0 shadow-sm mb-4">
<div class="card-body">
<div class="form-check mb-2">
<input class="form-check-input" type="radio" name="computer_use" id="use_yes" value="1" required>
<label class="form-check-label fw-bold" for="use_yes">
1. ใช้คอมพิวเตอร์ในการปฏิบัติงาน
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="computer_use" id="use_no" value="2">
<label class="form-check-label fw-bold" for="use_no">
2. ไม่ได้ใช้คอมพิวเตอร์ในการปฏิบัติงาน
</label>
</div>
</div>
</div>
<h4 class="section-title">ส่วนที่ 3 การประเมินการรับรู้ ความเข้าใจ และการปฏิบัติ</h4>
<div class="table-responsive rounded shadow-sm border border-1 mb-4">
<table class="table table-bordered table-custom mb-0">
<thead>
<tr>
<th rowspan="2" class="align-middle" style="width: 50%;">ระเบียบปฏิบัติ</th>
<th colspan="2">การรับรู้</th>
<th colspan="2">ความเข้าใจ</th>
<th colspan="2">การปฏิบัติ</th>
</tr>
<tr style="background:#173e55;">
<th>รู้</th>
<th>ไม่รู้</th>
<th>เข้าใจ</th>
<th>ไม่เข้าใจ</th>
<th>ได้</th>
<th>ไม่ได้</th>
</tr>
</thead>
<tbody>
<?php
$rules = $pdo_assess->query("SELECT * FROM it_rules WHERE is_active = 1 ORDER BY order_no ASC")->fetchAll();
$n = 1;
foreach ($rules as $rule):
$r_id = $rule['id'];
?>
<tr>
<td><?php echo $n . ". " . htmlspecialchars($rule['content']); ?></td>
<td class="text-center radio-custom"><input type="radio" name="r_<?php echo $r_id; ?>_k" value="yes" required></td>
<td class="text-center radio-custom"><input type="radio" name="r_<?php echo $r_id; ?>_k" value="no"></td>
<td class="text-center radio-custom"><input type="radio" name="r_<?php echo $r_id; ?>_u" value="yes" required></td>
<td class="text-center radio-custom"><input type="radio" name="r_<?php echo $r_id; ?>_u" value="no"></td>
<td class="text-center radio-custom"><input type="radio" name="r_<?php echo $r_id; ?>_p" value="yes" required></td>
<td class="text-center radio-custom"><input type="radio" name="r_<?php echo $r_id; ?>_p" value="no"></td>
</tr>
<?php
$n++;
endforeach; ?>
</tbody>
</table>
</div>
<div id="extended_sections">
<h4 class="section-title">ส่วนที่ 4 แบบประเมินข้อตกลงการให้บริการ (SLA)</h4>
<div class="alert alert-warning border-0 text-dark" style="background:#fff8e9;">
<strong>หมายเหตุ:</strong> ส่วนนี้สำหรับเจ้าหน้าที่ที่ใช้คอมพิวเตอร์ในการปฏิบัติงานเท่านั้น
</div>
<div class="table-responsive rounded shadow-sm border border-1 mb-5">
<table class="table table-bordered table-custom mb-0">
<thead>
<tr>
<th rowspan="2" class="align-middle">บริการ</th>
<th rowspan="2" class="align-middle">เวลามาตรฐาน<br>(นาที)</th>
<th colspan="5">ระดับความพึงพอใจ</th>
<th rowspan="2" class="align-middle">ข้อเสนอแนะ / เวลาที่คาดหวัง</th>
</tr>
<tr style="background:#173e55;">
<th>5<br><small>มากที่สุด</small></th>
<th>4<br><small>มาก</small></th>
<th>3<br><small>ปานกลาง</small></th>
<th>2<br><small>น้อย</small></th>
<th>1<br><small>น้อยมาก</small></th>
</tr>
</thead>
<tbody>
<?php
$slas = $pdo_assess->query("SELECT * FROM it_slas WHERE is_active = 1 ORDER BY order_no ASC")->fetchAll();
$n = 1;
foreach ($slas as $sla):
$s_id = $sla['id'];
?>
<tr>
<td><?php echo $n . ". " . htmlspecialchars($sla['service_name']); ?></td>
<td class="text-center"><?php echo $sla['standard_time']; ?></td>
<?php for ($score = 5; $score >= 1; $score--): ?>
<td class="text-center radio-custom"><input type="radio" name="sla_<?php echo $s_id; ?>_score" value="<?php echo $score; ?>" required></td>
<?php endfor; ?>
<td><input type="text" class="form-control form-control-sm" name="sla_<?php echo $s_id; ?>_comment" placeholder="ความคิดเห็น..."></td>
</tr>
<?php
$n++;
endforeach; ?>
</tbody>
</table>
</div>
</div>
<div class="text-center mt-4">
<button type="submit" class="btn btn-submit px-5" id="btnSubmit">บันทึกแบบประเมิน</button>
</div>
</form>
</div>
<?php endif; ?>
</div>
<script>
document.addEventListener("DOMContentLoaded", function() {
const useYes = document.getElementById("use_yes");
const useNo = document.getElementById("use_no");
const extendedSections = document.getElementById("extended_sections");
function toggleSections() {
if (useNo && useNo.checked) {
extendedSections.style.display = "none";
// ยกเลิก required ชั่วคราว
const reqInputs = extendedSections.querySelectorAll('input[required]');
reqInputs.forEach(input => {
input.dataset.required = 'true';
input.removeAttribute('required');
// Clear validation highlights
let row = input.closest('tr');
if (row) row.classList.remove('table-danger');
input.classList.remove('is-invalid');
});
} else {
extendedSections.style.display = "block";
const reqInputs = extendedSections.querySelectorAll('input[data-required="true"]');
reqInputs.forEach(input => {
input.setAttribute('required', 'required');
});
}
}
if (useYes && useNo) {
useYes.addEventListener("change", toggleSections);
useNo.addEventListener("change", toggleSections);
}
// Highlight invalid fields when native HTML5 validation fails
const allInputs = document.querySelectorAll('#assessmentForm input');
allInputs.forEach(input => {
input.addEventListener('invalid', function() {
let row = this.closest('tr');
if (row) {
row.classList.add('table-danger');
} else {
this.classList.add('is-invalid');
}
});
input.addEventListener('change', function() {
let row = this.closest('tr');
if (row) {
// Because radios in the same row might have different names (like Rule K, U, P),
// we shouldn't necessarily remove table-danger if other groups in the same row are still invalid.
// However, a simple approach is to check if the form is valid.
// Actually, checking if the specific required radios are filled is tricky.
// For a better UX, we can just remove table-danger and let them submit again to re-check.
row.classList.remove('table-danger');
} else {
this.classList.remove('is-invalid');
}
});
});
const form = document.getElementById("assessmentForm");
if (form) {
form.addEventListener("submit", function(e) {
e.preventDefault();
// Double check if form is valid (it should be if submit fires, due to HTML5, but just in case)
if (!form.checkValidity()) {
return;
}
Swal.fire({
title: 'ยืนยันการส่งแบบประเมิน?',
text: "โปรดตรวจสอบข้อมูลให้ถูกต้องก่อนกดยืนยัน",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#008f91',
cancelButtonColor: '#d33',
confirmButtonText: 'ยืนยันส่งข้อมูล',
cancelButtonText: 'ยกเลิก'
}).then((result) => {
if (result.isConfirmed) {
form.submit();
}
});
});
}
});
<?php if (isset($_SESSION['success_msg'])): ?>
Swal.fire({
icon: 'success',
title: 'สำเร็จ!',
text: '<?php echo $_SESSION['success_msg']; ?>',
confirmButtonColor: '#008f91'
});
<?php unset($_SESSION['success_msg']); ?>
<?php endif; ?>
<?php if (isset($_SESSION['error_msg'])): ?>
Swal.fire({
icon: 'error',
title: 'เกิดข้อผิดพลาด',
text: '<?php echo $_SESSION['error_msg']; ?>',
confirmButtonColor: '#d33'
});
<?php unset($_SESSION['error_msg']); ?>
<?php endif; ?>
</script>
</body>
</html>