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,559 @@
<?php
// เชื่อมต่อฐานข้อมูล
require_once 'config.php';
// ดึงการตั้งค่าระบบ (เพื่อเช็คโหมด Grayscale และชื่อโรงพยาบาล)
$stmtSet = $pdo->query("SELECT setting_key, setting_value FROM settings");
$settings = [];
while ($row = $stmtSet->fetch()) {
$settings[$row['setting_key']] = $row['setting_value'];
}
$hospitalName = $settings['hospital_name'] ?? 'โรงพยาบาลเกาะสมุย';
$systemVersion = $settings['system_version'] ?? '2569.2.5';
$enableGrayscale = $settings['enable_grayscale'] ?? '0';
$logoUrl = "assets/img/logo_MOPH.png";
// รับค่าหมวดหมู่จาก URL (เช่น ?slug=pr_news)
$slug = $_GET['slug'] ?? 'pr_news';
// ชื่อหมวดหมู่
$categoryNames = [
'pr_news' => 'ข่าวประชาสัมพันธ์',
'jobs' => 'ประกาศรับสมัครงาน',
'procurement_supplies' => 'ประกาศจัดซื้อจัดจ้าง (พัสดุ-ครุภัณฑ์)',
'procurement_meds' => 'ประกาศจัดซื้อจัดจ้าง (ยา-เวชภัณฑ์)',
'plan' => 'แผนปฏิบัติการ',
'finance' => 'รายงานงบทดลอง',
'academic' => 'งานวิชาการ/วิจัย',
'laws' => 'กฎหมายน่ารู้',
'gallery' => 'แกลเลอรี่ภาพกิจกรรม',
'download' => 'ดาวน์โหลดเอกสาร',
'infographic' => 'อินโฟกราฟิกความรู้สุขภาพ'
];
$pageTitle = $categoryNames[$slug] ?? 'ข้อมูลหมวดหมู่';
// ==========================================
// ระบบแบ่งหน้า (Pagination)
// ==========================================
$page = max(1, isset($_GET['page']) ? (int)$_GET['page'] : 1);
$limit = 12; // จำนวนที่แสดงต่อหน้า
$offset = ($page - 1) * $limit;
$items = [];
$totalItems = 0;
$totalPages = 0;
if (isset($pdo)) {
// นับจำนวนทั้งหมด
$stmtCount = $pdo->prepare("SELECT COUNT(*) FROM contents WHERE category_slug = ? AND status = 'published'");
$stmtCount->execute([$slug]);
$totalItems = $stmtCount->fetchColumn();
$totalPages = ceil($totalItems / $limit);
// ดึงข้อมูล
$stmt = $pdo->prepare("SELECT * FROM contents WHERE category_slug = ? AND status = 'published' ORDER BY created_at DESC LIMIT ? OFFSET ?");
$stmt->bindValue(1, $slug, PDO::PARAM_STR);
$stmt->bindValue(2, $limit, PDO::PARAM_INT);
$stmt->bindValue(3, $offset, PDO::PARAM_INT);
$stmt->execute();
$items = $stmt->fetchAll();
}
// ฟังก์ชันแปลงวันที่เป็นภาษาไทย
function formatThaiDate($timestamp)
{
if (!$timestamp) return '-';
$months = ['', 'ม.ค.', 'ก.พ.', 'มี.ค.', 'เม.ย.', 'พ.ค.', 'มิ.ย.', 'ก.ค.', 'ส.ค.', 'ก.ย.', 'ต.ค.', 'พ.ย.', 'ธ.ค.'];
$time = strtotime($timestamp);
return sprintf("%02d %s %d", date('d', $time), $months[date('n', $time)], date('Y', $time) + 543);
}
// เช็คว่าหมวดหมู่นี้ใช้ Layout แบบภาพ Grid หรือ แบบ List รายการ
$isGridLayout = in_array($slug, ['pr_news', 'gallery', 'infographic']);
?>
<!DOCTYPE html>
<html lang="th">
<head>
<meta name="referrer" content="no-referrer" />
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#056839">
<link rel="manifest" href="manifest.json">
<title><?= htmlspecialchars($pageTitle) ?> - <?= htmlspecialchars($hospitalName) ?></title>
<link rel="icon" href="<?= $logoUrl ?>">
<link href="https://fonts.googleapis.com/css2?family=Sarabun:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
darkMode: 'class',
}
</script>
<script src="https://unpkg.com/lucide@latest"></script>
<style>
body,
.font-sans,
* {
font-family: 'Sarabun', sans-serif !important;
}
.custom-scrollbar::-webkit-scrollbar {
height: 6px;
width: 6px;
}
.custom-scrollbar::-webkit-scrollbar-track {
background: transparent;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background: #a7f3d0;
border-radius: 10px;
}
@keyframes fade-in {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.animate-fade-in {
animation: fade-in 0.5s ease-out forwards;
}
.glass-card {
background: rgba(255, 255, 255, 0.7);
backdrop-filter: blur(16px);
border: 1px solid rgba(255, 255, 255, 0.6);
}
.dark .glass-card {
background: rgba(15, 23, 42, 0.75);
backdrop-filter: blur(16px);
border: 1px solid rgba(255, 255, 255, 0.1);
}
.glass-nav {
background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(20px);
border-bottom: 1px solid rgba(255, 255, 255, 0.5);
}
.dark .glass-nav {
background: rgba(15, 23, 42, 0.85);
backdrop-filter: blur(20px);
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
</style>
</head>
<!-- โทนสี Pastel Green Gradient + เช็คโหมดขาวดำ -->
<script>
if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
</script>
<body class="bg-gradient-to-br from-[#e8fbf0] via-[#f2fdf7] to-[#dcfce7] dark:from-slate-950 dark:via-slate-900 dark:to-slate-950 text-slate-900 dark:text-slate-100 selection:bg-emerald-300 dark:selection:bg-emerald-700 min-h-screen flex flex-col <?= $enableGrayscale == '1' ? 'grayscale' : '' ?>">
<!-- NAVBAR แบบย่อ -->
<nav class="fixed w-full z-40 glass-nav shadow-[0_2px_20px_-5px_rgba(0,0,0,0.05)] dark:shadow-[0_2px_20px_-5px_rgba(0,0,0,0.5)] transition-all duration-300">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center h-20">
<div class="flex items-center space-x-3 cursor-pointer group" onclick="window.location.href='index.php'">
<div class="w-10 h-10 md:w-12 md:h-12 bg-white rounded-full flex items-center justify-center p-1 shadow-sm group-hover:scale-105 transition-transform">
<img src="<?= $logoUrl ?>" alt="Logo" class="w-full h-full object-contain" />
</div>
<div>
<h1 class="text-lg md:text-xl font-extrabold text-[#056839] dark:text-emerald-400 truncate"><?= htmlspecialchars($hospitalName) ?></h1>
<p class="text-xs md:text-sm text-emerald-600 dark:text-emerald-500 font-medium">Koh Samui Hospital</p>
</div>
</div>
<div class="flex items-center space-x-2 md:space-x-4">
<button id="theme-toggle" class="p-2 text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none rounded-lg text-sm transition-colors">
<i id="theme-toggle-dark-icon" data-lucide="moon" class="w-5 h-5 hidden"></i>
<i id="theme-toggle-light-icon" data-lucide="sun" class="w-5 h-5 hidden"></i>
</button>
<a href="index.php" class="flex items-center bg-white/80 dark:bg-slate-800/80 border border-emerald-100 dark:border-slate-700 hover:bg-emerald-50 dark:hover:bg-slate-700 px-5 py-2.5 rounded-full text-[#056839] dark:text-emerald-400 font-bold transition-all shadow-sm hover:shadow-md hover:-translate-y-0.5">
<i data-lucide="arrow-left" class="w-4 h-4 mr-2"></i> กลับหน้าหลัก
</a>
</div>
</div>
</div>
</nav>
<!-- ส่วนหัวของหน้า (Page Header) -->
<div class="pt-32 pb-16 bg-[#02311b] relative overflow-hidden shrink-0 shadow-inner">
<div class="absolute top-0 right-0 w-96 h-96 bg-emerald-500 opacity-20 rounded-full blur-[100px] transform translate-x-1/2 -translate-y-1/2 pointer-events-none"></div>
<div class="absolute bottom-0 left-0 w-64 h-64 bg-teal-400 opacity-10 rounded-full blur-[80px] transform -translate-x-1/2 translate-y-1/2 pointer-events-none"></div>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10 text-center">
<div class="inline-flex items-center space-x-2 text-emerald-300 text-sm mb-4 font-medium bg-white/10 px-4 py-1.5 rounded-full backdrop-blur-sm border border-white/10">
<a href="index.php" class="hover:text-white transition-colors">หน้าแรก</a>
<i data-lucide="chevron-right" class="w-3 h-3"></i>
<span class="text-white"><?= htmlspecialchars($pageTitle) ?></span>
</div>
<h2 class="text-3xl md:text-4xl lg:text-5xl font-extrabold text-white tracking-tight leading-tight">
<?= htmlspecialchars($pageTitle) ?>
</h2>
<p class="text-emerald-100/70 mt-4 text-sm md:text-base">ข้อมูลอัปเดตล่าสุดจาก <?= htmlspecialchars($hospitalName) ?></p>
</div>
</div>
<!-- ส่วนเนื้อหาหลัก (Main Content) -->
<main class="flex-1 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12 w-full animate-fade-in relative z-10 -mt-8">
<?php if (empty($items)): ?>
<!-- สถานะไม่มีข้อมูล -->
<div class="text-center py-24 glass-card rounded-[2.5rem] shadow-xl">
<div class="w-24 h-24 bg-white rounded-full flex items-center justify-center mx-auto mb-6 shadow-sm border border-gray-100">
<i data-lucide="folder-search" class="w-12 h-12 text-emerald-300"></i>
</div>
<h3 class="text-2xl font-extrabold text-gray-800">ไม่พบข้อมูล</h3>
<p class="text-gray-500 mt-2 font-medium">ยังไม่มีข้อมูลในหมวดหมู่นี้ หรือข้อมูลอาจถูกลบไปแล้ว</p>
<a href="index.php" class="inline-flex items-center mt-8 px-8 py-3 bg-[#056839] text-white font-bold rounded-2xl hover:bg-[#04522b] transition-all shadow-lg hover:-translate-y-1">
กลับสู่หน้าหลัก
</a>
</div>
<?php else: ?>
<?php if ($isGridLayout): ?>
<!-- ==========================================
แสดงผลแบบ Grid (สำหรับ ข่าว, แกลเลอรี่, อินโฟกราฟิก)
========================================== -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6 md:gap-8">
<?php foreach ($items as $item):
$details = isset($item['details']) ? json_decode($item['details'], true) : [];
$images = $details['images'] ?? [];
$cover = $item['drive_file_url'] ?? '';
$date = formatThaiDate($item['created_at']);
if ($slug === 'gallery' || $slug === 'infographic') {
$modalImages = ($slug === 'gallery' && !empty($images)) ? $images : [$cover];
$albumData = ['title' => $item['title'], 'date' => $date, 'images' => $modalImages];
$jsonAlbum = htmlspecialchars(json_encode($albumData), ENT_QUOTES, 'UTF-8');
$onClick = "openGalleryModal($jsonAlbum)";
} else {
$onClick = "void(0)";
}
?>
<div onclick='<?= $onClick ?>' class="glass-card rounded-[2rem] shadow-lg hover:shadow-2xl shadow-emerald-900/5 transition-all duration-300 overflow-hidden group cursor-pointer flex flex-col h-full hover:-translate-y-2 border-2 border-white">
<div class="relative overflow-hidden <?= $slug === 'infographic' ? 'aspect-[3/4]' : 'aspect-[4/3]' ?> bg-slate-100 shrink-0">
<!-- เพิ่ม onerror กรณีไฟล์เป็น PDF จะได้แสดงรูป Placeholder แทน -->
<img src="<?= htmlspecialchars($cover) ?>" onerror="this.src='https://placehold.co/600x400/e2e8f0/475569?text=Document+File'" class="w-full h-full object-cover transform group-hover:scale-110 transition-transform duration-700" alt="Cover" loading="lazy" />
<div class="absolute top-4 right-4 bg-white/90 backdrop-blur-md px-3.5 py-1.5 rounded-full text-xs font-extrabold text-[#056839] shadow-sm flex items-center border border-white">
<i data-lucide="calendar" class="w-3.5 h-3.5 mr-1.5"></i> <?= $date ?>
</div>
<?php if ($slug === 'gallery' || $slug === 'infographic'): ?>
<div class="absolute inset-0 bg-[#056839]/60 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center backdrop-blur-sm">
<span class="bg-white text-[#056839] px-5 py-2.5 rounded-xl font-extrabold text-sm shadow-xl flex items-center">
<i data-lucide="<?= $slug === 'gallery' ? 'images' : 'eye' ?>" class="w-4 h-4 mr-2"></i>
<?= $slug === 'gallery' ? 'ดูภาพทั้งหมด' : 'ขยายรูปภาพ' ?>
</span>
</div>
<?php endif; ?>
</div>
<div class="p-6 flex-1 flex flex-col justify-between bg-white/40">
<div>
<h4 class="text-base md:text-lg font-bold text-gray-800 group-hover:text-[#056839] transition-colors leading-snug line-clamp-3">
<?= htmlspecialchars($item['title']) ?>
</h4>
<?php if ($slug === 'gallery' && count($images) > 0): ?>
<p class="text-emerald-600 text-xs font-bold mt-4 flex items-center bg-white w-fit px-3 py-1 rounded-lg border border-emerald-100 shadow-sm">
<i data-lucide="image" class="w-3 h-3 mr-1.5"></i> <?= count($images) ?> รูปภาพ
</p>
<?php endif; ?>
</div>
<!-- เพิ่มปุ่มดาวน์โหลดสำหรับรูปแบบ Grid -->
<?php if ($item['drive_file_url']): ?>
<div class="mt-5 pt-4 border-t border-white/50 flex justify-end">
<a href="<?= htmlspecialchars($item['drive_file_url']) ?>" target="_blank" onclick="event.stopPropagation();" class="inline-flex items-center justify-center px-4 py-2 bg-white border border-emerald-200 rounded-xl text-[#056839] font-bold text-xs hover:bg-[#056839] hover:text-white hover:border-emerald-600 transition-colors shadow-sm">
<i data-lucide="download" class="w-3.5 h-3.5 mr-1.5"></i> ดาวน์โหลดไฟล์
</a>
</div>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
</div>
<?php else: ?>
<!-- ==========================================
แสดงผลแบบ List (สำหรับ ประกาศ, เอกสาร, กฎหมาย ฯลฯ)
========================================== -->
<div class="space-y-4 md:space-y-5">
<?php foreach ($items as $item):
$details = isset($item['details']) ? json_decode($item['details'], true) : [];
$date = formatThaiDate($item['created_at']);
// จัดการ Icon และสี ตามหมวดหมู่
$icon = 'file-text';
$iconColor = 'text-blue-600';
$iconBg = 'bg-blue-100';
if ($slug === 'jobs') {
$icon = 'briefcase';
$iconColor = 'text-amber-600';
$iconBg = 'bg-amber-100';
}
if (strpos($slug, 'procurement') !== false) {
$icon = 'shopping-cart';
$iconColor = 'text-teal-600';
$iconBg = 'bg-teal-100';
}
if ($slug === 'plan') {
$icon = 'bar-chart';
$iconColor = 'text-blue-600';
$iconBg = 'bg-blue-100';
}
if ($slug === 'finance') {
$icon = 'pie-chart';
$iconColor = 'text-indigo-600';
$iconBg = 'bg-indigo-100';
}
if ($slug === 'academic') {
$icon = 'book-open';
$iconColor = 'text-purple-600';
$iconBg = 'bg-purple-100';
}
if ($slug === 'laws') {
$icon = 'scale';
$iconColor = 'text-rose-600';
$iconBg = 'bg-rose-100';
}
if ($slug === 'download') {
$icon = 'download';
$iconColor = 'text-[#056839]';
$iconBg = 'bg-emerald-100';
}
?>
<div class="glass-card rounded-[2rem] p-5 md:p-6 hover:bg-white/90 hover:shadow-xl transition-all duration-300 border-2 border-white hover:border-emerald-100 group flex flex-col sm:flex-row sm:items-center gap-4 md:gap-6 transform hover:-translate-y-1">
<div class="w-14 h-14 md:w-16 md:h-16 <?= $iconBg ?> <?= $iconColor ?> rounded-2xl flex items-center justify-center shrink-0 group-hover:scale-110 transition-transform shadow-inner">
<i data-lucide="<?= $icon ?>" class="w-6 h-6 md:w-7 md:h-7"></i>
</div>
<div class="flex-1 min-w-0">
<h4 class="font-extrabold text-gray-800 group-hover:text-[#056839] transition-colors text-base md:text-xl mb-2 leading-snug">
<?= htmlspecialchars($item['title']) ?>
</h4>
<div class="flex flex-wrap items-center gap-2 md:gap-3 text-xs md:text-sm text-gray-500 font-medium">
<span class="flex items-center bg-white px-3 py-1 rounded-lg border border-gray-100 shadow-sm"><i data-lucide="calendar" class="w-3.5 h-3.5 mr-1.5"></i> <?= $date ?></span>
<!-- แสดงข้อมูลพิเศษเพิ่มเติมตามหมวดหมู่ -->
<?php if (isset($details['amount'])): ?>
<span class="px-3 py-1 rounded-lg bg-amber-50 text-amber-700 font-bold border border-amber-100 shadow-sm"><?= htmlspecialchars($details['amount']) ?></span>
<?php endif; ?>
<?php if (isset($details['status'])): ?>
<span class="px-3 py-1 rounded-lg <?= $details['status'] === 'สิ้นสุด' ? 'bg-slate-100 text-slate-600 border-slate-200' : 'bg-teal-50 text-teal-700 border-teal-100' ?> font-bold border shadow-sm">สถานะ: <?= htmlspecialchars($details['status']) ?></span>
<?php endif; ?>
<?php if (isset($details['author'])): ?>
<span class="px-3 py-1 rounded-lg bg-purple-50 text-purple-700 font-bold border border-purple-100 shadow-sm">โดย <?= htmlspecialchars($details['author']) ?></span>
<?php endif; ?>
<?php if (isset($details['size'])): ?>
<span class="px-3 py-1 rounded-lg bg-emerald-50 text-[#056839] font-bold border border-emerald-100 shadow-sm">ขนาด: <?= htmlspecialchars($details['size']) ?></span>
<?php endif; ?>
</div>
</div>
<div class="self-start sm:self-center shrink-0 w-full sm:w-auto mt-2 sm:mt-0">
<?php if ($item['drive_file_url']): ?>
<a href="<?= htmlspecialchars($item['drive_file_url']) ?>" target="_blank" class="flex w-full sm:w-auto items-center justify-center px-6 py-3 bg-white border border-emerald-200 rounded-xl text-[#056839] font-extrabold text-sm hover:bg-[#056839] hover:text-white hover:border-[#056839] transition-colors shadow-sm group-hover:shadow-md">
<i data-lucide="download" class="w-4 h-4 mr-2"></i> ดาวน์โหลด
</a>
<?php else: ?>
<!-- กรณีไม่มีไฟล์แนบ (ถ้าหมวดหมู่นี้ควรอ่านต่อได้) -->
<?php if (!in_array($slug, ['download', 'finance', 'plan'])): ?>
<button class="flex w-full sm:w-auto items-center justify-center px-6 py-3 bg-white border border-gray-200 rounded-xl text-gray-600 font-bold text-sm hover:bg-gray-50 transition-colors shadow-sm">
อ่านเพิ่มเติม
</button>
<?php endif; ?>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<!-- ==========================================
ส่วนแบ่งหน้า (Pagination)
========================================== -->
<?php if ($totalPages > 1): ?>
<div class="mt-12 flex justify-center">
<div class="glass-card flex items-center space-x-1 p-2 rounded-2xl shadow-lg border-white">
<!-- ปุ่มย้อนกลับ -->
<?php if ($page > 1): ?>
<a href="?slug=<?= $slug ?>&page=<?= $page - 1 ?>" class="flex items-center justify-center w-10 h-10 md:w-12 md:h-12 bg-white rounded-xl text-gray-600 hover:bg-emerald-50 hover:text-[#056839] transition-all shadow-sm font-bold">
<i data-lucide="chevron-left" class="w-5 h-5"></i>
</a>
<?php endif; ?>
<!-- เลขหน้า -->
<?php
$startPage = max(1, $page - 2);
$endPage = min($totalPages, $page + 2);
for ($i = $startPage; $i <= $endPage; $i++):
?>
<a href="?slug=<?= $slug ?>&page=<?= $i ?>" class="flex items-center justify-center w-10 h-10 md:w-12 md:h-12 rounded-xl text-sm font-extrabold transition-all <?= $i == $page ? 'bg-[#056839] text-white shadow-md scale-105' : 'bg-white text-gray-600 hover:bg-emerald-50 hover:text-[#056839] shadow-sm' ?>">
<?= $i ?>
</a>
<?php endfor; ?>
<!-- ปุ่มถัดไป -->
<?php if ($page < $totalPages): ?>
<a href="?slug=<?= $slug ?>&page=<?= $page + 1 ?>" class="flex items-center justify-center w-10 h-10 md:w-12 md:h-12 bg-white rounded-xl text-gray-600 hover:bg-emerald-50 hover:text-[#056839] transition-all shadow-sm font-bold">
<i data-lucide="chevron-right" class="w-5 h-5"></i>
</a>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<?php endif; ?>
</main>
<!-- ==========================================
FOOTER
========================================== -->
<footer class="bg-[#012012] text-emerald-100/70 pt-12 pb-6 border-t-[6px] border-[#056839] mt-20 shrink-0">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex flex-col md:flex-row justify-between items-center text-xs md:text-sm gap-4 font-medium text-emerald-100/50">
<p class="text-center md:text-left">
&copy; <?= date('Y') + 543 ?> หน่วยงานสุขภาพดิจิทัล โรงพยาบาลเกาะสมุย. สงวนลิขสิทธิ์.
</p>
<div class="flex items-center bg-black/20 px-4 py-1.5 rounded-full border border-emerald-900/50">
Version <?= htmlspecialchars($systemVersion) ?>
</div>
</div>
</div>
</footer>
<!-- ==========================================
MODALS
========================================== -->
<!-- Gallery Modal (ใช้ตัวเดียวกันกับหน้าแรก) -->
<div id="gallery-modal" class="hidden fixed inset-0 z-[60] items-center justify-center bg-slate-900/95 backdrop-blur-sm p-4 animate-fade-in overflow-y-auto">
<div class="bg-transparent w-full max-w-6xl overflow-hidden relative my-4 md:my-8 flex flex-col mx-auto h-[90vh]">
<div class="flex justify-between items-center mb-4 shrink-0 px-2">
<div class="text-white">
<h2 id="gallery-modal-title" class="text-xl md:text-3xl font-extrabold drop-shadow-md">Title</h2>
<p id="gallery-modal-meta" class="text-emerald-300 text-sm md:text-base mt-2 flex items-center font-bold drop-shadow-md"><i data-lucide="calendar" class="w-4 h-4 mr-2"></i> Date</p>
</div>
<button onclick="closeModal('gallery-modal')" class="p-3 bg-white/10 hover:bg-white/30 backdrop-blur-md rounded-full transition-colors shrink-0 text-white border border-white/20">
<i data-lucide="x" class="w-6 h-6"></i>
</button>
</div>
<div class="overflow-y-auto custom-scrollbar flex-1 bg-black/40 rounded-3xl p-6 border border-white/10 backdrop-blur-md">
<div id="gallery-modal-grid" class="grid gap-6 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3">
<!-- Images injected here -->
</div>
</div>
</div>
</div>
<!-- JAVASCRIPT -->
<script>
lucide.createIcons();
function openModal(id) {
const modal = document.getElementById(id);
modal.classList.remove('hidden');
modal.classList.add('flex');
document.body.style.overflow = 'hidden';
}
function closeModal(id) {
const modal = document.getElementById(id);
modal.classList.add('hidden');
modal.classList.remove('flex');
document.body.style.overflow = 'auto';
}
function openGalleryModal(album) {
document.getElementById('gallery-modal-title').innerText = album.title;
const metaText = album.images && album.images.length > 1 ?
`${album.date} • ${album.images.length} รูปภาพ` :
album.date;
document.getElementById('gallery-modal-meta').innerHTML = `<i data-lucide="calendar" class="w-4 h-4 mr-2"></i> ${metaText}`;
const grid = document.getElementById('gallery-modal-grid');
grid.innerHTML = '';
if (album.images && album.images.length === 1) {
grid.className = "grid gap-6 grid-cols-1 max-w-3xl mx-auto";
} else {
grid.className = "grid gap-6 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3";
}
album.images.forEach((img) => {
grid.innerHTML += `
<div class="relative rounded-2xl overflow-hidden group shadow-lg ${album.images.length === 1 ? 'aspect-auto' : 'aspect-square md:h-80'} bg-black/50 border border-white/10">
<img src="${img}" class="w-full h-full ${album.images.length === 1 ? 'object-contain' : 'object-cover'} transform group-hover:scale-105 transition-transform duration-500" loading="lazy" />
</div>`;
});
lucide.createIcons();
openModal('gallery-modal');
}
// Theme Toggle
const themeToggleBtn = document.getElementById('theme-toggle');
const darkIcon = document.getElementById('theme-toggle-dark-icon');
const lightIcon = document.getElementById('theme-toggle-light-icon');
if (themeToggleBtn && darkIcon && lightIcon) {
if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
lightIcon.classList.remove('hidden');
} else {
darkIcon.classList.remove('hidden');
}
themeToggleBtn.addEventListener('click', function() {
darkIcon.classList.toggle('hidden');
lightIcon.classList.toggle('hidden');
if (localStorage.getItem('color-theme')) {
if (localStorage.getItem('color-theme') === 'light') {
document.documentElement.classList.add('dark');
localStorage.setItem('color-theme', 'dark');
} else {
document.documentElement.classList.remove('dark');
localStorage.setItem('color-theme', 'light');
}
} else {
if (document.documentElement.classList.contains('dark')) {
document.documentElement.classList.remove('dark');
localStorage.setItem('color-theme', 'light');
} else {
document.documentElement.classList.add('dark');
localStorage.setItem('color-theme', 'dark');
}
}
});
}
// PWA Service Worker Registration
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('./sw.js').catch(() => {});
});
}
</script>
</body>
</html>