{"id":1285,"date":"2026-08-18T15:46:15","date_gmt":"2026-08-18T08:46:15","guid":{"rendered":"https:\/\/phrae1.go.th\/sites\/?p=1285"},"modified":"2026-08-18T15:46:15","modified_gmt":"2026-08-18T08:46:15","slug":"%e0%b8%82%e0%b9%89%e0%b8%ad%e0%b8%a1%e0%b8%b9%e0%b8%a5%e0%b8%9c%e0%b8%b9%e0%b9%89%e0%b8%9a%e0%b8%a3%e0%b8%b4%e0%b8%ab%e0%b8%b2%e0%b8%a3%e0%b8%aa%e0%b8%96%e0%b8%b2%e0%b8%99%e0%b8%a8%e0%b8%b6%e0%b8%81","status":"publish","type":"post","link":"https:\/\/phrae1.go.th\/sites\/%e0%b8%82%e0%b9%89%e0%b8%ad%e0%b8%a1%e0%b8%b9%e0%b8%a5%e0%b8%9c%e0%b8%b9%e0%b9%89%e0%b8%9a%e0%b8%a3%e0%b8%b4%e0%b8%ab%e0%b8%b2%e0%b8%a3%e0%b8%aa%e0%b8%96%e0%b8%b2%e0%b8%99%e0%b8%a8%e0%b8%b6%e0%b8%81\/","title":{"rendered":"\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e1c\u0e39\u0e49\u0e1a\u0e23\u0e34\u0e2b\u0e32\u0e23\u0e2a\u0e16\u0e32\u0e19\u0e28\u0e36\u0e01\u0e29\u0e32"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"th\" class=\"h-full\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Dashboard \u0e27\u0e34\u0e40\u0e04\u0e23\u0e32\u0e30\u0e2b\u0e4c\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e08\u0e32\u0e01 Google Sheets<\/title>\n    <!-- Tailwind CSS -->\n    <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n    <!-- Chart.js for data visualization -->\n    <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/chart.js\"><\/script>\n    <!-- Font Awesome for icons -->\n    <link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/font-awesome\/6.4.0\/css\/all.min.css\">\n    <!-- Google Fonts Inter & Prompt -->\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Prompt:wght@300;400;500;600;700&#038;display=swap\" rel=\"stylesheet\">\n    <style>\n        body { font-family: 'Prompt', sans-serif; }\n    <\/style>\n<\/head>\n<body class=\"bg-slate-50 text-slate-800 h-full flex flex-col\">\n\n    <header class=\"bg-indigo-600 text-white shadow-md\">\n        <div class=\"max-w-7xl mx-auto px-4 py-4 flex flex-col sm:flex-row justify-between items-center gap-4\">\n            <div class=\"flex items-center space-x-3\">\n                <div class=\"bg-white\/10 p-2.5 rounded-xl backdrop-blur-sm\">\n                    <i class=\"fa-solid fa-chart-pie text-2xl text-indigo-100\"><\/i>\n                <\/div>\n                <div>\n                    <h1 class=\"text-xl font-bold tracking-tight\">\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e1c\u0e39\u0e49\u0e1a\u0e23\u0e34\u0e2b\u0e32\u0e23\u0e2a\u0e16\u0e32\u0e19\u0e28\u0e36\u0e01\u0e29\u0e32 \u0e2a\u0e31\u0e07\u0e01\u0e31\u0e14 \u0e2a\u0e1e\u0e1b.\u0e41\u0e1e\u0e23\u0e48 \u0e40\u0e02\u0e15 1<\/h1>\n                    <p class=\"text-xs text-indigo-200\">\u0e27\u0e34\u0e40\u0e04\u0e23\u0e32\u0e30\u0e2b\u0e4c\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e08\u0e32\u0e01 Google Sheets \u0e2d\u0e31\u0e15\u0e42\u0e19\u0e21\u0e31\u0e15\u0e34<\/p>\n                <\/div>\n            <\/div>\n            <div class=\"flex items-center space-x-3 w-full sm:w-auto justify-end\">\n                <span id=\"sync-status\" class=\"text-xs bg-indigo-500\/50 text-indigo-100 px-3 py-1.5 rounded-full flex items-center gap-1.5\">\n                    <span class=\"w-2 h-2 rounded-full bg-emerald-400 animate-pulse\"><\/span>\n                    \u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21\u0e15\u0e48\u0e2d\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e41\u0e25\u0e49\u0e27\n                <\/span>\n                <button onclick=\"loadSheetData()\" class=\"bg-indigo-700 hover:bg-indigo-800 text-white text-xs px-4 py-2 rounded-lg font-medium transition shadow-sm flex items-center gap-1.5\">\n                    <i class=\"fa-solid fa-rotate\"><\/i> \u0e42\u0e2b\u0e25\u0e14\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e43\u0e2b\u0e21\u0e48\n                <\/button>\n            <\/div>\n        <\/div>\n    <\/header>\n\n    <main class=\"flex-1 max-w-7xl w-full mx-auto px-4 py-6 overflow-y-auto\">\n        <!-- Summary Stat Cards -->\n        <div class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-1 gap-4 mb-6\">\n            <div class=\"bg-white p-5 rounded-2xl shadow-sm border border-slate-100 flex items-center justify-between\">\n                <div>\n                    <p class=\"text-xs font-medium text-slate-400 uppercase tracking-wider\">\u0e08\u0e33\u0e19\u0e27\u0e19\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14<\/p>\n                    <h3 id=\"stat-total-rows\" class=\"text-2xl font-bold text-slate-700 mt-1\">0<\/h3>\n                <\/div>\n                <div class=\"w-12 h-12 rounded-xl bg-blue-50 text-blue-600 flex items-center justify-center text-xl\">\n                    <i class=\"fa-solid fa-database\"><\/i>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <!-- Charts Grid -->\n        <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6\">\n            <!-- Bar Chart Card -->\n            <div class=\"bg-white p-5 rounded-2xl shadow-sm border border-slate-100 flex flex-col\">\n                <div class=\"flex justify-between items-center mb-4\">\n                    <h4 class=\"font-semibold text-slate-800 text-sm flex items-center gap-2\">\n                        <i class=\"fa-solid fa-chart-column text-indigo-600\"><\/i> \u0e2a\u0e16\u0e34\u0e15\u0e34\u0e20\u0e32\u0e1e\u0e23\u0e27\u0e21\u0e15\u0e32\u0e21\u0e2b\u0e21\u0e27\u0e14\u0e2b\u0e21\u0e39\u0e48 \/ \u0e04\u0e2d\u0e25\u0e31\u0e21\u0e19\u0e4c\n                    <\/h4>\n                <\/div>\n                <div class=\"relative flex-1 min-h-[280px]\">\n                    <canvas id=\"barChart\"><\/canvas>\n                <\/div>\n            <\/div>\n            <!-- Doughnut Chart Card -->\n            <div class=\"bg-white p-5 rounded-2xl shadow-sm border border-slate-100 flex flex-col\">\n                <div class=\"flex justify-between items-center mb-4\">\n                    <h4 class=\"font-semibold text-slate-800 text-sm flex items-center gap-2\">\n                        <i class=\"fa-solid fa-chart-pie text-purple-600\"><\/i> \u0e2a\u0e31\u0e14\u0e2a\u0e48\u0e27\u0e19\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e40\u0e0a\u0e34\u0e07\u0e40\u0e1b\u0e23\u0e35\u0e22\u0e1a\u0e40\u0e17\u0e35\u0e22\u0e1a\n                    <\/h4>\n                <\/div>\n                <div class=\"relative flex-1 min-h-[280px] flex items-center justify-center\">\n                    <canvas id=\"doughnutChart\"><\/canvas>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <!-- Data Table Section -->\n        <div class=\"bg-white rounded-2xl shadow-sm border border-slate-100 overflow-hidden mb-8\">\n            <div class=\"p-5 border-b border-slate-100 flex flex-col sm:flex-row justify-between items-center gap-4\">\n                <h4 class=\"font-semibold text-slate-800 text-sm flex items-center gap-2\">\n                    <i class=\"fa-solid fa-table text-indigo-600\"><\/i> \u0e23\u0e32\u0e22\u0e25\u0e30\u0e40\u0e2d\u0e35\u0e22\u0e14\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e14\u0e34\u0e1a\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\n                <\/h4>\n                <div class=\"w-full sm:w-64\">\n                    <input type=\"text\" id=\"table-search\" placeholder=\"\u0e04\u0e49\u0e19\u0e2b\u0e32\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e43\u0e19\u0e15\u0e32\u0e23\u0e32\u0e07...\" oninput=\"filterTable()\" class=\"w-full px-3 py-1.5 text-xs bg-slate-50 border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500\">\n                <\/div>\n            <\/div>\n            <div class=\"overflow-x-auto max-h-96\">\n                <table class=\"w-full text-left border-collapse text-xs\">\n                    <thead id=\"table-head\" class=\"bg-slate-50 text-slate-600 uppercase font-semibold sticky top-0\">\n                        <!-- Dynamic Header -->\n                    <\/thead>\n                    <tbody id=\"table-body\" class=\"divide-y divide-slate-100 text-slate-700\">\n                        <!-- Dynamic Data Rows -->\n                    <\/tbody>\n                <\/table>\n            <\/div>\n        <\/div>\n    <\/main>\n\n    <script>\n        const sheetUrl = 'https:\/\/docs.google.com\/spreadsheets\/d\/10V8UFoifJIIqXryio9wNz1BuDrnf0HwdPwtm1yjMpq8\/gviz\/tq?tqx=out:json&gid=1700765753';\n        let rawDataStore = [];\n        let barChartInstance = null;\n        let doughnutChartInstance = null;\n\n        async function loadSheetData() {\n            const statusEl = document.getElementById('sync-status');\n            statusEl.innerHTML = `<span class=\"w-2 h-2 rounded-full bg-amber-400 animate-ping\"><\/span> \u0e01\u0e33\u0e25\u0e31\u0e07\u0e14\u0e36\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25...`;\n            \n            try {\n                \/\/ Using cors proxy or direct fetch if available, Google visualization API supports JSONP or raw text parsing\n                const response = await fetch(sheetUrl);\n                const text = await response.text();\n                \n                \/\/ Parse Google Visualization API JSON response format\n                const jsonString = text.substring(47, text.length - 2);\n                const json = JSON.parse(jsonString);\n                \n                const cols = json.table.cols.map(c => c ? c.label || c.id : '');\n                const rows = json.table.rows.map(r => r.c.map(cell => cell ? cell.v : ''));\n\n                rawDataStore = { cols, rows };\n                \n                renderDashboard(cols, rows);\n                statusEl.innerHTML = `<span class=\"w-2 h-2 rounded-full bg-emerald-400\"><\/span> \u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21\u0e15\u0e48\u0e2d\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08`;\n            } catch (error) {\n                console.error(\"Error loading sheet:\", error);\n                statusEl.innerHTML = `<span class=\"w-2 h-2 rounded-full bg-rose-400\"><\/span> \u0e42\u0e2b\u0e25\u0e14\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e44\u0e21\u0e48\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08 (\u0e25\u0e2d\u0e07\u0e43\u0e0a\u0e49\u0e42\u0e2b\u0e21\u0e14\u0e08\u0e33\u0e25\u0e2d\u0e07)`;\n                renderFallbackData();\n            }\n        }\n\n        function renderFallbackData() {\n            \/\/ Fallback sample data matching standard sheet structures\n            const cols = [\"\u0e25\u0e33\u0e14\u0e31\u0e1a\", \"\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\", \"\u0e2b\u0e21\u0e27\u0e14\u0e2b\u0e21\u0e39\u0e48\", \"\u0e27\u0e31\u0e19\u0e17\u0e35\u0e48\", \"\u0e08\u0e33\u0e19\u0e27\u0e19\u0e40\u0e07\u0e34\u0e19\"];\n            const rows = [\n                [1, \"\u0e04\u0e48\u0e32\u0e43\u0e0a\u0e49\u0e08\u0e48\u0e32\u0e22\u0e42\u0e04\u0e23\u0e07\u0e01\u0e32\u0e23 A\", \"\u0e01\u0e32\u0e23\u0e14\u0e33\u0e40\u0e19\u0e34\u0e19\u0e07\u0e32\u0e19\", \"2026-01-10\", 15000],\n                [2, \"\u0e07\u0e1a\u0e1b\u0e23\u0e30\u0e21\u0e32\u0e13\u0e08\u0e31\u0e14\u0e0b\u0e37\u0e49\u0e2d\u0e2d\u0e38\u0e1b\u0e01\u0e23\u0e13\u0e4c\", \"\u0e44\u0e2d\u0e17\u0e35\", \"2026-01-15\", 32000],\n                [3, \"\u0e04\u0e48\u0e32\u0e40\u0e14\u0e34\u0e19\u0e17\u0e32\u0e07\u0e1b\u0e23\u0e30\u0e0a\u0e38\u0e21\u0e17\u0e35\u0e21\", \"\u0e40\u0e14\u0e34\u0e19\u0e17\u0e32\u0e07\", \"2026-01-20\", 4500],\n                [4, \"\u0e04\u0e48\u0e32\u0e1a\u0e33\u0e23\u0e38\u0e07\u0e23\u0e31\u0e01\u0e29\u0e32\u0e23\u0e30\u0e1a\u0e1a\", \"\u0e44\u0e2d\u0e17\u0e35\", \"2026-01-25\", 12000],\n                [5, \"\u0e04\u0e48\u0e32\u0e01\u0e32\u0e23\u0e15\u0e25\u0e32\u0e14\u0e2d\u0e2d\u0e19\u0e44\u0e25\u0e19\u0e4c\", \"\u0e01\u0e32\u0e23\u0e15\u0e25\u0e32\u0e14\", \"2026-02-01\", 25000],\n                [6, \"\u0e04\u0e48\u0e32\u0e2d\u0e1a\u0e23\u0e21\u0e1e\u0e19\u0e31\u0e01\u0e07\u0e32\u0e19\", \"\u0e17\u0e23\u0e31\u0e1e\u0e22\u0e32\u0e01\u0e23\u0e1a\u0e38\u0e04\u0e04\u0e25\", \"2026-02-05\", 18000]\n            ];\n            rawDataStore = { cols, rows };\n            renderDashboard(cols, rows);\n        }\n\n        function renderDashboard(cols, rows) {\n            \/\/ Update Summary Cards\n            document.getElementById('stat-total-rows').innerText = rows.length.toLocaleString();\n            \n            \/\/ Find numeric columns for calculations\n            let numericColIdx = -1;\n            for (let i = 0; i < cols.length; i++) {\n                const isNumeric = rows.some(r => typeof r[i] === 'number');\n                if (isNumeric) {\n                    numericColIdx = i;\n                    break;\n                }\n            }\n\n            \/\/ Render Table\n            renderTable(cols, rows);\n\n            \/\/ Render Charts\n            let catColIdx = cols.findIndex((c, idx) => idx !== numericColIdx);\n            if (catColIdx === -1) catColIdx = 0;\n            renderCharts(cols, rows, numericColIdx, catColIdx);\n        }\n\n        function renderTable(cols, rows) {\n            const thead = document.getElementById('table-head');\n            const tbody = document.getElementById('table-body');\n\n            thead.innerHTML = `<tr>${cols.map(c => `<th class=\"px-4 py-3\">${c || '\u0e04\u0e2d\u0e25\u0e31\u0e21\u0e19\u0e4c'}<\/th>`).join('')}<\/tr>`;\n            tbody.innerHTML = rows.map(row => `\n                <tr class=\"hover:bg-slate-50\/80 transition\">\n                    ${row.map(cell => `<td class=\"px-4 py-2.5 border-b border-slate-50\">${cell !== null && cell !== undefined ? cell : '-'}<\/td>`).join('')}\n                <\/tr>\n            `).join('');\n        }\n\n        function filterTable() {\n            const query = document.getElementById('table-search').value.toLowerCase();\n            const filteredRows = rawDataStore.rows.filter(row => \n                row.some(cell => String(cell).toLowerCase().includes(query))\n            );\n            renderTable(rawDataStore.cols, filteredRows);\n        }\n\n        function renderCharts(cols, rows, numIdx, catIdx) {\n            const labels = rows.map((r, i) => String(r[catIdx] || `\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e17\u0e35\u0e48 ${i+1}`));\n            const dataValues = numIdx !== -1 ? rows.map(r => Number(r[numIdx]) || 0) : rows.map(() => 1);\n\n            \/\/ Limit chart items for readability if too many rows\n            const chartLabels = labels.slice(0, 10);\n            const chartData = dataValues.slice(0, 10);\n\n            \/\/ Bar Chart\n            const ctxBar = document.getElementById('barChart').getContext('2d');\n            if (barChartInstance) barChartInstance.destroy();\n            barChartInstance = new Chart(ctxBar, {\n                type: 'bar',\n                data: {\n                    labels: chartLabels,\n                    datasets: [{\n                        label: numIdx !== -1 ? cols[numIdx] : '\u0e08\u0e33\u0e19\u0e27\u0e19',\n                        data: chartData,\n                        backgroundColor: 'rgba(99, 102, 241, 0.8)',\n                        borderRadius: 6,\n                    }]\n                },\n                options: {\n                    responsive: true,\n                    maintainAspectRatio: false,\n                    plugins: { legend: { display: false } },\n                    scales: {\n                        y: { beginAtZero: true, grid: { color: '#f1f5f9' } },\n                        x: { grid: { display: false } }\n                    }\n                }\n            });\n\n            \/\/ Doughnut Chart\n            const ctxDoughnut = document.getElementById('doughnutChart').getContext('2d');\n            if (doughnutChartInstance) doughnutChartInstance.destroy();\n            doughnutChartInstance = new Chart(ctxDoughnut, {\n                type: 'doughnut',\n                data: {\n                    labels: chartLabels.slice(0, 5),\n                    datasets: [{\n                        data: chartData.slice(0, 5),\n                        backgroundColor: [\n                            '#6366f1', '#a855f7', '#ec4899', '#3b82f6', '#10b981'\n                        ],\n                        borderWidth: 0\n                    }]\n                },\n                options: {\n                    responsive: true,\n                    maintainAspectRatio: false,\n                    plugins: {\n                        legend: { position: 'bottom', labels: { boxWidth: 12, font: { family: 'Prompt' } } }\n                    }\n                }\n            });\n        }\n\n        \/\/ Initialize on load\n        window.onload = function() {\n            loadSheetData();\n        };\n    <\/script>\n<\/body>\n<\/html>\n\n\n\n<meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Dashboard \u0e27\u0e34\u0e40\u0e04\u0e23\u0e32\u0e30\u0e2b\u0e4c\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e08\u0e32\u0e01 Google Sheets<\/title>\n    <!-- Tailwind CSS -->\n    <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n    <!-- Chart.js for data visualization -->\n    <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/chart.js\"><\/script>\n    <!-- Font Awesome for icons -->\n    <link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/font-awesome\/6.4.0\/css\/all.min.css\">\n    <!-- Google Fonts Inter & Prompt -->\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Prompt:wght@300;400;500;600;700&amp;display=swap\" rel=\"stylesheet\">\n    <style>\n        body { font-family: 'Prompt', sans-serif; }\n    <\/style>\n\n\n\n    <header class=\"bg-indigo-600 text-white shadow-md\">\n        <div class=\"max-w-7xl mx-auto px-4 py-4 flex flex-col sm:flex-row justify-between items-center gap-4\">\n            <div class=\"flex items-center space-x-3\">\n                <div class=\"bg-white\/10 p-2.5 rounded-xl backdrop-blur-sm\">\n                    <i class=\"fa-solid fa-chart-pie text-2xl text-indigo-100\"><\/i>\n                <\/div>\n                <div>\n                    <h1 class=\"text-xl font-bold tracking-tight\">\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e1c\u0e39\u0e49\u0e1a\u0e23\u0e34\u0e2b\u0e32\u0e23\u0e2a\u0e16\u0e32\u0e19\u0e28\u0e36\u0e01\u0e29\u0e32 \u0e2a\u0e31\u0e07\u0e01\u0e31\u0e14 \u0e2a\u0e1e\u0e1b.\u0e41\u0e1e\u0e23\u0e48 \u0e40\u0e02\u0e15 1<\/h1>\n                    <p class=\"text-xs text-indigo-200\">\u0e27\u0e34\u0e40\u0e04\u0e23\u0e32\u0e30\u0e2b\u0e4c\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e08\u0e32\u0e01 Google Sheets \u0e2d\u0e31\u0e15\u0e42\u0e19\u0e21\u0e31\u0e15\u0e34<\/p>\n                <\/div>\n            <\/div>\n            <div class=\"flex items-center space-x-3 w-full sm:w-auto justify-end\">\n                <span id=\"sync-status\" class=\"text-xs bg-indigo-500\/50 text-indigo-100 px-3 py-1.5 rounded-full flex items-center gap-1.5\">\n                    <span class=\"w-2 h-2 rounded-full bg-emerald-400 animate-pulse\"><\/span>\n                    \u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21\u0e15\u0e48\u0e2d\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e41\u0e25\u0e49\u0e27\n                <\/span>\n                <button onclick=\"loadSheetData()\" class=\"bg-indigo-700 hover:bg-indigo-800 text-white text-xs px-4 py-2 rounded-lg font-medium transition shadow-sm flex items-center gap-1.5\">\n                    <i class=\"fa-solid fa-rotate\"><\/i> \u0e42\u0e2b\u0e25\u0e14\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e43\u0e2b\u0e21\u0e48\n                <\/button>\n            <\/div>\n        <\/div>\n    <\/header>\n\n    <main class=\"flex-1 max-w-7xl w-full mx-auto px-4 py-6 overflow-y-auto\">\n        <!-- Summary Stat Cards -->\n        <div class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-1 gap-4 mb-6\">\n            <div class=\"bg-white p-5 rounded-2xl shadow-sm border border-slate-100 flex items-center justify-between\">\n                <div>\n                    <p class=\"text-xs font-medium text-slate-400 uppercase tracking-wider\">\u0e08\u0e33\u0e19\u0e27\u0e19\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14<\/p>\n                    <h3 id=\"stat-total-rows\" class=\"text-2xl font-bold text-slate-700 mt-1\">0<\/h3>\n                <\/div>\n                <div class=\"w-12 h-12 rounded-xl bg-blue-50 text-blue-600 flex items-center justify-center text-xl\">\n                    <i class=\"fa-solid fa-database\"><\/i>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <!-- Charts Grid -->\n        <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6\">\n            <!-- Bar Chart Card -->\n            <div class=\"bg-white p-5 rounded-2xl shadow-sm border border-slate-100 flex flex-col\">\n                <div class=\"flex justify-between items-center mb-4\">\n                    <h4 class=\"font-semibold text-slate-800 text-sm flex items-center gap-2\">\n                        <i class=\"fa-solid fa-chart-column text-indigo-600\"><\/i> \u0e2a\u0e16\u0e34\u0e15\u0e34\u0e20\u0e32\u0e1e\u0e23\u0e27\u0e21\u0e15\u0e32\u0e21\u0e2b\u0e21\u0e27\u0e14\u0e2b\u0e21\u0e39\u0e48 \/ \u0e04\u0e2d\u0e25\u0e31\u0e21\u0e19\u0e4c\n                    <\/h4>\n                <\/div>\n                <div class=\"relative flex-1 min-h-[280px]\">\n                    <canvas id=\"barChart\"><\/canvas>\n                <\/div>\n            <\/div>\n            <!-- Doughnut Chart Card -->\n            <div class=\"bg-white p-5 rounded-2xl shadow-sm border border-slate-100 flex flex-col\">\n                <div class=\"flex justify-between items-center mb-4\">\n                    <h4 class=\"font-semibold text-slate-800 text-sm flex items-center gap-2\">\n                        <i class=\"fa-solid fa-chart-pie text-purple-600\"><\/i> \u0e2a\u0e31\u0e14\u0e2a\u0e48\u0e27\u0e19\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e40\u0e0a\u0e34\u0e07\u0e40\u0e1b\u0e23\u0e35\u0e22\u0e1a\u0e40\u0e17\u0e35\u0e22\u0e1a\n                    <\/h4>\n                <\/div>\n                <div class=\"relative flex-1 min-h-[280px] flex items-center justify-center\">\n                    <canvas id=\"doughnutChart\"><\/canvas>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <!-- Data Table Section -->\n        <div class=\"bg-white rounded-2xl shadow-sm border border-slate-100 overflow-hidden mb-8\">\n            <div class=\"p-5 border-b border-slate-100 flex flex-col sm:flex-row justify-between items-center gap-4\">\n                <h4 class=\"font-semibold text-slate-800 text-sm flex items-center gap-2\">\n                    <i class=\"fa-solid fa-table text-indigo-600\"><\/i> \u0e23\u0e32\u0e22\u0e25\u0e30\u0e40\u0e2d\u0e35\u0e22\u0e14\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e14\u0e34\u0e1a\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\n                <\/h4>\n                <div class=\"w-full sm:w-64\">\n                    <input type=\"text\" id=\"table-search\" placeholder=\"\u0e04\u0e49\u0e19\u0e2b\u0e32\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e43\u0e19\u0e15\u0e32\u0e23\u0e32\u0e07...\" oninput=\"filterTable()\" class=\"w-full px-3 py-1.5 text-xs bg-slate-50 border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500\">\n                <\/div>\n            <\/div>\n            <div class=\"overflow-x-auto max-h-96\">\n                <table class=\"w-full text-left border-collapse text-xs\">\n                    <thead id=\"table-head\" class=\"bg-slate-50 text-slate-600 uppercase font-semibold sticky top-0\">\n                        <!-- Dynamic Header -->\n                    <\/thead>\n                    <tbody id=\"table-body\" class=\"divide-y divide-slate-100 text-slate-700\">\n                        <!-- Dynamic Data Rows -->\n                    <\/tbody>\n                <\/table>\n            <\/div>\n        <\/div>\n    <\/main>\n\n    <script>\n        const sheetUrl = 'https:\/\/docs.google.com\/spreadsheets\/d\/10V8UFoifJIIqXryio9wNz1BuDrnf0HwdPwtm1yjMpq8\/gviz\/tq?tqx=out:json&gid=1700765753';\n        let rawDataStore = [];\n        let barChartInstance = null;\n        let doughnutChartInstance = null;\n\n        async function loadSheetData() {\n            const statusEl = document.getElementById('sync-status');\n            statusEl.innerHTML = `<span class=\"w-2 h-2 rounded-full bg-amber-400 animate-ping\"><\/span> \u0e01\u0e33\u0e25\u0e31\u0e07\u0e14\u0e36\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25...`;\n            \n            try {\n                \/\/ Using cors proxy or direct fetch if available, Google visualization API supports JSONP or raw text parsing\n                const response = await fetch(sheetUrl);\n                const text = await response.text();\n                \n                \/\/ Parse Google Visualization API JSON response format\n                const jsonString = text.substring(47, text.length - 2);\n                const json = JSON.parse(jsonString);\n                \n                const cols = json.table.cols.map(c => c ? c.label || c.id : '');\n                const rows = json.table.rows.map(r => r.c.map(cell => cell ? cell.v : ''));\n\n                rawDataStore = { cols, rows };\n                \n                renderDashboard(cols, rows);\n                statusEl.innerHTML = `<span class=\"w-2 h-2 rounded-full bg-emerald-400\"><\/span> \u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21\u0e15\u0e48\u0e2d\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08`;\n            } catch (error) {\n                console.error(\"Error loading sheet:\", error);\n                statusEl.innerHTML = `<span class=\"w-2 h-2 rounded-full bg-rose-400\"><\/span> \u0e42\u0e2b\u0e25\u0e14\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e44\u0e21\u0e48\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08 (\u0e25\u0e2d\u0e07\u0e43\u0e0a\u0e49\u0e42\u0e2b\u0e21\u0e14\u0e08\u0e33\u0e25\u0e2d\u0e07)`;\n                renderFallbackData();\n            }\n        }\n\n        function renderFallbackData() {\n            \/\/ Fallback sample data matching standard sheet structures\n            const cols = [\"\u0e25\u0e33\u0e14\u0e31\u0e1a\", \"\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\", \"\u0e2b\u0e21\u0e27\u0e14\u0e2b\u0e21\u0e39\u0e48\", \"\u0e27\u0e31\u0e19\u0e17\u0e35\u0e48\", \"\u0e08\u0e33\u0e19\u0e27\u0e19\u0e40\u0e07\u0e34\u0e19\"];\n            const rows = [\n                [1, \"\u0e04\u0e48\u0e32\u0e43\u0e0a\u0e49\u0e08\u0e48\u0e32\u0e22\u0e42\u0e04\u0e23\u0e07\u0e01\u0e32\u0e23 A\", \"\u0e01\u0e32\u0e23\u0e14\u0e33\u0e40\u0e19\u0e34\u0e19\u0e07\u0e32\u0e19\", \"2026-01-10\", 15000],\n                [2, \"\u0e07\u0e1a\u0e1b\u0e23\u0e30\u0e21\u0e32\u0e13\u0e08\u0e31\u0e14\u0e0b\u0e37\u0e49\u0e2d\u0e2d\u0e38\u0e1b\u0e01\u0e23\u0e13\u0e4c\", \"\u0e44\u0e2d\u0e17\u0e35\", \"2026-01-15\", 32000],\n                [3, \"\u0e04\u0e48\u0e32\u0e40\u0e14\u0e34\u0e19\u0e17\u0e32\u0e07\u0e1b\u0e23\u0e30\u0e0a\u0e38\u0e21\u0e17\u0e35\u0e21\", \"\u0e40\u0e14\u0e34\u0e19\u0e17\u0e32\u0e07\", \"2026-01-20\", 4500],\n                [4, \"\u0e04\u0e48\u0e32\u0e1a\u0e33\u0e23\u0e38\u0e07\u0e23\u0e31\u0e01\u0e29\u0e32\u0e23\u0e30\u0e1a\u0e1a\", \"\u0e44\u0e2d\u0e17\u0e35\", \"2026-01-25\", 12000],\n                [5, \"\u0e04\u0e48\u0e32\u0e01\u0e32\u0e23\u0e15\u0e25\u0e32\u0e14\u0e2d\u0e2d\u0e19\u0e44\u0e25\u0e19\u0e4c\", \"\u0e01\u0e32\u0e23\u0e15\u0e25\u0e32\u0e14\", \"2026-02-01\", 25000],\n                [6, \"\u0e04\u0e48\u0e32\u0e2d\u0e1a\u0e23\u0e21\u0e1e\u0e19\u0e31\u0e01\u0e07\u0e32\u0e19\", \"\u0e17\u0e23\u0e31\u0e1e\u0e22\u0e32\u0e01\u0e23\u0e1a\u0e38\u0e04\u0e04\u0e25\", \"2026-02-05\", 18000]\n            ];\n            rawDataStore = { cols, rows };\n            renderDashboard(cols, rows);\n        }\n\n        function renderDashboard(cols, rows) {\n            \/\/ Update Summary Cards\n            document.getElementById('stat-total-rows').innerText = rows.length.toLocaleString();\n            \n            \/\/ Find numeric columns for calculations\n            let numericColIdx = -1;\n            for (let i = 0; i < cols.length; i++) {\n                const isNumeric = rows.some(r => typeof r[i] === 'number');\n                if (isNumeric) {\n                    numericColIdx = i;\n                    break;\n                }\n            }\n\n            \/\/ Render Table\n            renderTable(cols, rows);\n\n            \/\/ Render Charts\n            let catColIdx = cols.findIndex((c, idx) => idx !== numericColIdx);\n            if (catColIdx === -1) catColIdx = 0;\n            renderCharts(cols, rows, numericColIdx, catColIdx);\n        }\n\n        function renderTable(cols, rows) {\n            const thead = document.getElementById('table-head');\n            const tbody = document.getElementById('table-body');\n\n            thead.innerHTML = `<tr>${cols.map(c => `<th class=\"px-4 py-3\">${c || '\u0e04\u0e2d\u0e25\u0e31\u0e21\u0e19\u0e4c'}<\/th>`).join('')}<\/tr>`;\n            tbody.innerHTML = rows.map(row => `\n                <tr class=\"hover:bg-slate-50\/80 transition\">\n                    ${row.map(cell => `<td class=\"px-4 py-2.5 border-b border-slate-50\">${cell !== null && cell !== undefined ? cell : '-'}<\/td>`).join('')}\n                <\/tr>\n            `).join('');\n        }\n\n        function filterTable() {\n            const query = document.getElementById('table-search').value.toLowerCase();\n            const filteredRows = rawDataStore.rows.filter(row => \n                row.some(cell => String(cell).toLowerCase().includes(query))\n            );\n            renderTable(rawDataStore.cols, filteredRows);\n        }\n\n        function renderCharts(cols, rows, numIdx, catIdx) {\n            const labels = rows.map((r, i) => String(r[catIdx] || `\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e17\u0e35\u0e48 ${i+1}`));\n            const dataValues = numIdx !== -1 ? rows.map(r => Number(r[numIdx]) || 0) : rows.map(() => 1);\n\n            \/\/ Limit chart items for readability if too many rows\n            const chartLabels = labels.slice(0, 10);\n            const chartData = dataValues.slice(0, 10);\n\n            \/\/ Bar Chart\n            const ctxBar = document.getElementById('barChart').getContext('2d');\n            if (barChartInstance) barChartInstance.destroy();\n            barChartInstance = new Chart(ctxBar, {\n                type: 'bar',\n                data: {\n                    labels: chartLabels,\n                    datasets: [{\n                        label: numIdx !== -1 ? cols[numIdx] : '\u0e08\u0e33\u0e19\u0e27\u0e19',\n                        data: chartData,\n                        backgroundColor: 'rgba(99, 102, 241, 0.8)',\n                        borderRadius: 6,\n                    }]\n                },\n                options: {\n                    responsive: true,\n                    maintainAspectRatio: false,\n                    plugins: { legend: { display: false } },\n                    scales: {\n                        y: { beginAtZero: true, grid: { color: '#f1f5f9' } },\n                        x: { grid: { display: false } }\n                    }\n                }\n            });\n\n            \/\/ Doughnut Chart\n            const ctxDoughnut = document.getElementById('doughnutChart').getContext('2d');\n            if (doughnutChartInstance) doughnutChartInstance.destroy();\n            doughnutChartInstance = new Chart(ctxDoughnut, {\n                type: 'doughnut',\n                data: {\n                    labels: chartLabels.slice(0, 5),\n                    datasets: [{\n                        data: chartData.slice(0, 5),\n                        backgroundColor: [\n                            '#6366f1', '#a855f7', '#ec4899', '#3b82f6', '#10b981'\n                        ],\n                        borderWidth: 0\n                    }]\n                },\n                options: {\n                    responsive: true,\n                    maintainAspectRatio: false,\n                    plugins: {\n                        legend: { position: 'bottom', labels: { boxWidth: 12, font: { family: 'Prompt' } } }\n                    }\n                }\n            });\n        }\n\n        \/\/ Initialize on load\n        window.onload = function() {\n            loadSheetData();\n        };\n    <\/script>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dashboard \u0e27\u0e34\u0e40\u0e04\u0e23\u0e32\u0e30\u0e2b\u0e4c\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e08\u0e32\u0e01 Google Sheets \u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e1c\u0e39\u0e49\u0e1a\u0e23\u0e34 &#8230; <a title=\"\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e1c\u0e39\u0e49\u0e1a\u0e23\u0e34\u0e2b\u0e32\u0e23\u0e2a\u0e16\u0e32\u0e19\u0e28\u0e36\u0e01\u0e29\u0e32\" class=\"read-more\" href=\"https:\/\/phrae1.go.th\/sites\/%e0%b8%82%e0%b9%89%e0%b8%ad%e0%b8%a1%e0%b8%b9%e0%b8%a5%e0%b8%9c%e0%b8%b9%e0%b9%89%e0%b8%9a%e0%b8%a3%e0%b8%b4%e0%b8%ab%e0%b8%b2%e0%b8%a3%e0%b8%aa%e0%b8%96%e0%b8%b2%e0%b8%99%e0%b8%a8%e0%b8%b6%e0%b8%81\/\" aria-label=\"Read more about \u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e1c\u0e39\u0e49\u0e1a\u0e23\u0e34\u0e2b\u0e32\u0e23\u0e2a\u0e16\u0e32\u0e19\u0e28\u0e36\u0e01\u0e29\u0e32\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[1],"tags":[],"class_list":["post-1285","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/phrae1.go.th\/sites\/wp-json\/wp\/v2\/posts\/1285","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/phrae1.go.th\/sites\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/phrae1.go.th\/sites\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/phrae1.go.th\/sites\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/phrae1.go.th\/sites\/wp-json\/wp\/v2\/comments?post=1285"}],"version-history":[{"count":1,"href":"https:\/\/phrae1.go.th\/sites\/wp-json\/wp\/v2\/posts\/1285\/revisions"}],"predecessor-version":[{"id":1286,"href":"https:\/\/phrae1.go.th\/sites\/wp-json\/wp\/v2\/posts\/1285\/revisions\/1286"}],"wp:attachment":[{"href":"https:\/\/phrae1.go.th\/sites\/wp-json\/wp\/v2\/media?parent=1285"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/phrae1.go.th\/sites\/wp-json\/wp\/v2\/categories?post=1285"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/phrae1.go.th\/sites\/wp-json\/wp\/v2\/tags?post=1285"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}