ลิงก์ที่เกี่ยวข้อง
ลิงก์ที่เกี่ยวข้อง
Prompt สำหรับสร้าง Webapp
ในฐานะที่คุณเป็นผู้เชี่ยวชาญด้านการสร้างเว็บ ช่วยฉันสร้าง Prompt ระบบแบบประเมินการสอนของครู ให้หน่อย
เป็นระบบ CRUD ให้มีหน้าตาสวยงาม ใช้ tailwind css
โดยมีรายละเอียดดังนี้
1.
2.
3.
...
- Header : โลโก้ https://img5.pic.in.th/file/secure-sv1/logo-nn.md.png ขนาดเหมาะสม (ไม่เกิน 150px) มี title ระบบแบบประเมินการสอนของครู ไม่ต้องมี background
- Footer: ข้อความ “© 2025 แบบประเมินการสอนของครู | khomkrit paisri” อยู่ตรงกลาง ไม่ต้องมี blackground
- ในการทำ crud ขอให้เก็บข้อมูลจริง และให้เก็บในรูปแบบ json data ที่เป็นมาตรฐาน และให้เก็บโดยใช้ localstorage, ให้ใช้ jquery,jquery validate, sweet alert, loading ขนาดเล็ก ให้ด้วยตอนสถานะรอการทำงาน
- ขอแค่ prompt นะ และขอเป็นภาษาไทยด้วย ยาวไม่เกิน 4000 อักขระ
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ระบบแบบประเมินการสอนของครู</title>
<!-- Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- jQuery Validate -->
<script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.19.5/dist/jquery.validate.min.js"></script>
<!-- SweetAlert2 -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<!-- Custom CSS for Loading Spinner -->
<style>
.spinner {
border: 3px solid #f3f3f3;
border-top: 3px solid #3498db;
border-radius: 50%;
width: 30px;
height: 30px;
animation: spin 1s linear infinite;
margin: 0 auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loading-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.loading-content {
background: white;
padding: 20px;
border-radius: 10px;
text-align: center;
}
</style>
</head>
<body class="bg-gray-100 min-h-screen">
<!-- Loading Overlay -->
<div id="loadingOverlay" class="loading-overlay hidden">
<div class="loading-content">
<div class="spinner"></div>
<p class="mt-3 text-gray-600">กำลังดำเนินการ...</p>
</div>
</div>
<!-- Header -->
<header class="bg-blue-600 text-white py-8">
<div class="container mx-auto px-4">
<div class="flex items-center justify-center space-x-4">
<img src="https://img5.pic.in.th/file/secure-sv1/logo-nn.md.png"
alt="Logo"
class="h-16 w-auto object-contain">
<div class="text-center">
<h1 class="text-3xl font-bold mb-2">ระบบแบบประเมินการสอนของครู</h1>
<p class="text-blue-100">จัดการและติดตามผลการประเมินครูอย่างมีประสิทธิภาพ</p>
</div>
</div>
</div>
</header>
<!-- Main Content -->
<main class="container mx-auto px-4 py-8">
<!-- Evaluation Form -->
<div class="bg-white rounded-lg shadow-md p-6 mb-6">
<h2 class="text-2xl font-bold text-gray-800 mb-6">
<span id="formTitle">เพิ่มการประเมินใหม่</span>
</h2>
<form id="evaluationForm" class="space-y-4">
<input type="hidden" id="editId" value="">
<!-- Teacher Name -->
<div>
<label for="teacherName" class="block text-sm font-medium text-gray-700 mb-2">
ชื่อครู <span class="text-red-500">*</span>
</label>
<input type="text"
id="teacherName"
name="teacherName"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
placeholder="กรอกชื่อครู">
</div>
<!-- Subject -->
<div>
<label for="subject" class="block text-sm font-medium text-gray-700 mb-2">
วิชา <span class="text-red-500">*</span>
</label>
<input type="text"
id="subject"
name="subject"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
placeholder="กรอกชื่อวิชา">
</div>
<!-- Score -->
<div>
<label for="score" class="block text-sm font-medium text-gray-700 mb-2">
คะแนนประเมิน (1-5) <span class="text-red-500">*</span>
</label>
<select id="score"
name="score"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">
<option value="">เลือกคะแนน</option>
<option value="1">1 - ต้องปรับปรุง</option>
<option value="2">2 - พอใช้</option>
<option value="3">3 - ปานกลาง</option>
<option value="4">4 - ดี</option>
<option value="5">5 - ดีเยี่ยม</option>
</select>
</div>
<!-- Comments -->
<div>
<label for="comments" class="block text-sm font-medium text-gray-700 mb-2">
ความคิดเห็น
</label>
<textarea id="comments"
name="comments"
rows="4"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
placeholder="กรอกความคิดเห็นเพิ่มเติม (ไม่บังคับ)"></textarea>
</div>
<!-- Form Buttons -->
<div class="flex space-x-4">
<button type="submit"
class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-md font-medium transition duration-200 flex-1">
<span id="submitText">บันทึกการประเมิน</span>
</button>
<button type="button"
id="cancelEdit"
class="bg-gray-500 hover:bg-gray-600 text-white px-6 py-2 rounded-md font-medium transition duration-200 hidden">
ยกเลิก
</button>
</div>
</form>
</div>
<!-- Evaluations List -->
<div class="bg-white rounded-lg shadow-md p-6">
<h2 class="text-2xl font-bold text-gray-800 mb-6">รายการการประเมิน</h2>
<!-- Search and Filter -->
<div class="mb-4">
<input type="text"
id="searchInput"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
placeholder="ค้นหาชื่อครูหรือวิชา...">
</div>
<!-- Evaluations Table/Cards -->
<div id="evaluationsList" class="space-y-4">
<!-- Dynamic content will be inserted here -->
</div>
<!-- Empty State -->
<div id="emptyState" class="text-center py-8 text-gray-500 hidden">
<svg class="mx-auto h-12 w-12 text-gray-400 mb-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
<p class="text-lg">ยังไม่มีการประเมิน</p>
<p class="text-sm">เริ่มต้นโดยการเพิ่มการประเมินครูคนแรก</p>
</div>
</div>
</div>
</main>
<!-- Footer -->
<footer class="bg-blue-600 text-white py-6 mt-8">
<div class="container mx-auto px-4 text-center">
<p class="mb-2">© 2025 แบบประเมินการสอนของครู</p>
<p class="text-blue-100">พัฒนาโดย khomkrit paisri</p>
</div>
</footer>
<script>
// Global variables
let evaluations = [];
let editingId = null;
// Initialize the application
$(document).ready(function() {
loadEvaluations();
setupFormValidation();
setupEventListeners();
renderEvaluations();
});
// Setup form validation
function setupFormValidation() {
$("#evaluationForm").validate({
rules: {
teacherName: {
required: true,
minlength: 2
},
subject: {
required: true,
minlength: 2
},
score: {
required: true,
range: [1, 5]
}
},
messages: {
teacherName: {
required: "กรุณากรอกชื่อครู",
minlength: "ชื่อครูต้องมีอย่างน้อย 2 ตัวอักษร"
},
subject: {
required: "กรุณากรอกชื่อวิชา",
minlength: "ชื่อวิชาต้องมีอย่างน้อย 2 ตัวอักษร"
},
score: {
required: "กรุณาเลือกคะแนนประเมิน",
range: "คะแนนต้องอยู่ระหว่าง 1-5"
}
},
errorClass: "text-red-500 text-sm mt-1",
errorElement: "div",
submitHandler: function(form) {
handleFormSubmit();
}
});
}
// Setup event listeners
function setupEventListeners() {
// Search functionality
$("#searchInput").on("input", function() {
const searchTerm = $(this).val().toLowerCase();
filterEvaluations(searchTerm);
});
// Cancel edit button
$("#cancelEdit").click(function() {
resetForm();
});
}
// Show loading overlay
function showLoading() {
$("#loadingOverlay").removeClass("hidden");
}
// Hide loading overlay
function hideLoading() {
$("#loadingOverlay").addClass("hidden");
}
// Generate unique ID
function generateId() {
return Date.now().toString() + Math.random().toString(36).substr(2, 9);
}
// Load evaluations from localStorage
function loadEvaluations() {
const stored = localStorage.getItem('teacherEvaluations');
if (stored) {
evaluations = JSON.parse(stored);
}
}
// Save evaluations to localStorage
function saveEvaluations() {
localStorage.setItem('teacherEvaluations', JSON.stringify(evaluations));
}
// Handle form submission
function handleFormSubmit() {
showLoading();
// Simulate processing time
setTimeout(() => {
const formData = {
teacherName: $("#teacherName").val().trim(),
subject: $("#subject").val().trim(),
score: parseInt($("#score").val()),
comments: $("#comments").val().trim(),
createdAt: new Date().toISOString()
};
if (editingId) {
// Update existing evaluation
const index = evaluations.findIndex(eval => eval.id === editingId);
if (index !== -1) {
evaluations[index] = { ...evaluations[index], ...formData };
saveEvaluations();
renderEvaluations();
resetForm();
hideLoading();
Swal.fire({
icon: 'success',
title: 'สำเร็จ!',
text: 'อัปเดตการประเมินเรียบร้อยแล้ว',
timer: 2000,
showConfirmButton: false
});
}
} else {
// Create new evaluation
const newEvaluation = {
id: generateId(),
...formData
};
evaluations.unshift(newEvaluation);
saveEvaluations();
renderEvaluations();
resetForm();
hideLoading();
Swal.fire({
icon: 'success',
title: 'สำเร็จ!',
text: 'บันทึกการประเมินเรียบร้อยแล้ว',
timer: 2000,
showConfirmButton: false
});
}
}, 1000);
}
// Reset form to initial state
function resetForm() {
$("#evaluationForm")[0].reset();
$("#evaluationForm").validate().resetForm();
$("#editId").val("");
$("#formTitle").text("เพิ่มการประเมินใหม่");
$("#submitText").text("บันทึกการประเมิน");
$("#cancelEdit").addClass("hidden");
editingId = null;
}
// Edit evaluation
function editEvaluation(id) {
const evaluation = evaluations.find(eval => eval.id === id);
if (evaluation) {
$("#teacherName").val(evaluation.teacherName);
$("#subject").val(evaluation.subject);
$("#score").val(evaluation.score);
$("#comments").val(evaluation.comments);
$("#editId").val(id);
$("#formTitle").text("แก้ไขการประเมิน");
$("#submitText").text("อัปเดตการประเมิน");
$("#cancelEdit").removeClass("hidden");
editingId = id;
// Scroll to form
$('html, body').animate({
scrollTop: $("#evaluationForm").offset().top - 100
}, 500);
}
}
// Delete evaluation
function deleteEvaluation(id) {
Swal.fire({
title: 'ยืนยันการลบ',
text: 'คุณต้องการลบการประเมินนี้หรือไม่?',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#d33',
cancelButtonColor: '#3085d6',
confirmButtonText: 'ลบ',
cancelButtonText: 'ยกเลิก'
}).then((result) => {
if (result.isConfirmed) {
showLoading();
setTimeout(() => {
evaluations = evaluations.filter(eval => eval.id !== id);
saveEvaluations();
renderEvaluations();
hideLoading();
Swal.fire({
icon: 'success',
title: 'ลบเรียบร้อย!',
text: 'การประเมินถูกลบแล้ว',
timer: 2000,
showConfirmButton: false
});
}, 500);
}
});
}
// Get score text
function getScoreText(score) {
const scoreTexts = {
1: 'ต้องปรับปรุง',
2: 'พอใช้',
3: 'ปานกลาง',
4: 'ดี',
5: 'ดีเยี่ยม'
};
return scoreTexts[score] || 'ไม่ระบุ';
}
// Get score color
function getScoreColor(score) {
const colors = {
1: 'bg-red-100 text-red-800',
2: 'bg-orange-100 text-orange-800',
3: 'bg-yellow-100 text-yellow-800',
4: 'bg-blue-100 text-blue-800',
5: 'bg-green-100 text-green-800'
};
return colors[score] || 'bg-gray-100 text-gray-800';
}
// Format date
function formatDate(dateString) {
const date = new Date(dateString);
return date.toLocaleDateString('th-TH', {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
}
// Render evaluations
function renderEvaluations() {
const container = $("#evaluationsList");
const emptyState = $("#emptyState");
if (evaluations.length === 0) {
container.empty();
emptyState.removeClass("hidden");
return;
}
emptyState.addClass("hidden");
const html = evaluations.map(evaluation => `
<div class="evaluation-card border border-gray-200 rounded-lg p-4 hover:shadow-md transition-shadow duration-200">
<div class="flex flex-col md:flex-row md:items-center md:justify-between">
<div class="flex-1">
<div class="flex flex-col md:flex-row md:items-center md:space-x-4 mb-2">
<h3 class="text-lg font-semibold text-gray-800">${evaluation.teacherName}</h3>
<span class="text-sm text-gray-600">${evaluation.subject}</span>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${getScoreColor(evaluation.score)}">
${evaluation.score}/5 - ${getScoreText(evaluation.score)}
</span>
</div>
${evaluation.comments ? `
<p class="text-gray-600 text-sm mb-2">${evaluation.comments}</p>
` : ''}
<p class="text-xs text-gray-500">
วันที่ประเมิน: ${formatDate(evaluation.createdAt)}
</p>
</div>
<div class="flex space-x-2 mt-3 md:mt-0">
<button onclick="editEvaluation('${evaluation.id}')"
class="bg-yellow-500 hover:bg-yellow-600 text-white px-3 py-1 rounded text-sm transition duration-200">
แก้ไข
</button>
<button onclick="deleteEvaluation('${evaluation.id}')"
class="bg-red-500 hover:bg-red-600 text-white px-3 py-1 rounded text-sm transition duration-200">
ลบ
</button>
</div>
</div>
</div>
`).join('');
container.html(html);
}
// Filter evaluations based on search term
function filterEvaluations(searchTerm) {
const cards = $(".evaluation-card");
if (!searchTerm) {
cards.show();
return;
}
cards.each(function() {
const card = $(this);
const text = card.text().toLowerCase();
if (text.includes(searchTerm)) {
card.show();
} else {
card.hide();
}
});
}
</script>
</body>
</html>
function doGet(e) {
return HtmlService
.createTemplateFromFile('index')
.evaluate()
.setTitle('ระบบประเมินการสอนของครู')
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ระบบแบบประเมินภาวะซึมเศร้า</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.19.5/dist/jquery.validate.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<style>
.loader {
border: 2px solid #f3f3f3;
border-top: 2px solid #3498db;
border-radius: 50%;
width: 20px;
height: 20px;
animation: spin 1s linear infinite;
display: inline-block;
margin-right: 8px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.error {
color: #ef4444;
font-size: 0.875rem;
margin-top: 0.25rem;
}
</style>
</head>
<body class="bg-gradient-to-br from-blue-50 to-indigo-100 min-h-screen">
<!-- Header -->
<header class="bg-transparent py-6">
<div class="container mx-auto px-4">
<div class="flex items-center justify-center">
<img src="https://img5.pic.in.th/file/secure-sv1/logo-nn.md.png" alt="Logo" class="h-24 w-auto mr-4">
<h1 class="text-3xl font-bold text-gray-800">ระบบแบบประเมินภาวะซึมเศร้า</h1>
</div>
</div>
</header>
<div class="container mx-auto px-4 pb-20">
<!-- Assessment Form -->
<div class="bg-white rounded-lg shadow-lg p-8 mb-8">
<h2 class="text-2xl font-semibold text-gray-800 mb-6">แบบประเมินภาวะซึมเศร้า (PHQ-9)</h2>
<form id="assessmentForm" class="space-y-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">ชื่อผู้ประเมิน *</label>
<input type="text" id="assessorName" name="assessorName" required
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">วันที่ประเมิน *</label>
<input type="datetime-local" id="assessmentDate" name="assessmentDate" required
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
</div>
</div>
<!-- PHQ-9 Questions -->
<div class="space-y-4">
<h3 class="text-lg font-medium text-gray-800 mb-4">คำถาม PHQ-9 (ในช่วง 2 สัปดาห์ที่ผ่านมา คุณรู้สึกรำคาญหรือหดหู่ใจเพราะปัญหาต่อไปนี้บ่อยแค่ไหน)</h3>
<div class="phq9-question">
<label class="block text-sm font-medium text-gray-700 mb-2">1. เบื่อหน่าย ไม่สนใจ หรือไม่มีความสุขในการทำกิจกรรมต่างๆ *</label>
<select name="q1" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
<option value="">เลือกคำตอบ</option>
<option value="0">ไม่เลย (0 คะแนน)</option>
<option value="1">หลายวัน (1 คะแนน)</option>
<option value="2">มากกว่าครึ่งของจำนวนวัน (2 คะแนน)</option>
<option value="3">เกือบทุกวัน (3 คะแนน)</option>
</select>
</div>
<div class="phq9-question">
<label class="block text-sm font-medium text-gray-700 mb-2">2. รู้สึกหดหู่ ท้อแท้ หรือสิ้นหวัง *</label>
<select name="q2" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
<option value="">เลือกคำตอบ</option>
<option value="0">ไม่เลย (0 คะแนน)</option>
<option value="1">หลายวัน (1 คะแนน)</option>
<option value="2">มากกว่าครึ่งของจำนวนวัน (2 คะแนน)</option>
<option value="3">เกือบทุกวัน (3 คะแนน)</option>
</select>
</div>
<div class="phq9-question">
<label class="block text-sm font-medium text-gray-700 mb-2">3. หลับยาก นอนไม่หลับ หรือนอนมากเกินไป *</label>
<select name="q3" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
<option value="">เลือกคำตอบ</option>
<option value="0">ไม่เลย (0 คะแนน)</option>
<option value="1">หลายวัน (1 คะแนน)</option>
<option value="2">มากกว่าครึ่งของจำนวนวัน (2 คะแนน)</option>
<option value="3">เกือบทุกวัน (3 คะแนน)</option>
</select>
</div>
<div class="phq9-question">
<label class="block text-sm font-medium text-gray-700 mb-2">4. รู้สึกเหนื่อยหรือไม่มีพลังงาน *</label>
<select name="q4" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
<option value="">เลือกคำตอบ</option>
<option value="0">ไม่เลย (0 คะแนน)</option>
<option value="1">หลายวัน (1 คะแนน)</option>
<option value="2">มากกว่าครึ่งของจำนวนวัน (2 คะแนน)</option>
<option value="3">เกือบทุกวัน (3 คะแนน)</option>
</select>
</div>
<div class="phq9-question">
<label class="block text-sm font-medium text-gray-700 mb-2">5. เบื่ออาหาร หรือกินมากเกินไป *</label>
<select name="q5" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
<option value="">เลือกคำตอบ</option>
<option value="0">ไม่เลย (0 คะแนน)</option>
<option value="1">หลายวัน (1 คะแนน)</option>
<option value="2">มากกว่าครึ่งของจำนวนวัน (2 คะแนน)</option>
<option value="3">เกือบทุกวัน (3 คะแนน)</option>
</select>
</div>
<div class="phq9-question">
<label class="block text-sm font-medium text-gray-700 mb-2">6. รู้สึกแย่กับตัวเอง หรือรู้สึกว่าตัวเองล้มเหลว หรือทำให้ตัวเองหรือครอบครัวผิดหวัง *</label>
<select name="q6" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
<option value="">เลือกคำตอบ</option>
<option value="0">ไม่เลย (0 คะแนน)</option>
<option value="1">หลายวัน (1 คะแนน)</option>
<option value="2">มากกว่าครึ่งของจำนวนวัน (2 คะแนน)</option>
<option value="3">เกือบทุกวัน (3 คะแนน)</option>
</select>
</div>
<div class="phq9-question">
<label class="block text-sm font-medium text-gray-700 mb-2">7. มีปัญหาในการจดจ่อ เช่น การอ่านหนังสือพิมพ์ หรือดูโทรทัศน์ *</label>
<select name="q7" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
<option value="">เลือกคำตอบ</option>
<option value="0">ไม่เลย (0 คะแนน)</option>
<option value="1">หลายวัน (1 คะแนน)</option>
<option value="2">มากกว่าครึ่งของจำนวนวัน (2 คะแนน)</option>
<option value="3">เกือบทุกวัน (3 คะแนน)</option>
</select>
</div>
<div class="phq9-question">
<label class="block text-sm font-medium text-gray-700 mb-2">8. เคลื่อนไหวหรือพูดช้าจนคนอื่นสังเกตเห็น หรือกระสับกระส่าย ไม่สามารถนิ่งอยู่กับที่ได้ *</label>
<select name="q8" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
<option value="">เลือกคำตอบ</option>
<option value="0">ไม่เลย (0 คะแนน)</option>
<option value="1">หลายวัน (1 คะแนน)</option>
<option value="2">มากกว่าครึ่งของจำนวนวัน (2 คะแนน)</option>
<option value="3">เกือบทุกวัน (3 คะแนน)</option>
</select>
</div>
<div class="phq9-question">
<label class="block text-sm font-medium text-gray-700 mb-2">9. คิดว่าตายไปเสียจะดีกว่า หรือคิดทำร้ายตัวเอง *</label>
<select name="q9" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
<option value="">เลือกคำตอบ</option>
<option value="0">ไม่เลย (0 คะแนน)</option>
<option value="1">หลายวัน (1 คะแนน)</option>
<option value="2">มากกว่าครึ่งของจำนวนวัน (2 คะแนน)</option>
<option value="3">เกือบทุกวัน (3 คะแนน)</option>
</select>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">คะแนนรวม</label>
<input type="number" id="totalScore" name="totalScore" readonly
class="w-full px-4 py-2 border border-gray-300 rounded-lg bg-gray-50">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">บันทึกเพิ่มเติม</label>
<textarea id="notes" name="notes" rows="3"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"></textarea>
</div>
<div class="flex gap-4">
<button type="submit" id="submitBtn"
class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg font-medium transition-colors">
<span class="loader" id="submitLoader" style="display: none;"></span>
<span id="submitText">บันทึกข้อมูล</span>
</button>
<button type="button" id="cancelBtn"
class="bg-gray-500 hover:bg-gray-600 text-white px-6 py-2 rounded-lg font-medium transition-colors">
ยกเลิก
</button>
</div>
</form>
</div>
<!-- Assessment List -->
<div class="bg-white rounded-lg shadow-lg p-8">
<h2 class="text-2xl font-semibold text-gray-800 mb-6">รายการแบบประเมิน</h2>
<div class="overflow-x-auto">
<table class="w-full table-auto">
<thead>
<tr class="bg-gray-50">
<th class="px-4 py-3 text-left text-sm font-medium text-gray-700">ชื่อผู้ประเมิน</th>
<th class="px-4 py-3 text-left text-sm font-medium text-gray-700">วันที่ประเมิน</th>
<th class="px-4 py-3 text-left text-sm font-medium text-gray-700">คะแนนรวม</th>
<th class="px-4 py-3 text-left text-sm font-medium text-gray-700">ระดับความรุนแรง</th>
<th class="px-4 py-3 text-center text-sm font-medium text-gray-700">การจัดการ</th>
</tr>
</thead>
<tbody id="assessmentList">
<!-- Data will be populated here -->
</tbody>
</table>
</div>
</div>
</div>
<!-- Footer -->
<footer class="bg-transparent py-6 mt-12">
<div class="container mx-auto px-4">
<p class="text-center text-gray-600">© 2025 แบบประเมินภาวะซึมเศร้า | khomkrit paisri</p>
</div>
</footer>
<script>
$(document).ready(function() {
let editingId = null;
// Set current date/time as default
$('#assessmentDate').val(new Date().toISOString().slice(0, 16));
// Form validation
$('#assessmentForm').validate({
rules: {
assessorName: {
required: true,
minlength: 2
},
assessmentDate: {
required: true
},
q1: { required: true },
q2: { required: true },
q3: { required: true },
q4: { required: true },
q5: { required: true },
q6: { required: true },
q7: { required: true },
q8: { required: true },
q9: { required: true }
},
messages: {
assessorName: {
required: "กรุณากรอกชื่อผู้ประเมิน",
minlength: "ชื่อต้องมีอย่างน้อย 2 ตัวอักษร"
},
assessmentDate: "กรุณาเลือกวันที่ประเมิน",
q1: "กรุณาเลือกคำตอบสำหรับคำถามข้อ 1",
q2: "กรุณาเลือกคำตอบสำหรับคำถามข้อ 2",
q3: "กรุณาเลือกคำตอบสำหรับคำถามข้อ 3",
q4: "กรุณาเลือกคำตอบสำหรับคำถามข้อ 4",
q5: "กรุณาเลือกคำตอบสำหรับคำถามข้อ 5",
q6: "กรุณาเลือกคำตอบสำหรับคำถามข้อ 6",
q7: "กรุณาเลือกคำตอบสำหรับคำถามข้อ 7",
q8: "กรุณาเลือกคำตอบสำหรับคำถามข้อ 8",
q9: "กรุณาเลือกคำตอบสำหรับคำถามข้อ 9"
},
submitHandler: function(form) {
saveAssessment();
}
});
// Calculate total score when answers change
$('select[name^="q"]').change(function() {
calculateTotalScore();
});
function calculateTotalScore() {
let total = 0;
for (let i = 1; i <= 9; i++) {
const value = parseInt($(`select[name="q${i}"]`).val()) || 0;
total += value;
}
$('#totalScore').val(total);
}
function getSeverityLevel(score) {
if (score >= 0 && score <= 4) return { text: 'ไม่มีอาการซึมเศร้า', class: 'text-green-600' };
if (score >= 5 && score <= 9) return { text: 'อาการซึมเศร้าระดับเล็กน้อย', class: 'text-yellow-600' };
if (score >= 10 && score <= 14) return { text: 'อาการซึมเศร้าระดับปานกลาง', class: 'text-orange-600' };
if (score >= 15 && score <= 19) return { text: 'อาการซึมเศร้าระดับรุนแรงปานกลาง', class: 'text-red-600' };
if (score >= 20) return { text: 'อาการซึมเศร้าระดับรุนแรง', class: 'text-red-800' };
return { text: '-', class: '' };
}
function saveAssessment() {
$('#submitLoader').show();
$('#submitText').text('กำลังบันทึก...');
$('#submitBtn').prop('disabled', true);
setTimeout(function() {
const formData = {
id: editingId || Date.now().toString(),
assessorName: $('#assessorName').val(),
assessmentDate: $('#assessmentDate').val(),
answers: {},
totalScore: parseInt($('#totalScore').val()),
notes: $('#notes').val(),
createdAt: editingId ? getAssessmentById(editingId).createdAt : new Date().toISOString(),
updatedAt: new Date().toISOString()
};
// Collect all answers
for (let i = 1; i <= 9; i++) {
formData.answers[`q${i}`] = parseInt($(`select[name="q${i}"]`).val());
}
// Get existing data
let assessments = JSON.parse(localStorage.getItem('depressionAssessments') || '[]');
if (editingId) {
// Update existing
const index = assessments.findIndex(a => a.id === editingId);
if (index !== -1) {
assessments[index] = formData;
}
} else {
// Add new
assessments.push(formData);
}
// Save to localStorage
localStorage.setItem('depressionAssessments', JSON.stringify(assessments));
$('#submitLoader').hide();
$('#submitText').text('บันทึกข้อมูล');
$('#submitBtn').prop('disabled', false);
Swal.fire({
icon: 'success',
title: 'สำเร็จ!',
text: editingId ? 'แก้ไขข้อมูลเรียบร้อยแล้ว' : 'บันทึกข้อมูลเรียบร้อยแล้ว',
confirmButtonColor: '#3b82f6'
});
resetForm();
loadAssessments();
}, 1000);
}
function resetForm() {
$('#assessmentForm')[0].reset();
$('#assessmentDate').val(new Date().toISOString().slice(0, 16));
$('#totalScore').val('');
editingId = null;
$('#submitText').text('บันทึกข้อมูล');
}
function loadAssessments() {
const assessments = JSON.parse(localStorage.getItem('depressionAssessments') || '[]');
const tbody = $('#assessmentList');
tbody.empty();
if (assessments.length === 0) {
tbody.append(`
<tr>
<td colspan="5" class="px-4 py-8 text-center text-gray-500">
ยังไม่มีข้อมูลแบบประเมิน
</td>
</tr>
`);
return;
}
assessments.sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt));
assessments.forEach(assessment => {
const date = new Date(assessment.assessmentDate);
const formattedDate = date.toLocaleDateString('th-TH') + ' ' + date.toLocaleTimeString('th-TH', { hour: '2-digit', minute: '2-digit' });
const severity = getSeverityLevel(assessment.totalScore);
tbody.append(`
<tr class="border-b hover:bg-gray-50">
<td class="px-4 py-3">${assessment.assessorName}</td>
<td class="px-4 py-3">${formattedDate}</td>
<td class="px-4 py-3 font-semibold">${assessment.totalScore}</td>
<td class="px-4 py-3 ${severity.class} font-medium">${severity.text}</td>
<td class="px-4 py-3 text-center">
<button onclick="viewAssessment('${assessment.id}')"
class="bg-blue-500 hover:bg-blue-600 text-white px-3 py-1 rounded text-sm mr-1">
ดู
</button>
<button onclick="editAssessment('${assessment.id}')"
class="bg-yellow-500 hover:bg-yellow-600 text-white px-3 py-1 rounded text-sm mr-1">
แก้ไข
</button>
<button onclick="deleteAssessment('${assessment.id}')"
class="bg-red-500 hover:bg-red-600 text-white px-3 py-1 rounded text-sm">
ลบ
</button>
</td>
</tr>
`);
});
}
function getAssessmentById(id) {
const assessments = JSON.parse(localStorage.getItem('depressionAssessments') || '[]');
return assessments.find(a => a.id === id);
}
// Global functions for buttons
window.viewAssessment = function(id) {
const assessment = getAssessmentById(id);
if (!assessment) return;
const date = new Date(assessment.assessmentDate);
const formattedDate = date.toLocaleDateString('th-TH') + ' ' + date.toLocaleTimeString('th-TH');
const severity = getSeverityLevel(assessment.totalScore);
let answersHtml = '';
const questions = [
'เบื่อหน่าย ไม่สนใจ หรือไม่มีความสุขในการทำกิจกรรมต่างๆ',
'รู้สึกหดหู่ ท้อแท้ หรือสิ้นหวัง',
'หลับยาก นอนไม่หลับ หรือนอนมากเกินไป',
'รู้สึกเหนื่อยหรือไม่มีพลังงาน',
'เบื่ออาหาร หรือกินมากเกินไป',
'รู้สึกแย่กับตัวเอง หรือรู้สึกว่าตัวเองล้มเหลว',
'มีปัญหาในการจดจ่อ เช่น การอ่านหนังสือพิมพ์ หรือดูโทรทัศน์',
'เคลื่อนไหวหรือพูดช้าจนคนอื่นสังเกตเห็น หรือกระสับกระส่าย',
'คิดว่าตายไปเสียจะดีกว่า หรือคิดทำร้ายตัวเอง'
];
const scoreText = ['ไม่เลย', 'หลายวัน', 'มากกว่าครึ่งของจำนวนวัน', 'เกือบทุกวัน'];
for (let i = 1; i <= 9; i++) {
const score = assessment.answers[`q${i}`];
answersHtml += `<p><strong>ข้อ ${i}:</strong> ${questions[i-1]} - <span class="text-blue-600">${scoreText[score]} (${score} คะแนน)</span></p>`;
}
Swal.fire({
title: 'รายละเอียดแบบประเมิน',
html: `
<div class="text-left space-y-2">
<p><strong>ชื่อผู้ประเมิน:</strong> ${assessment.assessorName}</p>
<p><strong>วันที่ประเมิน:</strong> ${formattedDate}</p>
<p><strong>คะแนนรวม:</strong> <span class="text-lg font-bold ${severity.class}">${assessment.totalScore} คะแนน</span></p>
<p><strong>ระดับความรุนแรง:</strong> <span class="${severity.class} font-medium">${severity.text}</span></p>
<hr class="my-4">
<div class="space-y-1 text-sm">
${answersHtml}
</div>
${assessment.notes ? `<hr class="my-4"><p><strong>บันทึกเพิ่มเติม:</strong> ${assessment.notes}</p>` : ''}
</div>
`,
width: '600px',
confirmButtonColor: '#3b82f6'
});
};
window.editAssessment = function(id) {
const assessment = getAssessmentById(id);
if (!assessment) return;
editingId = id;
$('#assessorName').val(assessment.assessorName);
$('#assessmentDate').val(assessment.assessmentDate);
$('#notes').val(assessment.notes);
// Set answers
for (let i = 1; i <= 9; i++) {
$(`select[name="q${i}"]`).val(assessment.answers[`q${i}`]);
}
calculateTotalScore();
$('#submitText').text('อัปเดตข้อมูล');
// Scroll to form
$('html, body').animate({
scrollTop: $('#assessmentForm').offset().top - 100
}, 500);
};
window.deleteAssessment = function(id) {
Swal.fire({
title: 'ยืนยันการลบ',
text: 'คุณต้องการลบข้อมูลแบบประเมินนี้หรือไม่?',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#ef4444',
cancelButtonColor: '#6b7280',
confirmButtonText: 'ลบ',
cancelButtonText: 'ยกเลิก'
}).then((result) => {
if (result.isConfirmed) {
let assessments = JSON.parse(localStorage.getItem('depressionAssessments') || '[]');
assessments = assessments.filter(a => a.id !== id);
localStorage.setItem('depressionAssessments', JSON.stringify(assessments));
Swal.fire({
icon: 'success',
title: 'ลบสำเร็จ!',
text: 'ลบข้อมูลแบบประเมินเรียบร้อยแล้ว',
confirmButtonColor: '#3b82f6'
});
loadAssessments();
}
});
};
// Cancel button
$('#cancelBtn').click(function() {
resetForm();
});
// Load assessments on page load
loadAssessments();
});
</script>
</body>
</html>
นี่คือ javascript ของไฟล์ index.html ใน google appscript โดยขอให้ปรับไปใช้ข้อมูลจริงจาก google sheet ในการทำ crud โดย google appscript เรียก google sheet ด้วยการใช้ getActiveSheet หากข้อมูลจำเป็นต้อง ใช้ sheetname อะไร และหากไม่มี sheetname นั้นให้ google appscript สร้าง sheetname นั้นให้ และหากไม่มี column header ให้ google appscript สร้าง column header ให้ด้วย ขอ code.gs และปรับ index.html ให้ด้วย
https://script.google.com/macros/s/AKfycbyBx2M0ztnnnDxQ16Sx1I_Q9ijxs8oCHjDPXy-LsibFy1es3kFTbXned0BjTSYjk9wwgg/exec
นี่คือโครงสร้างเว็บ ใน google appscript ชื่อว่า index.html โดยขอให้ปรับไปใช้ข้อมูลจริงจาก google sheet ในการทำ crud โดย google appscript เรียก google sheet ด้วยการใช้ getActiveSheet หากข้อมูลจำเป็นต้อง ใช้ sheetname อะไร และหากไม่มี sheetname นั้นให้ google appscript สร้าง sheetname นั้นให้ และหากไม่มี column header ให้ google appscript สร้าง column header ให้ด้วย ขอ code.gs และปรับ index.html ให้ด้วย
https://script.google.com/macros/s/AKfycbyBx2M0ztnnnDxQ16Sx1I_Q9ijxs8oCHjDPXy-LsibFy1es3kFTbXned0BjTSYjk9wwgg/exec
ในฐานะที่คุณเป็นผู้เชี่ยวชาญด้านการสร้างเว็บ ช่วยฉันสร้าง Prompt ระบบแบบลงทะเบียนและรับเกียรติบัตรสัปดาห์วันวิทยาศาสตร์แห่งชาติ โรงเรียนเนินสง่าวิทยา ให้หน่อย
เป็นระบบ CRUD ให้มีหน้าตาสวยงามและทันสมัยสุดๆ
- แถบเมนูสีเข้ม อยู่ทางซ้าย จากด้านบนจนสุดด้านล่าง
- เมนูที่ 1 เมนูสมัครเข้าร่ามกิจกรรม
- มีดรอปดาวเลือกกิจกรรม เมื่อเลือกแล้วจะมีข้อความแจ้ง รายละเอียด ห้วงวันเวลาเปิดรับสมัคร ห้วงวันเวลาจัดกิจกรรม/แข่งขัน สถานที่จัดกิจกรรม/แข่งขัน จำนวนผู้สมัครที่จะสามารถกรอกมาได้
- หน้าคำนำหน้า ชื่อ-นามสกุล มีดอปดาวน์เลือกชั้น
- มีช่องกรอก คำนำหน้า ชื่อ-นามสกุล ได้จำนวนแถวเท่ากับจำนวนผู้สมัครที่จะสามารถกรอกมาได้ที่ครูกำหนดไว้
- เมนูที่ 2 เมนู รายชื่อผู้เข้าร่วมกิจกรรม
- user ครู และ admin สามารถ ค้นหา ดู แก้ไข และลบได้
- นักเรียน สามารถค้นหา ดู ได้เท่านั้น
- เมนูที่ 3 เมนู เกียรติบัตร
- มีช่องค้นหาจากชื่อ-นามสกุล มีดอปดาวน์เลือกกิจกรรมหรือทั้งหมด
- ด้านท้ายของเลขที่นักเรียน user ครู และ admin จะต้องกรอกรันรหัสเกียรติบัตรก่อน ทั้งนักเรียน ครู และ admin ถึงจะสามารถกดดาวโหลดไฟล์ได้
- เมื่อกดดาวโหลดไฟล์ ระบบถึงจะประมวลผลไฟล์ภาพเกียรติพร้อมชื่อ-นามสกุลให้ และเมื่อดาวโหลดสำเร็จก็ให้ลบไฟล์ยั้นออกจากระบบเพื่ิอลดพื้นเก็บข้อมูล
- เมนู ล่างสุดเสมอ ลงชื่อเข้าใช้ (ถ้าลงชื่อเข้าใช้แล้ว จะเห็นเป็น logout แทน)
- user:admin และ pass:password1 ใช้สิทธิแอดมิน ทำได้ทุกอย่าง รวมถึงมีเมนูให้สร้าง user/pass ให้ครูได้ด้วย
- user ครู และ admin จะมีเมนู จัดการกิจกรรม คือ สามารถเพิ่มรายชื่อกิจกรรม รายละเอียด ห้วงวันเวลาเปิดรับสมัคร ห้วงวันเวลาจัดกิจกรรม/แข่งขัน สถานที่จัดกิจกรรม/แข่งขัน จำนวนผู้สมัครที่จะสามารถกรอกมาได้
- user ครู และ admin จะมีเมนู อัพโหลดไฟล์เกียรติบัตรแม่แบบ ขนาด A4 แนวนอน โดยจะกรอกเป็นลิงก์ไฟล์รูปภาพเอา โดยจะให้กรอกลิงก์และสามารถเลือกประเภทของฟอนต์ ขนาดของฟอนต์ สีของฟอนต์ตามรหัสสี และสามารถกรอกพิกัดการวางข้อความบนแม่แบบ และจัดกึ่งกลาง สามารถเลือกตัวหนาตัวบาง
- user ครู และ admin จะมีเมนู จัดการข้อมูลนักเรียน ที่ประกอบด้วย 1. คำนำหน้า 2. ชื่อ 3. นามสกุล 4. ชั้น 5. เลขที่ โดยสามารถกรอกทีละคน และอัพโหลดด้วยไฟล์ CSV ได้ จาก Sheet1 และคอลัม 1. คำนำหน้า 2. ชื่อ 3. นามสกุล 4. ชั้น 5. เลขที่ ตามลำดับ
- Header : โลโก้ https://img5.pic.in.th/file/secure-sv1/logo-nn.md.png ขนาดเหมาะสม (ไม่เกิน 150px) มี title สัปดาห์วันวิทยาศาสตร์แห่งชาติ
- Footer: ข้อความ “© 2025 สัปดาห์วันวิทยาศาสตร์แห่งชาติ โรงเรียนเนินสง่าวิทยา | khomkrit paisri” อยู่ตรงกลาง
- ในการทำ crud ขอให้เก็บข้อมูลจริง และให้เก็บในรูปแบบ json data ที่เป็นมาตรฐาน และให้เก็บโดยใช้ localstorage, ให้ใช้ jquery,jquery validate, sweet alert, loading ขนาดเล็ก ให้ด้วยตอนสถานะรอการทำงาน
ขอแค่ prompt นะ และขอเป็นภาษาไทยด้วย
alidate, sweet alert, loading ขนาดเล็กให้ด้วยตอนสถานะรอการทำงาน
- ขอแค่ prompt นะ และขอเป็นภาษาไทยด้วย ยาวไม่เกิน 4000 อักขระ
ปรับไปใช้ Firebase Realtime Database
สามารถ sync ข้อมูลแบบ realtime กับ firebase
แล้วให้ทำการเชื่อมต่อกับ Firebase Database ด้วย config ดังต่อไปนี้
const firebaseConfig = {
apiKey: "AIzaSyAT4FCM6dS8kpwUVZLOQTt4ffcHPI35p6c",
authDomain: "science-webapp.firebaseapp.com",
projectId: "science-webapp",
storageBucket: "science-webapp.firebasestorage.app",
messagingSenderId: "1055620244411",
appId: "1:1055620244411:web:5737a762982f7fc2a19a9e",
measurementId: "G-KCGDLSMS6Q"
};
ให้ใช้ Firebase JavaScript SDK v11+ with import via CDN (no npm)
ให้ code HTML มีการ setup Firebase และ Javascript ใน file เดียว