{"id":239,"date":"2026-08-26T15:37:56","date_gmt":"2026-08-26T08:37:56","guid":{"rendered":"https:\/\/rkk.ac.th\/?page_id=239"},"modified":"2026-08-26T16:56:50","modified_gmt":"2026-08-26T09:56:50","slug":"%e0%b8%aa%e0%b8%b7%e0%b9%88%e0%b8%ad%e0%b8%81%e0%b8%b2%e0%b8%a3%e0%b8%aa%e0%b8%ad%e0%b8%99","status":"publish","type":"page","link":"https:\/\/rkk.ac.th\/?page_id=239","title":{"rendered":"\u0e2a\u0e37\u0e48\u0e2d\u0e01\u0e32\u0e23\u0e2a\u0e2d\u0e19"},"content":{"rendered":"\n<div class=\"wp-block-cover alignfull is-light\" style=\"padding-top:0vw;padding-right:4vw;padding-bottom:0vw;padding-left:4vw;min-height:66vh;aspect-ratio:unset;\"><span aria-hidden=\"true\" class=\"wp-block-cover__background has-base-background-color has-background-dim-100 has-background-dim\"><\/span><div class=\"wp-block-cover__inner-container is-layout-flow wp-block-cover-is-layout-flow\">\n<!DOCTYPE html>\n<html lang=\"th\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>\u0e04\u0e25\u0e31\u0e07\u0e2a\u0e37\u0e48\u0e2d\u0e01\u0e32\u0e23\u0e40\u0e23\u0e35\u0e22\u0e19\u0e23\u0e39\u0e49\u0e04\u0e23\u0e39 &#8211; Teacher Media Hub<\/title>\n    <!-- Tailwind CSS CDN -->\n    <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n    <!-- Google Fonts (Kanit) -->\n    <link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n    <link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Kanit:ital,wght@0,200;0,300;0,400;0,500;0,600;0,700;1,300&#038;display=swap\" rel=\"stylesheet\">\n    <!-- Font Awesome Icons -->\n    <link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/font-awesome\/6.4.0\/css\/all.min.css\">\n    \n    <script>\n        tailwind.config = {\n            theme: {\n                extend: {\n                    fontFamily: {\n                        sans: ['Kanit', 'sans-serif'],\n                    },\n                    colors: {\n                        brand: {\n                            50: '#f0f9ff',\n                            100: '#e0f2fe',\n                            500: '#0284c7',\n                            600: '#0369a1',\n                            700: '#075985',\n                        }\n                    }\n                }\n            }\n        }\n    <\/script>\n    <style>\n        body { font-family: 'Kanit', sans-serif; }\n        .glass-card {\n            background: rgba(255, 255, 255, 0.9);\n            backdrop-filter: blur(8px);\n        }\n        \/* Custom Scrollbar *\/\n        ::-webkit-scrollbar {\n            width: 6px;\n            height: 6px;\n        }\n        ::-webkit-scrollbar-track {\n            background: #f1f1f1;\n        }\n        ::-webkit-scrollbar-thumb {\n            background: #cbd5e1;\n            border-radius: 4px;\n        }\n        ::-webkit-scrollbar-thumb:hover {\n            background: #94a3b8;\n        }\n    <\/style>\n<\/head>\n<body class=\"bg-slate-50 min-h-screen flex flex-col text-slate-800\">\n\n    <main class=\"flex-grow max-w-7xl w-full mx-auto px-4 sm:px-6 lg:px-8 py-6\">\n\n        <!-- Banner \/ Quick Stats -->\n        <div class=\"bg-gradient-to-r from-sky-700 via-indigo-700 to-purple-800 rounded-2xl p-6 md:p-8 text-white mb-8 shadow-lg relative overflow-hidden\">\n            <div class=\"absolute -right-10 -bottom-10 opacity-10 text-white\">\n                <i class=\"fa-solid fa-folder-tree text-[220px]\"><\/i>\n            <\/div>\n            <div class=\"relative z-10 max-w-3xl\">\n                <span class=\"bg-white\/20 text-white text-xs font-semibold px-3 py-1 rounded-full uppercase tracking-wider backdrop-blur-md\">\n                    Media Repository\n                <\/span>\n                <h2 class=\"text-2xl md:text-3xl font-bold mt-2 mb-2\">\u0e28\u0e39\u0e19\u0e22\u0e4c\u0e23\u0e27\u0e21\u0e2a\u0e37\u0e48\u0e2d\u0e41\u0e25\u0e30\u0e19\u0e27\u0e31\u0e15\u0e01\u0e23\u0e23\u0e21\u0e01\u0e32\u0e23\u0e40\u0e23\u0e35\u0e22\u0e19\u0e23\u0e39\u0e49<\/h2>\n                <p class=\"text-sky-100 text-sm md:text-base leading-relaxed\">\n                    \u0e04\u0e25\u0e31\u0e07\u0e2a\u0e37\u0e48\u0e2d\u0e01\u0e32\u0e23\u0e2a\u0e2d\u0e19 \u0e04\u0e38\u0e13\u0e04\u0e23\u0e39\u0e42\u0e23\u0e07\u0e40\u0e23\u0e35\u0e22\u0e19\u0e23\u0e48\u0e21\u0e40\u0e01\u0e25\u0e49\u0e32 \u0e01\u0e32\u0e0d\u0e08\u0e19\u0e1a\u0e38\u0e23\u0e35 (\u0e43\u0e19\u0e42\u0e04\u0e23\u0e07\u0e01\u0e32\u0e23\u0e1e\u0e23\u0e30\u0e23\u0e32\u0e0a\u0e14\u0e33\u0e23\u0e34)\n                <\/p>\n\n                <!-- Stats Badges -->\n                <div class=\"grid grid-cols-2 sm:grid-cols-4 gap-3 mt-6 pt-4 border-t border-white\/20\">\n                    <div class=\"bg-white\/10 backdrop-blur-md rounded-xl p-3 border border-white\/10\">\n                        <div class=\"text-xs text-sky-200\">\u0e2a\u0e37\u0e48\u0e2d\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14<\/div>\n                        <div class=\"text-xl md:text-2xl font-bold mt-0.5\" id=\"statTotalMedia\">0<\/div>\n                    <\/div>\n                    <div class=\"bg-white\/10 backdrop-blur-md rounded-xl p-3 border border-white\/10\">\n                        <div class=\"text-xs text-sky-200\">\u0e01\u0e25\u0e38\u0e48\u0e21\u0e2a\u0e32\u0e23\u0e30\u0e2f<\/div>\n                        <div class=\"text-xl md:text-2xl font-bold mt-0.5\" id=\"statSubjects\">0<\/div>\n                    <\/div>\n                    <div class=\"bg-white\/10 backdrop-blur-md rounded-xl p-3 border border-white\/10\">\n                        <div class=\"text-xs text-sky-200\">\u0e23\u0e30\u0e14\u0e31\u0e1a\u0e0a\u0e31\u0e49\u0e19<\/div>\n                        <div class=\"text-xl md:text-2xl font-bold mt-0.5\" id=\"statGrades\">0<\/div>\n                    <\/div>\n                    <div class=\"bg-white\/10 backdrop-blur-md rounded-xl p-3 border border-white\/10\">\n                        <div class=\"text-xs text-sky-200\">\u0e04\u0e38\u0e13\u0e04\u0e23\u0e39\u0e1c\u0e39\u0e49\u0e2a\u0e23\u0e49\u0e32\u0e07\u0e2a\u0e37\u0e48\u0e2d<\/div>\n                        <div class=\"text-xl md:text-2xl font-bold mt-0.5\" id=\"statTeachers\">0<\/div>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <!-- Filter Box Component -->\n        <div class=\"bg-white rounded-2xl shadow-sm border border-slate-200 p-4 md:p-6 mb-8\">\n            <div class=\"flex items-center justify-between mb-4\">\n                <h3 class=\"font-semibold text-slate-800 flex items-center text-base\">\n                    <i class=\"fa-solid fa-filter text-sky-600 mr-2\"><\/i> \u0e15\u0e31\u0e27\u0e01\u0e23\u0e2d\u0e07\u0e04\u0e49\u0e19\u0e2b\u0e32\u0e2a\u0e37\u0e48\u0e2d\n                <\/h3>\n                <button onclick=\"resetFilters()\" class=\"text-xs text-slate-500 hover:text-sky-600 flex items-center transition\">\n                    <i class=\"fa-solid fa-rotate-right mr-1\"><\/i> \u0e25\u0e49\u0e32\u0e07\u0e15\u0e31\u0e27\u0e01\u0e23\u0e2d\u0e07\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\n                <\/button>\n            <\/div>\n\n            <div class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4\">\n                \n                <!-- Keyword Search -->\n                <div class=\"sm:col-span-2 lg:col-span-1\">\n                    <label class=\"block text-xs font-medium text-slate-600 mb-1.5\">\u0e04\u0e49\u0e19\u0e2b\u0e32\u0e14\u0e49\u0e27\u0e22\u0e0a\u0e37\u0e48\u0e2d\u0e2a\u0e37\u0e48\u0e2d<\/label>\n                    <div class=\"relative\">\n                        <input type=\"text\" id=\"searchInput\" oninput=\"applyFilters()\" placeholder=\"\u0e1e\u0e34\u0e21\u0e1e\u0e4c\u0e0a\u0e37\u0e48\u0e2d\u0e2a\u0e37\u0e48\u0e2d\u0e01\u0e32\u0e23\u0e2a\u0e2d\u0e19...\" \n                            class=\"w-full pl-9 pr-4 py-2 bg-slate-50 border border-slate-200 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-sky-500 focus:bg-white transition\">\n                        <i class=\"fa-solid fa-magnifying-glass absolute left-3 top-3 text-slate-400 text-sm\"><\/i>\n                    <\/div>\n                <\/div>\n\n                <!-- Grade Filter -->\n                <div>\n                    <label class=\"block text-xs font-medium text-slate-600 mb-1.5\">\u0e23\u0e30\u0e14\u0e31\u0e1a\u0e0a\u0e31\u0e49\u0e19<\/label>\n                    <div class=\"relative\">\n                        <select id=\"gradeSelect\" onchange=\"applyFilters()\" class=\"w-full pl-9 pr-8 py-2 bg-slate-50 border border-slate-200 rounded-xl text-sm appearance-none focus:outline-none focus:ring-2 focus:ring-sky-500 focus:bg-white transition\">\n                            <option value=\"\">\u0e17\u0e38\u0e01\u0e23\u0e30\u0e14\u0e31\u0e1a\u0e0a\u0e31\u0e49\u0e19<\/option>\n                        <\/select>\n                        <i class=\"fa-solid fa-graduation-cap absolute left-3 top-3 text-slate-400 text-sm\"><\/i>\n                        <i class=\"fa-solid fa-chevron-down absolute right-3 top-3.5 text-slate-400 text-xs pointer-events-none\"><\/i>\n                    <\/div>\n                <\/div>\n\n                <!-- Subject Group Filter -->\n                <div>\n                    <label class=\"block text-xs font-medium text-slate-600 mb-1.5\">\u0e01\u0e25\u0e38\u0e48\u0e21\u0e2a\u0e32\u0e23\u0e30\u0e01\u0e32\u0e23\u0e40\u0e23\u0e35\u0e22\u0e19\u0e23\u0e39\u0e49 (\u0e42\u0e1f\u0e25\u0e40\u0e14\u0e2d\u0e23\u0e4c)<\/label>\n                    <div class=\"relative\">\n                        <select id=\"subjectSelect\" onchange=\"applyFilters()\" class=\"w-full pl-9 pr-8 py-2 bg-slate-50 border border-slate-200 rounded-xl text-sm appearance-none focus:outline-none focus:ring-2 focus:ring-sky-500 focus:bg-white transition\">\n                            <option value=\"\">\u0e17\u0e38\u0e01\u0e01\u0e25\u0e38\u0e48\u0e21\u0e2a\u0e32\u0e23\u0e30\u0e2f<\/option>\n                        <\/select>\n                        <i class=\"fa-solid fa-layer-group absolute left-3 top-3 text-slate-400 text-sm\"><\/i>\n                        <i class=\"fa-solid fa-chevron-down absolute right-3 top-3.5 text-slate-400 text-xs pointer-events-none\"><\/i>\n                    <\/div>\n                <\/div>\n\n                <!-- Teacher Filter -->\n                <div>\n                    <label class=\"block text-xs font-medium text-slate-600 mb-1.5\">\u0e0a\u0e37\u0e48\u0e2d\u0e04\u0e23\u0e39\u0e1c\u0e39\u0e49\u0e2a\u0e2d\u0e19<\/label>\n                    <div class=\"relative\">\n                        <select id=\"teacherSelect\" onchange=\"applyFilters()\" class=\"w-full pl-9 pr-8 py-2 bg-slate-50 border border-slate-200 rounded-xl text-sm appearance-none focus:outline-none focus:ring-2 focus:ring-sky-500 focus:bg-white transition\">\n                            <option value=\"\">\u0e04\u0e23\u0e39\u0e1c\u0e39\u0e49\u0e2a\u0e2d\u0e19\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14<\/option>\n                        <\/select>\n                        <i class=\"fa-solid fa-user-tie absolute left-3 top-3 text-slate-400 text-sm\"><\/i>\n                        <i class=\"fa-solid fa-chevron-down absolute right-3 top-3.5 text-slate-400 text-xs pointer-events-none\"><\/i>\n                    <\/div>\n                <\/div>\n\n            <\/div>\n\n            <!-- Naming format hint -->\n            <div class=\"mt-4 pt-3 border-t border-slate-100 flex flex-wrap items-center justify-between text-xs text-slate-500 gap-2\">\n                <div class=\"flex items-center\">\n                    <i class=\"fa-solid fa-circle-info text-sky-500 mr-1.5\"><\/i>\n                    <span>\u0e23\u0e39\u0e1b\u0e41\u0e1a\u0e1a\u0e01\u0e32\u0e23\u0e15\u0e31\u0e49\u0e07\u0e0a\u0e37\u0e48\u0e2d\u0e44\u0e1f\u0e25\u0e4c\u0e17\u0e35\u0e48\u0e23\u0e2d\u0e07\u0e23\u0e31\u0e1a: <code class=\"bg-slate-100 text-sky-700 px-2 py-0.5 rounded font-mono font-semibold\">\u0e23\u0e30\u0e14\u0e31\u0e1a\u0e0a\u0e31\u0e49\u0e19-\u0e0a\u0e37\u0e48\u0e2d\u0e2a\u0e37\u0e48\u0e2d-\u0e0a\u0e37\u0e48\u0e2d\u0e04\u0e38\u0e13\u0e04\u0e23\u0e39.ext<\/code><\/span>\n                <\/div>\n                <div class=\"text-slate-400\">\n                    \u0e40\u0e0a\u0e48\u0e19 <span class=\"italic text-slate-600\">\u0e21.3-\u0e43\u0e1a\u0e07\u0e32\u0e19\u0e40\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e40\u0e0b\u0e25\u0e25\u0e4c-\u0e04\u0e23\u0e39\u0e2a\u0e21\u0e0a\u0e32\u0e22.pdf<\/span>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <!-- Content Results Area -->\n        <div class=\"flex items-center justify-between mb-4\">\n            <h3 class=\"font-bold text-slate-800 text-lg flex items-center\">\n                <span>\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e2a\u0e37\u0e48\u0e2d\u0e01\u0e32\u0e23\u0e40\u0e23\u0e35\u0e22\u0e19\u0e23\u0e39\u0e49<\/span>\n                <span id=\"resultCountBadge\" class=\"ml-2 bg-sky-100 text-sky-800 text-xs font-semibold px-2.5 py-0.5 rounded-full\">0 \u0e23\u0e32\u0e22\u0e01\u0e32\u0e23<\/span>\n            <\/h3>\n            \n            <!-- View Mode Switcher or Sort -->\n            <div class=\"text-xs text-slate-500\" id=\"dataSourceStatus\">\n                \u0e01\u0e33\u0e25\u0e31\u0e07\u0e41\u0e2a\u0e14\u0e07\u0e1c\u0e25: <span class=\"font-medium text-amber-600\">\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e15\u0e31\u0e27\u0e2d\u0e22\u0e48\u0e32\u0e07 (Demo Data)<\/span>\n            <\/div>\n        <\/div>\n\n        <!-- Loading Spinner State -->\n        <div id=\"loadingState\" class=\"hidden py-16 text-center\">\n            <div class=\"inline-block animate-spin rounded-full h-10 w-10 border-4 border-sky-600 border-t-transparent\"><\/div>\n            <p class=\"mt-3 text-slate-500 text-sm\">\u0e01\u0e33\u0e25\u0e31\u0e07\u0e42\u0e2b\u0e25\u0e14\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e2a\u0e37\u0e48\u0e2d\u0e08\u0e32\u0e01 Google Drive&#8230;<\/p>\n        <\/div>\n\n        <!-- Media Grid -->\n        <div id=\"mediaGrid\" class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-5\">\n            <!-- Dynamic Media Cards Rendered Here -->\n        <\/div>\n\n        <!-- Pagination -->\n        <div id=\"pagination\" class=\"hidden mt-8 flex flex-wrap items-center justify-center gap-2\"><\/div>\n\n        <!-- Empty State -->\n        <div id=\"emptyState\" class=\"hidden py-16 text-center bg-white rounded-2xl border border-dashed border-slate-300 my-4\">\n            <div class=\"w-16 h-16 bg-slate-100 text-slate-400 rounded-full flex items-center justify-center mx-auto mb-4 text-2xl\">\n                <i class=\"fa-solid fa-folder-open\"><\/i>\n            <\/div>\n            <h4 class=\"text-slate-700 font-medium text-base mb-1\">\u0e44\u0e21\u0e48\u0e1e\u0e1a\u0e2a\u0e37\u0e48\u0e2d\u0e01\u0e32\u0e23\u0e40\u0e23\u0e35\u0e22\u0e19\u0e23\u0e39\u0e49\u0e17\u0e35\u0e48\u0e15\u0e23\u0e07\u0e01\u0e31\u0e1a\u0e40\u0e07\u0e37\u0e48\u0e2d\u0e19\u0e44\u0e02<\/h4>\n            <p class=\"text-slate-400 text-sm max-w-sm mx-auto mb-4\">\u0e25\u0e2d\u0e07\u0e1b\u0e23\u0e31\u0e1a\u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19\u0e15\u0e31\u0e27\u0e01\u0e23\u0e2d\u0e07 \u0e04\u0e49\u0e19\u0e2b\u0e32\u0e14\u0e49\u0e27\u0e22\u0e04\u0e33\u0e2d\u0e37\u0e48\u0e19 \u0e2b\u0e23\u0e37\u0e2d\u0e25\u0e49\u0e32\u0e07\u0e15\u0e31\u0e27\u0e01\u0e23\u0e2d\u0e07\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14<\/p>\n            <button onclick=\"resetFilters()\" class=\"px-4 py-2 bg-sky-600 hover:bg-sky-700 text-white text-xs font-medium rounded-lg transition shadow-sm\">\n                \u0e25\u0e49\u0e32\u0e07\u0e15\u0e31\u0e27\u0e01\u0e23\u0e2d\u0e07\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\n            <\/button>\n        <\/div>\n\n    <\/main>\n\n    <!-- Preview Modal -->\n    <div id=\"previewModal\" class=\"fixed inset-0 bg-slate-900\/80 backdrop-blur-md flex items-center justify-center p-3 sm:p-6 hidden\" style=\"position:fixed;inset:0;z-index:2147483647;\">\n        <div class=\"bg-white rounded-2xl w-full max-w-5xl h-[90vh] flex flex-col overflow-hidden shadow-2xl relative\">\n            <!-- Modal Header -->\n            <div class=\"px-5 py-3.5 bg-slate-900 text-white flex items-center justify-between border-b border-slate-800\">\n                <div class=\"flex items-center space-x-3 overflow-hidden\">\n                    <span id=\"modalFileIcon\" class=\"text-sky-400 text-lg\"><\/span>\n                    <div class=\"truncate\">\n                        <h4 id=\"modalFileTitle\" class=\"font-semibold text-sm sm:text-base truncate\">\u0e0a\u0e37\u0e48\u0e2d\u0e44\u0e1f\u0e25\u0e4c\u0e2a\u0e37\u0e48\u0e2d<\/h4>\n                        <p id=\"modalFileMeta\" class=\"text-xs text-slate-400 truncate\">\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e23\u0e32\u0e22\u0e25\u0e30\u0e40\u0e2d\u0e35\u0e22\u0e14<\/p>\n                    <\/div>\n                <\/div>\n                <div class=\"flex items-center space-x-2\">\n                    <a id=\"modalDownloadBtn\" href=\"#\" target=\"_blank\" class=\"px-3 py-1.5 bg-sky-600 hover:bg-sky-500 text-white text-xs font-medium rounded-lg transition flex items-center\">\n                        <i class=\"fa-solid fa-external-link mr-1.5\"><\/i> \u0e40\u0e1b\u0e34\u0e14\u0e43\u0e19 Google Drive\n                    <\/a>\n                    <button onclick=\"closePreviewModal()\" class=\"text-slate-400 hover:text-white w-8 h-8 rounded-full flex items-center justify-center transition\">\n                        <i class=\"fa-solid fa-xmark text-lg\"><\/i>\n                    <\/button>\n                <\/div>\n            <\/div>\n\n            <!-- Modal Content Body -->\n            <div class=\"flex-grow bg-slate-100 relative\">\n                <iframe id=\"previewIframe\" class=\"w-full h-full border-0\" src=\"\" allow=\"autoplay\" sandbox=\"allow-scripts allow-forms allow-modals allow-popups allow-popups-to-escape-sandbox allow-downloads\"><\/iframe>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <script>\n        \/\/ Global State Variables\n        let allMediaItems = [];\n        let filteredMediaItems = [];\n        let currentMode = 'demo'; \/\/ 'demo' or 'drive'\n        let currentPage = 1;\n        let activePreviewUrl = '';\n        const ITEMS_PER_PAGE = 12;\n        \/\/ \u0e41\u0e2a\u0e14\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e08\u0e32\u0e01\u0e41\u0e04\u0e0a\u0e17\u0e31\u0e19\u0e17\u0e35 \u0e41\u0e25\u0e49\u0e27\u0e04\u0e48\u0e2d\u0e22\u0e2d\u0e31\u0e1b\u0e40\u0e14\u0e15\u0e08\u0e32\u0e01 Drive \u0e40\u0e1a\u0e37\u0e49\u0e2d\u0e07\u0e2b\u0e25\u0e31\u0e07\n        const GOOGLE_DRIVE_API_KEY = 'AIzaSyBpwXDI0Ru6B-RtOU3VGx7EPrD381dSqd4';\n        const DRIVE_FOLDER_ID = '1DjDBQdoG4VA6PHQkeWuziiB7hhqDCrvC';\n        const CACHE_KEY = `teacher_media_cache_v2_${DRIVE_FOLDER_ID}`;\n\n        \/\/ Comprehensive Mock Data matching user's specification: \u0e23\u0e30\u0e14\u0e31\u0e1a\u0e0a\u0e31\u0e49\u0e19-\u0e0a\u0e37\u0e48\u0e2d\u0e2a\u0e37\u0e48\u0e2d-\u0e0a\u0e37\u0e48\u0e2d\u0e04\u0e38\u0e13\u0e04\u0e23\u0e39\n        const MOCK_DATA = [\n            {\n                id: '1',\n                name: '\u0e21.3-\u0e43\u0e1a\u0e07\u0e32\u0e19\u0e40\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e01\u0e32\u0e23\u0e2a\u0e31\u0e07\u0e40\u0e04\u0e23\u0e32\u0e30\u0e2b\u0e4c\u0e14\u0e49\u0e27\u0e22\u0e41\u0e2a\u0e07-\u0e04\u0e23\u0e39\u0e2a\u0e21\u0e0a\u0e32\u0e22 \u0e43\u0e08\u0e14\u0e35.pdf',\n                subject: '\u0e27\u0e34\u0e17\u0e22\u0e32\u0e28\u0e32\u0e2a\u0e15\u0e23\u0e4c\u0e41\u0e25\u0e30\u0e40\u0e17\u0e04\u0e42\u0e19\u0e42\u0e25\u0e22\u0e35',\n                mimeType: 'application\/pdf',\n                webViewLink: 'https:\/\/drive.google.com\/file\/d\/demo1\/view',\n                embedLink: 'https:\/\/drive.google.com\/file\/d\/1_dM9y0F1234567890\/preview',\n                modifiedTime: '2026-08-15T09:30:00Z',\n                size: '2.4 MB'\n            },\n            {\n                id: '2',\n                name: '\u0e21.1-\u0e2a\u0e44\u0e25\u0e14\u0e4c\u0e2a\u0e23\u0e38\u0e1b\u0e1b\u0e23\u0e30\u0e27\u0e31\u0e15\u0e34\u0e28\u0e32\u0e2a\u0e15\u0e23\u0e4c\u0e2a\u0e21\u0e31\u0e22\u0e2a\u0e38\u0e42\u0e02\u0e17\u0e31\u0e22-\u0e04\u0e23\u0e39\u0e27\u0e34\u0e20\u0e32\u0e27\u0e23\u0e23\u0e13 \u0e2a\u0e38\u0e02\u0e40\u0e2a\u0e23\u0e34\u0e10.pptx',\n                subject: '\u0e2a\u0e31\u0e07\u0e04\u0e21\u0e28\u0e36\u0e01\u0e29\u0e32 \u0e28\u0e32\u0e2a\u0e19\u0e32 \u0e41\u0e25\u0e30\u0e27\u0e31\u0e12\u0e19\u0e18\u0e23\u0e23\u0e21',\n                mimeType: 'application\/vnd.openxmlformats-officedocument.presentationml.presentation',\n                webViewLink: 'https:\/\/drive.google.com\/file\/d\/demo2\/view',\n                embedLink: '',\n                modifiedTime: '2026-08-10T14:15:00Z',\n                size: '15.1 MB'\n            },\n            {\n                id: '3',\n                name: '\u0e1b.6-\u0e41\u0e1a\u0e1a\u0e1d\u0e36\u0e01\u0e2b\u0e31\u0e14\u0e40\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e40\u0e28\u0e29\u0e2a\u0e48\u0e27\u0e19\u0e41\u0e25\u0e30\u0e01\u0e32\u0e23\u0e1a\u0e27\u0e01\u0e17\u0e28\u0e19\u0e34\u0e22\u0e21-\u0e04\u0e23\u0e39\u0e1b\u0e23\u0e30\u0e40\u0e2a\u0e23\u0e34\u0e10 \u0e1b\u0e31\u0e0d\u0e0d\u0e32\u0e14\u0e35.docx',\n                subject: '\u0e04\u0e13\u0e34\u0e15\u0e28\u0e32\u0e2a\u0e15\u0e23\u0e4c',\n                mimeType: 'application\/vnd.openxmlformats-officedocument.wordprocessingml.document',\n                webViewLink: 'https:\/\/drive.google.com\/file\/d\/demo3\/view',\n                embedLink: '',\n                modifiedTime: '2026-08-20T11:00:00Z',\n                size: '850 KB'\n            },\n            {\n                id: '4',\n                name: '\u0e21.4-\u0e04\u0e25\u0e34\u0e1b\u0e2a\u0e32\u0e18\u0e34\u0e15\u0e01\u0e32\u0e23\u0e40\u0e02\u0e35\u0e22\u0e19\u0e42\u0e1b\u0e23\u0e41\u0e01\u0e23\u0e21 Python \u0e40\u0e1a\u0e37\u0e49\u0e2d\u0e07\u0e15\u0e49\u0e19-\u0e04\u0e23\u0e39\u0e2d\u0e19\u0e31\u0e19\u0e15\u0e4c \u0e40\u0e17\u0e04\u0e42\u0e19\u0e42\u0e25\u0e22\u0e35.mp4',\n                subject: '\u0e27\u0e34\u0e17\u0e22\u0e32\u0e28\u0e32\u0e2a\u0e15\u0e23\u0e4c\u0e41\u0e25\u0e30\u0e40\u0e17\u0e04\u0e42\u0e19\u0e42\u0e25\u0e22\u0e35',\n                mimeType: 'video\/mp4',\n                webViewLink: 'https:\/\/drive.google.com\/file\/d\/demo4\/view',\n                embedLink: '',\n                modifiedTime: '2026-08-01T08:45:00Z',\n                size: '45.0 MB'\n            },\n            {\n                id: '5',\n                name: '\u0e21.2-\u0e41\u0e1a\u0e1a\u0e17\u0e14\u0e2a\u0e2d\u0e1a\u0e27\u0e23\u0e23\u0e13\u0e04\u0e14\u0e35\u0e40\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e23\u0e32\u0e21\u0e40\u0e01\u0e35\u0e22\u0e23\u0e15\u0e34\u0e4c-\u0e04\u0e23\u0e39\u0e28\u0e34\u0e23\u0e34\u0e1e\u0e23 \u0e2d\u0e31\u0e01\u0e29\u0e23\u0e28\u0e32\u0e2a\u0e15\u0e23\u0e4c.pdf',\n                subject: '\u0e20\u0e32\u0e29\u0e32\u0e44\u0e17\u0e22',\n                mimeType: 'application\/pdf',\n                webViewLink: 'https:\/\/drive.google.com\/file\/d\/demo5\/view',\n                embedLink: '',\n                modifiedTime: '2026-08-18T16:20:00Z',\n                size: '1.2 MB'\n            },\n            {\n                id: '6',\n                name: '\u0e21.5-Grammar and Vocabulary Review Sheet-\u0e04\u0e23\u0e39\u0e08\u0e2d\u0e2b\u0e4c\u0e19 \u0e2a\u0e21\u0e34\u0e18.pdf',\n                subject: '\u0e20\u0e32\u0e29\u0e32\u0e15\u0e48\u0e32\u0e07\u0e1b\u0e23\u0e30\u0e40\u0e17\u0e28',\n                mimeType: 'application\/pdf',\n                webViewLink: 'https:\/\/drive.google.com\/file\/d\/demo6\/view',\n                embedLink: '',\n                modifiedTime: '2026-08-22T10:10:00Z',\n                size: '3.1 MB'\n            },\n            {\n                id: '7',\n                name: '\u0e21.3-\u0e41\u0e1c\u0e19\u0e01\u0e32\u0e23\u0e2a\u0e2d\u0e19\u0e40\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e41\u0e23\u0e07\u0e41\u0e25\u0e30\u0e01\u0e32\u0e23\u0e40\u0e04\u0e25\u0e37\u0e48\u0e2d\u0e19\u0e17\u0e35\u0e48-\u0e04\u0e23\u0e39\u0e2a\u0e21\u0e0a\u0e32\u0e22 \u0e43\u0e08\u0e14\u0e35.pdf',\n                subject: '\u0e27\u0e34\u0e17\u0e22\u0e32\u0e28\u0e32\u0e2a\u0e15\u0e23\u0e4c\u0e41\u0e25\u0e30\u0e40\u0e17\u0e04\u0e42\u0e19\u0e42\u0e25\u0e22\u0e35',\n                mimeType: 'application\/pdf',\n                webViewLink: 'https:\/\/drive.google.com\/file\/d\/demo7\/view',\n                embedLink: '',\n                modifiedTime: '2026-08-05T13:00:00Z',\n                size: '4.5 MB'\n            },\n            {\n                id: '8',\n                name: '\u0e1b.4-\u0e42\u0e19\u0e49\u0e15\u0e14\u0e19\u0e15\u0e23\u0e35\u0e41\u0e25\u0e30\u0e40\u0e1e\u0e25\u0e07\u0e1e\u0e37\u0e49\u0e19\u0e1a\u0e49\u0e32\u0e19\u0e20\u0e32\u0e04\u0e40\u0e2b\u0e19\u0e37\u0e2d-\u0e04\u0e23\u0e39\u0e2a\u0e38\u0e19\u0e17\u0e23 \u0e04\u0e35\u0e15\u0e01\u0e32\u0e23.pptx',\n                subject: '\u0e28\u0e34\u0e25\u0e1b\u0e30 (\u0e14\u0e19\u0e15\u0e23\u0e35-\u0e19\u0e32\u0e0f\u0e28\u0e34\u0e25\u0e1b\u0e4c)',\n                mimeType: 'application\/vnd.openxmlformats-officedocument.presentationml.presentation',\n                webViewLink: 'https:\/\/drive.google.com\/file\/d\/demo8\/view',\n                embedLink: '',\n                modifiedTime: '2026-08-12T09:00:00Z',\n                size: '8.7 MB'\n            },\n            {\n                id: '9',\n                name: '\u0e21.6-\u0e04\u0e39\u0e48\u0e21\u0e37\u0e2d\u0e40\u0e15\u0e23\u0e35\u0e22\u0e21\u0e2a\u0e2d\u0e1a\u0e17\u0e31\u0e01\u0e29\u0e30\u0e01\u0e32\u0e23\u0e40\u0e25\u0e48\u0e19\u0e1a\u0e32\u0e2a\u0e40\u0e01\u0e15\u0e1a\u0e2d\u0e25-\u0e04\u0e23\u0e39\u0e2a\u0e21\u0e28\u0e31\u0e01\u0e14\u0e34\u0e4c \u0e1e\u0e25\u0e28\u0e36\u0e01\u0e29\u0e32.pdf',\n                subject: '\u0e2a\u0e38\u0e02\u0e28\u0e36\u0e01\u0e29\u0e32\u0e41\u0e25\u0e30\u0e1e\u0e25\u0e28\u0e36\u0e01\u0e29\u0e32',\n                mimeType: 'application\/pdf',\n                webViewLink: 'https:\/\/drive.google.com\/file\/d\/demo9\/view',\n                embedLink: '',\n                modifiedTime: '2026-08-19T15:30:00Z',\n                size: '2.0 MB'\n            }\n        ];\n\n        \/**\n         * Parses file name format: \u0e23\u0e30\u0e14\u0e31\u0e1a\u0e0a\u0e31\u0e49\u0e19-\u0e0a\u0e37\u0e48\u0e2d\u0e2a\u0e37\u0e48\u0e2d-\u0e0a\u0e37\u0e48\u0e2d\u0e04\u0e38\u0e13\u0e04\u0e23\u0e39\n         *\/\n        function parseFileName(fullFileName) {\n            \/\/ Remove file extension\n            const nameWithoutExt = fullFileName.substring(0, fullFileName.lastIndexOf('.')) || fullFileName;\n            const ext = fullFileName.split('.').pop().toLowerCase();\n\n            \/\/ Split by hyphen (-)\n            const parts = nameWithoutExt.split('-');\n\n            let grade = '\u0e44\u0e21\u0e48\u0e23\u0e30\u0e1a\u0e38';\n            let title = nameWithoutExt;\n            let teacher = '\u0e44\u0e21\u0e48\u0e23\u0e30\u0e1a\u0e38\u0e04\u0e23\u0e39\u0e1c\u0e39\u0e49\u0e2a\u0e2d\u0e19';\n\n            if (parts.length >= 3) {\n                grade = parts[0].trim();\n                title = parts[1].trim();\n                \/\/ If teacher name contains remaining hyphens, join them\n                teacher = parts.slice(2).join('-').trim();\n            } else if (parts.length === 2) {\n                grade = parts[0].trim();\n                title = parts[1].trim();\n            }\n\n            return { grade, title, teacher, extension: ext };\n        }\n\n        \/**\n         * Maps raw items into structured objects\n         *\/\n        function processMediaData(rawItems) {\n            return rawItems.map(item => {\n                const parsed = parseFileName(item.name);\n                return {\n                    id: item.id,\n                    rawName: item.name,\n                    title: parsed.title,\n                    grade: parsed.grade,\n                    teacher: parsed.teacher,\n                    subject: item.subject || '\u0e01\u0e25\u0e38\u0e48\u0e21\u0e2a\u0e32\u0e23\u0e30\u0e17\u0e31\u0e48\u0e27\u0e44\u0e1b',\n                    extension: parsed.extension,\n                    mimeType: item.mimeType,\n                    webViewLink: item.webViewLink || '#',\n                    embedLink: item.embedLink || `https:\/\/drive.google.com\/file\/d\/${item.id}\/preview`,\n                    modifiedTime: item.modifiedTime ? new Date(item.modifiedTime).toLocaleDateString('th-TH') : '\u0e44\u0e21\u0e48\u0e23\u0e30\u0e1a\u0e38',\n                    size: item.size || ''\n                };\n            });\n        }\n\n        \/**\n         * Populate filter select dropdown options dynamically\n         *\/\n        function populateFilterDropdowns() {\n            const gradeSelect = document.getElementById('gradeSelect');\n            const subjectSelect = document.getElementById('subjectSelect');\n            const teacherSelect = document.getElementById('teacherSelect');\n\n            \/\/ Extract unique values\n            const grades = [...new Set(allMediaItems.map(item => item.grade))].sort();\n            const subjects = [...new Set(allMediaItems.map(item => item.subject))].sort();\n            const teachers = [...new Set(allMediaItems.map(item => item.teacher))].sort();\n\n            \/\/ Clear existing except first\n            gradeSelect.innerHTML = '<option value=\"\">\u0e17\u0e38\u0e01\u0e23\u0e30\u0e14\u0e31\u0e1a\u0e0a\u0e31\u0e49\u0e19<\/option>';\n            subjectSelect.innerHTML = '<option value=\"\">\u0e17\u0e38\u0e01\u0e01\u0e25\u0e38\u0e48\u0e21\u0e2a\u0e32\u0e23\u0e30\u0e2f<\/option>';\n            teacherSelect.innerHTML = '<option value=\"\">\u0e04\u0e23\u0e39\u0e1c\u0e39\u0e49\u0e2a\u0e2d\u0e19\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14<\/option>';\n\n            grades.forEach(g => {\n                if (g && g !== '\u0e44\u0e21\u0e48\u0e23\u0e30\u0e1a\u0e38') {\n                    gradeSelect.innerHTML += `<option value=\"${g}\">${g}<\/option>`;\n                }\n            });\n\n            subjects.forEach(s => {\n                if (s) {\n                    subjectSelect.innerHTML += `<option value=\"${s}\">${s}<\/option>`;\n                }\n            });\n\n            teachers.forEach(t => {\n                if (t && t !== '\u0e44\u0e21\u0e48\u0e23\u0e30\u0e1a\u0e38\u0e04\u0e23\u0e39\u0e1c\u0e39\u0e49\u0e2a\u0e2d\u0e19') {\n                    teacherSelect.innerHTML += `<option value=\"${t}\">${t}<\/option>`;\n                }\n            });\n\n            \/\/ Update Header Stats Badges\n            document.getElementById('statTotalMedia').innerText = allMediaItems.length;\n            document.getElementById('statSubjects').innerText = subjects.length;\n            document.getElementById('statGrades').innerText = grades.length;\n            document.getElementById('statTeachers').innerText = teachers.length;\n        }\n\n        \/**\n         * Render Media Grid Cards\n         *\/\n        function renderMediaCards(items) {\n            const grid = document.getElementById('mediaGrid');\n            const emptyState = document.getElementById('emptyState');\n            const resultCountBadge = document.getElementById('resultCountBadge');\n            const pagination = document.getElementById('pagination');\n\n            grid.innerHTML = '';\n            resultCountBadge.innerText = `${items.length} \u0e23\u0e32\u0e22\u0e01\u0e32\u0e23`;\n\n            if (items.length === 0) {\n                emptyState.classList.remove('hidden');\n                grid.classList.add('hidden');\n                pagination.classList.add('hidden');\n                return;\n            }\n\n            emptyState.classList.add('hidden');\n            grid.classList.remove('hidden');\n\n            const totalPages = Math.ceil(items.length \/ ITEMS_PER_PAGE);\n            currentPage = Math.min(Math.max(currentPage, 1), totalPages);\n            const startIndex = (currentPage - 1) * ITEMS_PER_PAGE;\n            const pageItems = items.slice(startIndex, startIndex + ITEMS_PER_PAGE);\n\n            pageItems.forEach(item => {\n                const iconInfo = getFileTypeIcon(item.extension, item.mimeType);\n                \n                const card = document.createElement('div');\n                card.className = \"bg-white rounded-2xl border border-slate-200 hover:border-sky-300 shadow-sm hover:shadow-md transition-all duration-200 flex flex-col overflow-hidden group\";\n                \n                card.innerHTML = `\n                    <div class=\"p-5 flex-grow flex flex-col justify-between\">\n                        <div>\n                            <!-- Top Badges -->\n                            <div class=\"flex flex-wrap gap-1.5 mb-3\">\n                                <span class=\"bg-sky-50 text-sky-700 font-medium text-[11px] px-2.5 py-0.5 rounded-md border border-sky-100 flex items-center\">\n                                    <i class=\"fa-solid fa-graduation-cap mr-1 text-[10px]\"><\/i> ${item.grade}\n                                <\/span>\n                                <span class=\"bg-slate-100 text-slate-700 font-medium text-[11px] px-2.5 py-0.5 rounded-md flex items-center\">\n                                    <i class=\"fa-solid fa-folder mr-1 text-[10px] text-slate-400\"><\/i> ${item.subject}\n                                <\/span>\n                            <\/div>\n\n                            <!-- Title -->\n                            <div class=\"flex items-start space-x-3 mb-3\">\n                                <div class=\"${iconInfo.bgColor} ${iconInfo.textColor} p-2.5 rounded-xl shrink-0 mt-0.5\">\n                                    <i class=\"${iconInfo.icon} text-lg\"><\/i>\n                                <\/div>\n                                <h4 class=\"font-semibold text-slate-800 text-sm leading-snug group-hover:text-sky-600 transition line-clamp-2\" title=\"${item.title}\">\n                                    ${item.title}\n                                <\/h4>\n                            <\/div>\n                        <\/div>\n\n                        <!-- Info & Teacher -->\n                        <div class=\"mt-4 pt-3 border-t border-slate-100 space-y-1 text-xs text-slate-500\">\n                            <div class=\"flex items-center text-slate-600 font-medium\">\n                                <i class=\"fa-solid fa-user-circle text-slate-400 mr-1.5 text-sm\"><\/i>\n                                <span class=\"truncate\">${item.teacher}<\/span>\n                            <\/div>\n                            <div class=\"flex items-center justify-between text-[11px] text-slate-400 pt-1\">\n                                <span>\u0e2d\u0e31\u0e1b\u0e40\u0e14\u0e15: ${item.modifiedTime}<\/span>\n                                <span class=\"uppercase font-mono\">${item.extension}<\/span>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n\n                    <!-- Footer Action Buttons -->\n                    <div class=\"bg-slate-50 px-4 py-2.5 border-t border-slate-100 flex items-center justify-between gap-2\">\n                        <button onclick=\"openPreview('${item.title}', '${item.teacher}', '${item.embedLink}', '${item.webViewLink}', '${item.extension}', '${item.mimeType}', '${item.id}')\" \n                            class=\"flex-1 py-1.5 px-3 bg-white hover:bg-slate-100 text-slate-700 font-medium text-xs rounded-lg border border-slate-200 transition text-center flex items-center justify-center\">\n                            <i class=\"fa-solid fa-eye mr-1.5 text-slate-400\"><\/i> \u0e1e\u0e23\u0e35\u0e27\u0e34\u0e27\n                        <\/button>\n                        <a href=\"${item.webViewLink}\" target=\"_blank\" \n                            class=\"flex-1 py-1.5 px-3 bg-sky-600 hover:bg-sky-700 text-white font-medium text-xs rounded-lg transition text-center flex items-center justify-center shadow-sm\">\n                            <i class=\"fa-solid fa-arrow-up-right-from-square mr-1.5\"><\/i> \u0e40\u0e1b\u0e34\u0e14\u0e44\u0e1f\u0e25\u0e4c\n                        <\/a>\n                    <\/div>\n                `;\n                grid.appendChild(card);\n            });\n\n            renderPagination(totalPages);\n        }\n\n        function renderPagination(totalPages) {\n            const pagination = document.getElementById('pagination');\n            if (totalPages <= 1) {\n                pagination.classList.add('hidden');\n                pagination.innerHTML = '';\n                return;\n            }\n\n            pagination.classList.remove('hidden');\n            const pageButtons = [];\n            for (let page = 1; page <= totalPages; page++) {\n                if (page === 1 || page === totalPages || Math.abs(page - currentPage) <= 2) {\n                    pageButtons.push(`<button onclick=\"changePage(${page})\" class=\"min-w-9 h-9 px-3 rounded-lg text-sm font-medium border transition ${page === currentPage ? 'bg-sky-600 text-white border-sky-600' : 'bg-white text-slate-600 border-slate-200 hover:border-sky-400 hover:text-sky-600'}\">${page}<\/button>`);\n                } else if (pageButtons[pageButtons.length - 1] !== '<span>\u2026<\/span>') {\n                    pageButtons.push('<span>\u2026<\/span>');\n                }\n            }\n\n            pagination.innerHTML = `\n                <button onclick=\"changePage(${currentPage - 1})\" ${currentPage === 1 ? 'disabled' : ''} class=\"h-9 px-3 rounded-lg text-sm border border-slate-200 bg-white text-slate-600 disabled:opacity-40 disabled:cursor-not-allowed hover:border-sky-400\">\u0e01\u0e48\u0e2d\u0e19\u0e2b\u0e19\u0e49\u0e32<\/button>\n                ${pageButtons.join('')}\n                <button onclick=\"changePage(${currentPage + 1})\" ${currentPage === totalPages ? 'disabled' : ''} class=\"h-9 px-3 rounded-lg text-sm border border-slate-200 bg-white text-slate-600 disabled:opacity-40 disabled:cursor-not-allowed hover:border-sky-400\">\u0e16\u0e31\u0e14\u0e44\u0e1b<\/button>\n            `;\n        }\n\n        function changePage(page) {\n            const totalPages = Math.ceil(filteredMediaItems.length \/ ITEMS_PER_PAGE);\n            if (page < 1 || page > totalPages || page === currentPage) return;\n            currentPage = page;\n            renderMediaCards(filteredMediaItems);\n            document.getElementById('resultCountBadge').scrollIntoView({ behavior: 'smooth', block: 'center' });\n        }\n\n        \/**\n         * Return icon and style based on file type\n         *\/\n        function getFileTypeIcon(ext, mimeType) {\n            if (ext === 'pdf' || mimeType.includes('pdf')) {\n                return { icon: 'fa-solid fa-file-pdf', bgColor: 'bg-rose-50', textColor: 'text-rose-600' };\n            } else if (['pptx', 'ppt', 'key'].includes(ext) || mimeType.includes('presentation')) {\n                return { icon: 'fa-solid fa-file-powerpoint', bgColor: 'bg-orange-50', textColor: 'text-orange-600' };\n            } else if (['docx', 'doc'].includes(ext) || mimeType.includes('word')) {\n                return { icon: 'fa-solid fa-file-word', bgColor: 'bg-blue-50', textColor: 'text-blue-600' };\n            } else if (['xlsx', 'xls', 'csv'].includes(ext) || mimeType.includes('sheet')) {\n                return { icon: 'fa-solid fa-file-excel', bgColor: 'bg-emerald-50', textColor: 'text-emerald-600' };\n            } else if (['mp4', 'mov', 'avi', 'mkv'].includes(ext) || mimeType.includes('video')) {\n                return { icon: 'fa-solid fa-file-video', bgColor: 'bg-purple-50', textColor: 'text-purple-600' };\n            } else if (['jpg', 'png', 'jpeg', 'gif'].includes(ext) || mimeType.includes('image')) {\n                return { icon: 'fa-solid fa-file-image', bgColor: 'bg-indigo-50', textColor: 'text-indigo-600' };\n            } else {\n                return { icon: 'fa-solid fa-file-lines', bgColor: 'bg-slate-100', textColor: 'text-slate-600' };\n            }\n        }\n\n        \/**\n         * Apply all filters to media grid\n         *\/\n        function applyFilters() {\n            currentPage = 1;\n            const searchVal = document.getElementById('searchInput').value.toLowerCase().trim();\n            const selectedGrade = document.getElementById('gradeSelect').value;\n            const selectedSubject = document.getElementById('subjectSelect').value;\n            const selectedTeacher = document.getElementById('teacherSelect').value;\n\n            filteredMediaItems = allMediaItems.filter(item => {\n                \/\/ Keyword match (Title, RawName, Teacher)\n                const matchesKeyword = !searchVal || \n                    item.title.toLowerCase().includes(searchVal) ||\n                    item.rawName.toLowerCase().includes(searchVal) ||\n                    item.teacher.toLowerCase().includes(searchVal);\n\n                \/\/ Grade match\n                const matchesGrade = !selectedGrade || item.grade === selectedGrade;\n\n                \/\/ Subject match\n                const matchesSubject = !selectedSubject || item.subject === selectedSubject;\n\n                \/\/ Teacher match\n                const matchesTeacher = !selectedTeacher || item.teacher === selectedTeacher;\n\n                return matchesKeyword && matchesGrade && matchesSubject && matchesTeacher;\n            });\n\n            renderMediaCards(filteredMediaItems);\n        }\n\n        \/**\n         * Reset search and filters\n         *\/\n        function resetFilters() {\n            document.getElementById('searchInput').value = '';\n            document.getElementById('gradeSelect').value = '';\n            document.getElementById('subjectSelect').value = '';\n            document.getElementById('teacherSelect').value = '';\n            applyFilters();\n        }\n\n        \/**\n         * Fetch folders and files recursively\/by parent from Google Drive API v3\n         *\/\n        function buildDriveApiUrl(query, fields, apiKey, pageToken = '') {\n            const params = new URLSearchParams({\n                q: query,\n                fields: `nextPageToken,files(${fields})`,\n                pageSize: '1000',\n                orderBy: 'modifiedTime desc',\n                key: apiKey\n            });\n            if (pageToken) params.set('pageToken', pageToken);\n            return `https:\/\/www.googleapis.com\/drive\/v3\/files?${params.toString()}`;\n        }\n\n        async function fetchAllPages(query, fields, apiKey) {\n            const files = [];\n            let pageToken = '';\n            do {\n                const response = await fetch(buildDriveApiUrl(query, fields, apiKey, pageToken));\n                const data = await response.json();\n                if (!response.ok || data.error) {\n                    throw new Error(data.error?.message || `Google Drive \u0e15\u0e2d\u0e1a\u0e01\u0e25\u0e31\u0e1a ${response.status}`);\n                }\n                files.push(...(data.files || []));\n                pageToken = data.nextPageToken || '';\n            } while (pageToken);\n            return files;\n        }\n\n        function displayDriveData(rawItems, isCached = false) {\n            allMediaItems = processMediaData(rawItems);\n            populateFilterDropdowns();\n            applyFilters();\n            currentMode = 'drive';\n            const cacheText = isCached ? ' (\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e41\u0e04\u0e0a)' : '';\n            document.getElementById('dataSourceStatus').innerHTML = `\u0e01\u0e33\u0e25\u0e31\u0e07\u0e41\u0e2a\u0e14\u0e07\u0e1c\u0e25: <span class=\"font-medium text-emerald-600\"><i class=\"fa-brands fa-google-drive\"><\/i> \u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e08\u0e32\u0e01 Google Drive${cacheText}<\/span>`;\n        }\n\n        function readDriveCache() {\n            try {\n                const cache = JSON.parse(localStorage.getItem(CACHE_KEY));\n                if (!cache || !Array.isArray(cache.items)) return null;\n                return cache;\n            } catch (_) {\n                return null;\n            }\n        }\n\n        async function fetchGoogleDriveFiles(apiKey, rootFolderId, options = {}) {\n            const { background = false } = options;\n            if (!background) showLoading(true);\n            try {\n                \/\/ \u0e04\u0e33\u0e02\u0e2d\u0e41\u0e23\u0e01\u0e14\u0e36\u0e07\u0e17\u0e31\u0e49\u0e07\u0e42\u0e1f\u0e25\u0e40\u0e14\u0e2d\u0e23\u0e4c\u0e41\u0e25\u0e30\u0e44\u0e1f\u0e25\u0e4c\u0e17\u0e35\u0e48\u0e2d\u0e22\u0e39\u0e48\u0e2b\u0e19\u0e49\u0e32\u0e41\u0e23\u0e01\u0e1e\u0e23\u0e49\u0e2d\u0e21\u0e01\u0e31\u0e19\n                const rootChildren = await fetchAllPages(\n                    `'${rootFolderId}' in parents and trashed=false`,\n                    'id,name,mimeType,webViewLink,modifiedTime,size,parents',\n                    apiKey\n                );\n                const folderMime = 'application\/vnd.google-apps.folder';\n                const folders = rootChildren.filter(item => item.mimeType === folderMime);\n                const driveFiles = rootChildren\n                    .filter(item => item.mimeType !== folderMime)\n                    .map(item => ({ ...item, subject: '\u0e2a\u0e37\u0e48\u0e2d\u0e17\u0e31\u0e48\u0e27\u0e44\u0e1b' }));\n\n                \/\/ \u0e14\u0e36\u0e07\u0e41\u0e15\u0e48\u0e25\u0e30\u0e42\u0e1f\u0e25\u0e40\u0e14\u0e2d\u0e23\u0e4c\u0e1e\u0e23\u0e49\u0e2d\u0e21\u0e01\u0e31\u0e19 \u0e23\u0e2d\u0e07\u0e23\u0e31\u0e1a\u0e42\u0e04\u0e23\u0e07\u0e2a\u0e23\u0e49\u0e32\u0e07 Drive \u0e44\u0e14\u0e49\u0e40\u0e2a\u0e16\u0e35\u0e22\u0e23\u0e01\u0e27\u0e48\u0e32\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07 OR \u0e41\u0e1a\u0e1a\u0e22\u0e32\u0e27\n                if (folders.length) {\n                    const folderResults = await Promise.all(folders.map(async folder => {\n                        const files = await fetchAllPages(\n                            `'${folder.id}' in parents and mimeType!='${folderMime}' and trashed=false`,\n                            'id,name,mimeType,webViewLink,modifiedTime,size',\n                            apiKey\n                        );\n                        return files.map(file => ({ ...file, subject: folder.name }));\n                    }));\n                    driveFiles.push(...folderResults.flat());\n                }\n\n                localStorage.setItem(CACHE_KEY, JSON.stringify({ savedAt: Date.now(), items: driveFiles }));\n                displayDriveData(driveFiles);\n                \n            } catch (err) {\n                alertToast('\u0e40\u0e01\u0e34\u0e14\u0e02\u0e49\u0e2d\u0e1c\u0e34\u0e14\u0e1e\u0e25\u0e32\u0e14\u0e43\u0e19\u0e01\u0e32\u0e23\u0e14\u0e36\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25 Drive: ' + err.message, 'error');\n                if (!allMediaItems.length) {\n                    document.getElementById('dataSourceStatus').innerHTML = '<span class=\"font-medium text-rose-600\">\u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21\u0e15\u0e48\u0e2d Google Drive \u0e44\u0e21\u0e48\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08<\/span>';\n                    document.getElementById('mediaGrid').classList.add('hidden');\n                    document.getElementById('emptyState').classList.remove('hidden');\n                    document.querySelector('#emptyState h4').innerText = '\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e42\u0e2b\u0e25\u0e14\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e08\u0e32\u0e01 Google Drive \u0e44\u0e14\u0e49';\n                    document.querySelector('#emptyState p').innerText = err.message;\n                }\n            } finally {\n                if (!background) showLoading(false);\n            }\n        }\n\n        \/**\n         * Load Mock Demo Data\n         *\/\n        function loadDemoData() {\n            currentMode = 'demo';\n            allMediaItems = processMediaData(MOCK_DATA);\n            populateFilterDropdowns();\n            applyFilters();\n            \n            document.getElementById('dataSourceStatus').innerHTML = '\u0e01\u0e33\u0e25\u0e31\u0e07\u0e41\u0e2a\u0e14\u0e07\u0e1c\u0e25: <span class=\"font-medium text-amber-600\">\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e15\u0e31\u0e27\u0e2d\u0e22\u0e48\u0e32\u0e07 (Demo Data)<\/span>';\n        }\n\n        async function openPreview(title, teacher, embedLink, webViewLink, extension, mimeType, fileId) {\n            const modal = document.getElementById('previewModal');\n            const iframe = document.getElementById('previewIframe');\n            const iconContainer = document.getElementById('modalFileIcon');\n            const iconInfo = getFileTypeIcon(extension, mimeType);\n\n            document.getElementById('modalFileTitle').innerText = title;\n            document.getElementById('modalFileMeta').innerText = `\u0e04\u0e23\u0e39\u0e1c\u0e39\u0e49\u0e2a\u0e2d\u0e19: ${teacher} | \u0e1b\u0e23\u0e30\u0e40\u0e20\u0e17: ${extension.toUpperCase()}`;\n            document.getElementById('modalDownloadBtn').href = webViewLink;\n            \n            iconContainer.className = `text-lg ${iconInfo.textColor}`;\n            iconContainer.innerHTML = `<i class=\"${iconInfo.icon}\"><\/i>`;\n\n            \/\/ \u0e22\u0e49\u0e32\u0e22 Modal \u0e44\u0e1b\u0e44\u0e27\u0e49\u0e43\u0e15\u0e49 body \u0e42\u0e14\u0e22\u0e15\u0e23\u0e07 \u0e1b\u0e49\u0e2d\u0e07\u0e01\u0e31\u0e19\u0e40\u0e21\u0e19\u0e39\/\u0e18\u0e35\u0e21 WordPress \u0e17\u0e31\u0e1a\u0e2b\u0e19\u0e49\u0e32\u0e1e\u0e23\u0e35\u0e27\u0e34\u0e27\n            if (modal.parentElement !== document.body) document.body.appendChild(modal);\n            modal.style.setProperty('z-index', '2147483647', 'important');\n            modal.style.setProperty('top', '0', 'important');\n            modal.classList.remove('hidden');\n\n            if (activePreviewUrl) {\n                URL.revokeObjectURL(activePreviewUrl);\n                activePreviewUrl = '';\n            }\n\n            if (extension.toLowerCase() === 'html' || mimeType.includes('html')) {\n                iframe.srcdoc = '<div style=\"font-family:sans-serif;padding:40px;text-align:center;color:#64748b\">\u0e01\u0e33\u0e25\u0e31\u0e07\u0e42\u0e2b\u0e25\u0e14\u0e15\u0e31\u0e27\u0e2d\u0e22\u0e48\u0e32\u0e07 HTML...<\/div>';\n                try {\n                    \/\/ \u0e40\u0e1e\u0e34\u0e48\u0e21\u0e40\u0e27\u0e25\u0e32\u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19\u0e41\u0e25\u0e30\u0e1b\u0e34\u0e14\u0e41\u0e04\u0e0a \u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e43\u0e2b\u0e49\u0e44\u0e14\u0e49\u0e40\u0e19\u0e37\u0e49\u0e2d\u0e2b\u0e32\u0e44\u0e1f\u0e25\u0e4c\u0e40\u0e27\u0e2d\u0e23\u0e4c\u0e0a\u0e31\u0e19\u0e25\u0e48\u0e32\u0e2a\u0e38\u0e14\u0e40\u0e2a\u0e21\u0e2d\n                    const url = `https:\/\/www.googleapis.com\/drive\/v3\/files\/${encodeURIComponent(fileId)}?alt=media&key=${encodeURIComponent(GOOGLE_DRIVE_API_KEY)}&_=${Date.now()}`;\n                    const response = await fetch(url, { cache: 'no-store' });\n                    if (!response.ok) throw new Error(`\u0e42\u0e2b\u0e25\u0e14\u0e44\u0e1f\u0e25\u0e4c\u0e44\u0e21\u0e48\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08 (${response.status})`);\n                    const htmlText = await response.text();\n                    if (htmlText.includes('teacher_media_cache') || htmlText.includes('\u0e04\u0e25\u0e31\u0e07\u0e2a\u0e37\u0e48\u0e2d\u0e01\u0e32\u0e23\u0e40\u0e23\u0e35\u0e22\u0e19\u0e23\u0e39\u0e49\u0e04\u0e23\u0e39')) {\n                        iframe.srcdoc = '<div style=\"font-family:sans-serif;max-width:680px;margin:60px auto;padding:28px;text-align:center;color:#9f1239;background:#fff1f2;border:1px solid #fecdd3;border-radius:16px\"><h2 style=\"margin-top:0\">\u0e44\u0e1f\u0e25\u0e4c\u0e17\u0e35\u0e48\u0e2d\u0e31\u0e1b\u0e42\u0e2b\u0e25\u0e14\u0e40\u0e1b\u0e47\u0e19\u0e2b\u0e19\u0e49\u0e32\u0e40\u0e27\u0e47\u0e1a\u0e04\u0e25\u0e31\u0e07\u0e2a\u0e37\u0e48\u0e2d<\/h2><p>\u0e40\u0e19\u0e37\u0e49\u0e2d\u0e2b\u0e32\u0e20\u0e32\u0e22\u0e43\u0e19\u0e44\u0e1f\u0e25\u0e4c\u0e19\u0e35\u0e49\u0e22\u0e31\u0e07\u0e40\u0e1b\u0e47\u0e19\u0e42\u0e04\u0e49\u0e14\u0e02\u0e2d\u0e07\u0e04\u0e25\u0e31\u0e07\u0e2a\u0e37\u0e48\u0e2d\u0e40\u0e27\u0e2d\u0e23\u0e4c\u0e0a\u0e31\u0e19\u0e40\u0e14\u0e34\u0e21 \u0e44\u0e21\u0e48\u0e43\u0e0a\u0e48\u0e2b\u0e19\u0e49\u0e32\u0e1a\u0e17\u0e40\u0e23\u0e35\u0e22\u0e19\u0e17\u0e35\u0e48\u0e15\u0e49\u0e2d\u0e07\u0e01\u0e32\u0e23 \u0e01\u0e23\u0e38\u0e13\u0e32\u0e15\u0e23\u0e27\u0e08\u0e44\u0e1f\u0e25\u0e4c\u0e15\u0e49\u0e19\u0e09\u0e1a\u0e31\u0e1a\u0e43\u0e19\u0e40\u0e04\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e41\u0e25\u0e49\u0e27\u0e2d\u0e31\u0e1b\u0e42\u0e2b\u0e25\u0e14\u0e43\u0e2b\u0e21\u0e48<\/p><\/div>';\n                        return;\n                    }\n                    activePreviewUrl = URL.createObjectURL(new Blob([htmlText], { type: 'text\/html;charset=utf-8' }));\n                    iframe.removeAttribute('srcdoc');\n                    iframe.src = activePreviewUrl;\n                } catch (err) {\n                    iframe.srcdoc = `<div style=\"font-family:sans-serif;padding:40px;text-align:center;color:#be123c\">\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e1e\u0e23\u0e35\u0e27\u0e34\u0e27 HTML \u0e44\u0e14\u0e49<br><small>${err.message}<\/small><\/div>`;\n                }\n            } else {\n                iframe.removeAttribute('srcdoc');\n                iframe.src = embedLink;\n            }\n        }\n\n        function closePreviewModal() {\n            const modal = document.getElementById('previewModal');\n            const iframe = document.getElementById('previewIframe');\n            iframe.src = ''; \/\/ stop media playback\n            iframe.removeAttribute('srcdoc');\n            if (activePreviewUrl) {\n                URL.revokeObjectURL(activePreviewUrl);\n                activePreviewUrl = '';\n            }\n            modal.classList.add('hidden');\n        }\n\n        function showLoading(isLoading) {\n            const loading = document.getElementById('loadingState');\n            const grid = document.getElementById('mediaGrid');\n            if (isLoading) {\n                loading.classList.remove('hidden');\n                grid.classList.add('hidden');\n            } else {\n                loading.classList.add('hidden');\n                grid.classList.remove('hidden');\n            }\n        }\n\n        \/\/ Custom non-blocking Notification Toast\n        function alertToast(msg, type = 'info') {\n            const toast = document.createElement('div');\n            toast.className = `fixed bottom-5 right-5 z-50 px-4 py-3 rounded-xl shadow-lg text-xs font-medium text-white flex items-center space-x-2 transition-all duration-300 transform translate-y-2 ${type === 'error' ? 'bg-rose-600' : 'bg-slate-800'}`;\n            toast.innerHTML = `<i class=\"fa-solid fa-circle-info\"><\/i> <span>${msg}<\/span>`;\n            document.body.appendChild(toast);\n            setTimeout(() => {\n                toast.classList.add('opacity-0', 'translate-y-4');\n                setTimeout(() => toast.remove(), 300);\n            }, 4000);\n        }\n\n        \/\/ Initialize Application\n        window.onload = function() {\n            const cache = readDriveCache();\n            if (cache) {\n                displayDriveData(cache.items, true);\n                \/\/ \u0e41\u0e2a\u0e14\u0e07\u0e41\u0e04\u0e0a\u0e17\u0e31\u0e19\u0e17\u0e35\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e40\u0e23\u0e47\u0e27 \u0e41\u0e25\u0e30\u0e15\u0e23\u0e27\u0e08\u0e2b\u0e32\u0e44\u0e1f\u0e25\u0e4c\u0e43\u0e2b\u0e21\u0e48\u0e08\u0e32\u0e01 Drive \u0e17\u0e38\u0e01\u0e04\u0e23\u0e31\u0e49\u0e07\n                fetchGoogleDriveFiles(GOOGLE_DRIVE_API_KEY, DRIVE_FOLDER_ID, { background: true });\n            } else {\n                fetchGoogleDriveFiles(GOOGLE_DRIVE_API_KEY, DRIVE_FOLDER_ID);\n            }\n        };\n    <\/script>\n<\/body>\n<\/html>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"page-no-title","meta":{"footnotes":""},"class_list":["post-239","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/rkk.ac.th\/index.php?rest_route=\/wp\/v2\/pages\/239","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rkk.ac.th\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/rkk.ac.th\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/rkk.ac.th\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rkk.ac.th\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=239"}],"version-history":[{"count":11,"href":"https:\/\/rkk.ac.th\/index.php?rest_route=\/wp\/v2\/pages\/239\/revisions"}],"predecessor-version":[{"id":254,"href":"https:\/\/rkk.ac.th\/index.php?rest_route=\/wp\/v2\/pages\/239\/revisions\/254"}],"wp:attachment":[{"href":"https:\/\/rkk.ac.th\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=239"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}