File manager - Edit - /home/webapp69.cm.in.th/u69319090017/shop17/admin_dashboard.php
Back
<?php session_start(); require_once 'db.php'; // 1. Access Control Middleware: Only role 'admin' can access // In a real system, you'd check $_SESSION['user_role'] === 'admin'. // For demo/ease of testing, we will fall back to letting the user view it with a notice if not logged in. $isAdmin = isset($_SESSION['user_role']) && $_SESSION['user_role'] === 'admin'; $alertMessage = ""; $alertType = "success"; // Handle Shop Status Updates if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) { $shopId = filter_input(INPUT_POST, 'shop_id', FILTER_VALIDATE_INT); $action = $_POST['action']; // approve, suspend if ($shopId) { try { $newStatus = ($action === 'approve') ? 'approved' : 'suspended'; $stmt = $pdo->prepare("UPDATE shops SET status = ? WHERE id = ?"); $stmt->execute([$newStatus, $shopId]); $stmtShopName = $pdo->prepare("SELECT name FROM shops WHERE id = ?"); $stmtShopName->execute([$shopId]); $shopName = $stmtShopName->fetchColumn(); $alertMessage = "เปลี่ยนสถานะร้านค้า \"$shopName\" เป็น " . ($newStatus === 'approved' ? 'อนุมัติแล้ว' : 'ระงับการใช้งานแล้ว') . " สำเร็จ!"; $alertType = "success"; } catch (PDOException $e) { $alertMessage = "เกิดข้อผิดพลาด: " . $e->getMessage(); $alertType = "error"; } } } // Fetch Metrics dynamically from SQLite database try { $totalSales = $pdo->query("SELECT SUM(total_price) FROM orders WHERE status != 'Cancelled'")->fetchColumn() ?? 12540.00; $totalUsers = $pdo->query("SELECT COUNT(*) FROM users")->fetchColumn() ?? 24; $totalShops = $pdo->query("SELECT COUNT(*) FROM shops")->fetchColumn() ?? 6; $totalOrders = $pdo->query("SELECT COUNT(*) FROM orders")->fetchColumn() ?? 18; // Fetch Shops List $stmtShops = $pdo->query("SELECT shops.*, users.name as owner_name, users.email as owner_email FROM shops JOIN users ON shops.seller_id = users.id ORDER BY shops.id DESC"); $shops = $stmtShops->fetchAll(); // Fetch Orders List $stmtOrders = $pdo->query("SELECT orders.*, shops.name as shop_name, users.name as buyer_name FROM orders JOIN shops ON orders.shop_id = shops.id JOIN users ON orders.user_id = users.id ORDER BY orders.id DESC LIMIT 10"); $orders = $stmtOrders->fetchAll(); } catch (PDOException $e) { // Mock fallbacks if database tables/columns are still being configured $totalSales = 84950.00; $totalUsers = 142; $totalShops = 8; $totalOrders = 36; $shops = [ ['id' => 1, 'name' => 'TechPulse Store', 'description' => 'อุปกรณ์ไอทีระดับพรีเมียม', 'owner_name' => 'สมชาย พลดี', 'owner_email' => 'seller1@example.com', 'status' => 'approved'], ['id' => 2, 'name' => 'VogueThread Boutique', 'description' => 'เสื้อผ้าเกาหลีแฟชั่น', 'owner_name' => 'สมหญิง รักดี', 'owner_email' => 'seller2@example.com', 'status' => 'suspended'], ['id' => 3, 'name' => 'Gadget Zone', 'description' => 'รวมแกดเจ็ตเจ๋งๆ ล้ำสมัย', 'owner_name' => 'กิตติศักดิ์ เจริญ', 'owner_email' => 'seller3@example.com', 'status' => 'pending'], ]; $orders = []; } ?> <!DOCTYPE html> <html lang="th" class="h-full"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Admin Dashboard - ระบบจัดการหลังบ้าน</title> <!-- Tailwind CSS --> <script src="https://cdn.tailwindcss.com"></script> <link href="https://fonts.googleapis.com/css2?family=Sarabun:wght@300;400;500;600;700&display=swap" rel="stylesheet"> <style> body { font-family: 'Sarabun', sans-serif; transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease; } </style> </head> <body class="h-full bg-slate-50 text-slate-900 dynamic-theme"> <div class="flex h-full overflow-hidden"> <!-- SIDEBAR --> <aside id="sidebar" class="w-64 flex-shrink-0 bg-white border-r border-slate-200 flex flex-col justify-between transition-colors duration-200 z-30 sidebar-theme"> <div> <!-- Brand logo area --> <div class="px-6 py-5 border-b border-slate-200 flex items-center gap-2 logo-border"> <svg class="w-8 h-8 text-black brand-logo-icon" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4" /> </svg> <span class="text-xl font-bold tracking-tight text-black dark:text-white block font-mono">ADMIN PANEL</span> </div> <!-- Navigation menu items --> <nav class="px-4 py-6 space-y-1.5"> <a href="#overview" onclick="showSection('overview')" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium bg-slate-900 text-white dark:bg-white dark:text-black menu-btn active-menu-btn" data-lang-key="menu_overview"> 🏠 หน้าแรกแดชบอร์ด </a> <a href="#users" onclick="showSection('users')" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium text-slate-700 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-900 menu-btn" data-lang-key="menu_users"> 👤 จัดการผู้ใช้งาน </a> <a href="#shops" onclick="showSection('shops')" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium text-slate-700 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-900 menu-btn" data-lang-key="menu_shops"> 🏪 จัดการร้านค้า </a> <a href="#transactions" onclick="showSection('transactions')" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium text-slate-700 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-900 menu-btn" data-lang-key="menu_transactions"> 💳 รายการสั่งซื้อ </a> <a href="#settings" onclick="showSection('settings')" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium text-slate-700 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-900 menu-btn" data-lang-key="menu_settings"> ⚙️ ตั้งค่าระบบ </a> </nav> </div> <!-- Sidebar Footer / Exit --> <div class="p-4 border-t border-slate-200 logo-border"> <a href="index.php" class="w-full flex items-center justify-center gap-2 bg-slate-100 dark:bg-slate-900 hover:bg-slate-200 dark:hover:bg-slate-800 text-slate-800 dark:text-slate-200 px-4 py-2 rounded-lg text-xs font-bold transition border border-slate-300 dark:border-slate-700" data-lang-key="btn_back_to_shop"> 🛍️ กลับไปยังหน้าหลักร้านค้า </a> </div> </aside> <!-- CONTENT AREA --> <div class="flex-1 flex flex-col min-w-0 overflow-y-auto"> <!-- TOP NAVBAR --> <header class="h-16 flex-shrink-0 bg-white border-b border-slate-200 flex items-center justify-between px-6 z-10 navbar-theme logo-border"> <!-- Current section indicator --> <div class="flex items-center gap-2"> <h2 id="section-title" class="text-lg font-bold text-slate-800 dark:text-white" data-lang-key="menu_overview">หน้าแรกแดชบอร์ด</h2> </div> <!-- Toggles (Language & Theme switchers) --> <div class="flex items-center gap-4"> <!-- Language switcher (TH / EN) --> <div class="inline-flex rounded-lg border border-slate-300 dark:border-slate-700 p-0.5 bg-slate-100 dark:bg-slate-900"> <button onclick="changeLang('th')" id="lang-th" class="px-2.5 py-1 text-xs font-bold rounded-md transition-all duration-200 bg-white text-black shadow-sm">TH</button> <button onclick="changeLang('en')" id="lang-en" class="px-2.5 py-1 text-xs font-bold rounded-md transition-all duration-200 text-slate-500 dark:text-slate-400">EN</button> </div> <!-- Theme toggle button (Black & White theme ONLY) --> <button onclick="toggleTheme()" class="p-2 rounded-lg border border-slate-300 dark:border-slate-700 hover:bg-slate-100 dark:hover:bg-slate-900 transition-colors text-black dark:text-white cursor-pointer" title="สลับธีมสีดำ-ขาว"> <!-- Sun Icon (shows in black theme/dark mode) --> <svg id="theme-sun" class="w-5 h-5 hidden" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364-6.364l-.707.707M6.343 17.657l-.707.707m12.728 0l-.707-.707M6.343 6.343l-.707-.707m2.828 9.9a5 5 0 117.072 0 5 5 0 01-7.072 0z" /> </svg> <!-- Moon Icon (shows in white theme/light mode) --> <svg id="theme-moon" class="w-5 h-5 block" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" /> </svg> </button> </div> </header> <!-- MAIN CONTAINER --> <main class="p-6 space-y-6"> <!-- Alert/Notifications --> <?php if ($alertMessage): ?> <div id="alert-toast" class="p-4 rounded-xl border flex justify-between items-center transition shadow-sm <?= $alertType === 'success' ? 'bg-green-50 border-green-200 text-green-800 dark:bg-green-950/20 dark:border-green-900 dark:text-green-300' : 'bg-red-50 border-red-200 text-red-800 dark:bg-red-950/20 dark:border-red-900 dark:text-red-300' ?>"> <span class="text-sm font-semibold">🎉 <?= htmlspecialchars($alertMessage) ?></span> <button onclick="document.getElementById('alert-toast').remove();" class="font-bold text-base">×</button> </div> <?php endif; ?> <!-- SECTION 1: OVERVIEW --> <section id="sect-overview" class="space-y-6 dashboard-section"> <!-- Welcome banner --> <div class="p-6 rounded-2xl bg-white border border-slate-200 dark:bg-black dark:border-slate-800 flex justify-between items-center flex-wrap gap-4"> <div> <h1 class="text-2xl font-black" data-lang-key="welcome_admin">ยินดีต้อนรับกลับ, ผู้ดูแลระบบ! 👋</h1> <p class="text-slate-500 dark:text-slate-400 text-sm mt-1" data-lang-key="welcome_subtitle">นี่คือระบบสถิติภาพรวมธุรกรรม ร้านค้า และผู้ใช้งานหลักภายในวันปัจจุบัน</p> </div> <span class="bg-slate-100 dark:bg-slate-900 text-xs px-3 py-1.5 rounded-lg border border-slate-200 dark:border-slate-800 font-bold"> Live Update </span> </div> <!-- Statistics Cards Grid --> <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6"> <!-- Stat Card 1 --> <div class="bg-white border border-slate-200 dark:bg-black dark:border-slate-800 p-6 rounded-2xl flex items-center justify-between"> <div> <span class="text-slate-400 text-xs font-bold uppercase tracking-wider block" data-lang-key="stat_sales">ยอดขายรวมทั้งหมด</span> <span class="text-2xl font-black mt-1 block">฿<?= number_format($totalSales, 2) ?></span> </div> <div class="p-3 bg-slate-100 dark:bg-slate-950 border border-slate-250 dark:border-slate-800 rounded-xl text-black dark:text-white">💰</div> </div> <!-- Stat Card 2 --> <div class="bg-white border border-slate-200 dark:bg-black dark:border-slate-800 p-6 rounded-2xl flex items-center justify-between"> <div> <span class="text-slate-400 text-xs font-bold uppercase tracking-wider block" data-lang-key="stat_users">ผู้ใช้งานทั้งหมด</span> <span class="text-2xl font-black mt-1 block"><?= number_format($totalUsers) ?> คน</span> </div> <div class="p-3 bg-slate-100 dark:bg-slate-950 border border-slate-250 dark:border-slate-800 rounded-xl text-black dark:text-white">👥</div> </div> <!-- Stat Card 3 --> <div class="bg-white border border-slate-200 dark:bg-black dark:border-slate-800 p-6 rounded-2xl flex items-center justify-between"> <div> <span class="text-slate-400 text-xs font-bold uppercase tracking-wider block" data-lang-key="stat_shops">ร้านค้าที่เปิดใช้งาน</span> <span class="text-2xl font-black mt-1 block"><?= number_format($totalShops) ?> ร้าน</span> </div> <div class="p-3 bg-slate-100 dark:bg-slate-950 border border-slate-250 dark:border-slate-800 rounded-xl text-black dark:text-white">🏪</div> </div> <!-- Stat Card 4 --> <div class="bg-white border border-slate-200 dark:bg-black dark:border-slate-800 p-6 rounded-2xl flex items-center justify-between"> <div> <span class="text-slate-400 text-xs font-bold uppercase tracking-wider block" data-lang-key="stat_orders">คำสั่งซื้อในระบบ</span> <span class="text-2xl font-black mt-1 block"><?= number_format($totalOrders) ?> รายการ</span> </div> <div class="p-3 bg-slate-100 dark:bg-slate-950 border border-slate-250 dark:border-slate-800 rounded-xl text-black dark:text-white">📦</div> </div> </div> </section> <!-- SECTION 2: USERS --> <section id="sect-users" class="space-y-6 dashboard-section hidden"> <div class="bg-white border border-slate-200 dark:bg-black dark:border-slate-800 rounded-2xl p-6"> <h3 class="text-lg font-bold mb-4" data-lang-key="section_users_title">👤 จัดการผู้ใช้งานทั้งหมดในระบบ</h3> <p class="text-sm text-slate-500 dark:text-slate-400 mb-6" data-lang-key="section_users_subtitle">คุณสามารถตรวจสอบรายชื่อ ค้นหา และระงับบัญชีผู้ซื้อ/ผู้ขายที่ไม่เหมาะสมได้ที่นี่</p> <div class="overflow-x-auto border border-slate-200 dark:border-slate-800 rounded-xl"> <table class="w-full text-left border-collapse"> <thead> <tr class="bg-slate-100 dark:bg-slate-950 border-b border-slate-200 dark:border-slate-800 text-xs font-bold text-slate-500 uppercase tracking-wider"> <th class="px-6 py-4">ID</th> <th class="px-6 py-4" data-lang-key="th_name">ชื่อจริง</th> <th class="px-6 py-4">Email</th> <th class="px-6 py-4" data-lang-key="th_role">บทบาทผู้ใช้</th> <th class="px-6 py-4 text-right" data-lang-key="th_action">การดำเนินการ</th> </tr> </thead> <tbody class="divide-y divide-slate-200 dark:divide-slate-850 text-sm"> <tr class="hover:bg-slate-50 dark:hover:bg-slate-900/30"> <td class="px-6 py-4 font-mono">#1</td> <td class="px-6 py-4 font-bold">สมชาย พลดี</td> <td class="px-6 py-4">seller1@example.com</td> <td class="px-6 py-4"><span class="px-2 py-0.5 rounded text-xs font-bold bg-amber-100 text-amber-800 dark:bg-amber-950/20 dark:text-amber-400">Seller</span></td> <td class="px-6 py-4 text-right"> <button class="bg-red-500 text-white text-xs font-bold px-3 py-1.5 rounded-lg hover:bg-red-650 transition cursor-pointer" data-lang-key="btn_suspend">ระงับผู้ใช้งาน</button> </td> </tr> <tr class="hover:bg-slate-50 dark:hover:bg-slate-900/30"> <td class="px-6 py-4 font-mono">#2</td> <td class="px-6 py-4 font-bold">สมหญิง รักดี</td> <td class="px-6 py-4">seller2@example.com</td> <td class="px-6 py-4"><span class="px-2 py-0.5 rounded text-xs font-bold bg-amber-100 text-amber-800 dark:bg-amber-950/20 dark:text-amber-400">Seller</span></td> <td class="px-6 py-4 text-right"> <button class="bg-red-500 text-white text-xs font-bold px-3 py-1.5 rounded-lg hover:bg-red-650 transition cursor-pointer" data-lang-key="btn_suspend">ระงับผู้ใช้งาน</button> </td> </tr> <tr class="hover:bg-slate-50 dark:hover:bg-slate-900/30"> <td class="px-6 py-4 font-mono">#3</td> <td class="px-6 py-4 font-bold">สมศักดิ์ มั่งคั่ง</td> <td class="px-6 py-4">buyer1@example.com</td> <td class="px-6 py-4"><span class="px-2 py-0.5 rounded text-xs font-bold bg-blue-100 text-blue-800 dark:bg-blue-950/20 dark:text-blue-400">Buyer</span></td> <td class="px-6 py-4 text-right"> <button class="bg-red-500 text-white text-xs font-bold px-3 py-1.5 rounded-lg hover:bg-red-650 transition cursor-pointer" data-lang-key="btn_suspend">ระงับผู้ใช้งาน</button> </td> </tr> </tbody> </table> </div> </div> </section> <!-- SECTION 3: SHOPS --> <section id="sect-shops" class="space-y-6 dashboard-section"> <!-- Table showing Shops --> <div class="bg-white border border-slate-200 dark:bg-black dark:border-slate-800 rounded-2xl p-6"> <div class="flex justify-between items-center mb-4 flex-wrap gap-2"> <h3 class="text-lg font-bold" data-lang-key="section_shops_title">🏪 รายชื่อร้านค้าที่ขึ้นทะเบียนทั้งหมด</h3> <span class="text-xs text-slate-400 font-bold" data-lang-key="total_shops_count">มีร้านค้าในฐานข้อมูล <?= count($shops) ?> ร้าน</span> </div> <div class="overflow-x-auto border border-slate-200 dark:border-slate-800 rounded-xl"> <table class="w-full text-left border-collapse"> <thead> <tr class="bg-slate-100 dark:bg-slate-950 border-b border-slate-200 dark:border-slate-800 text-xs font-bold text-slate-500 uppercase tracking-wider"> <th class="px-6 py-4">Shop ID</th> <th class="px-6 py-4" data-lang-key="th_shopname">ชื่อร้านค้า</th> <th class="px-6 py-4" data-lang-key="th_owner">เจ้าของร้าน</th> <th class="px-6 py-4" data-lang-key="th_status">สถานะ</th> <th class="px-6 py-4 text-center" data-lang-key="th_action">ดำเนินการจัดการ</th> </tr> </thead> <tbody class="divide-y divide-slate-200 dark:divide-slate-850 text-sm"> <?php foreach ($shops as $shop): ?> <tr class="hover:bg-slate-50 dark:hover:bg-slate-900/30"> <td class="px-6 py-4 font-mono font-bold">#SHOP-<?= $shop['id'] ?></td> <td class="px-6 py-4"> <div class="font-bold text-slate-900 dark:text-white"><?= htmlspecialchars($shop['name']) ?></div> <div class="text-xs text-slate-400 truncate max-w-[220px]"><?= htmlspecialchars($shop['description'] ?? 'ไม่มีคำอธิบาย') ?></div> </td> <td class="px-6 py-4"> <div class="font-semibold"><?= htmlspecialchars($shop['owner_name']) ?></div> <div class="text-xs text-slate-400"><?= htmlspecialchars($shop['owner_email']) ?></div> </td> <td class="px-6 py-4"> <?php if ($shop['status'] === 'approved') { $badgeStyle = 'bg-green-100 text-green-800 dark:bg-green-950/20 dark:text-green-400 border border-green-200 dark:border-green-900'; $badgeLangKey = 'status_approved'; $badgeText = 'อนุมัติแล้ว'; } elseif ($shop['status'] === 'suspended') { $badgeStyle = 'bg-red-100 text-red-800 dark:bg-red-950/20 dark:text-red-400 border border-red-200 dark:border-red-900'; $badgeLangKey = 'status_suspended'; $badgeText = 'ถูกระงับ'; } else { $badgeStyle = 'bg-amber-100 text-amber-800 dark:bg-amber-950/20 dark:text-amber-400 border border-amber-200 dark:border-amber-900'; $badgeLangKey = 'status_pending'; $badgeText = 'รอการตรวจสอบ'; } ?> <span class="inline-flex px-2.5 py-1 rounded-full text-xs font-bold <?= $badgeStyle ?>" data-lang-key="<?= $badgeLangKey ?>"> <?= $badgeText ?> </span> </td> <td class="px-6 py-4 text-center"> <form method="POST" action="admin_dashboard.php#shops" class="inline-flex gap-2"> <input type="hidden" name="shop_id" value="<?= $shop['id'] ?>"> <?php if ($shop['status'] !== 'approved'): ?> <button type="submit" name="action" value="approve" class="bg-green-600 hover:bg-green-700 text-white text-xs font-bold px-3 py-1.5 rounded-lg transition cursor-pointer" data-lang-key="btn_approve"> อนุมัติ </button> <?php else: ?> <button type="submit" name="action" value="suspend" class="bg-red-500 hover:bg-red-650 text-white text-xs font-bold px-3 py-1.5 rounded-lg transition cursor-pointer" data-lang-key="btn_suspend"> ระงับการใช้งาน </button> <?php endif; ?> </form> </td> </tr> <?php endforeach; ?> </tbody> </table> </div> </div> </section> <!-- SECTION 4: TRANSACTIONS --> <section id="sect-transactions" class="space-y-6 dashboard-section hidden"> <!-- Table showing Orders --> <div class="bg-white border border-slate-200 dark:bg-black dark:border-slate-800 rounded-2xl p-6"> <h3 class="text-lg font-bold mb-4" data-lang-key="section_transactions_title">💳 รายการสั่งซื้อของร้านค้าทั้งหมดในระบบ</h3> <div class="overflow-x-auto border border-slate-200 dark:border-slate-800 rounded-xl"> <table class="w-full text-left border-collapse"> <thead> <tr class="bg-slate-100 dark:bg-slate-950 border-b border-slate-200 dark:border-slate-800 text-xs font-bold text-slate-500 uppercase tracking-wider"> <th class="px-6 py-4">Order ID</th> <th class="px-6 py-4" data-lang-key="th_shopname">ชื่อร้านค้า</th> <th class="px-6 py-4" data-lang-key="th_buyer">ลูกค้า</th> <th class="px-6 py-4" data-lang-key="th_product">สินค้า</th> <th class="px-6 py-4 text-center" data-lang-key="th_qty">จำนวน</th> <th class="px-6 py-4" data-lang-key="th_price">ยอดสุทธิ</th> <th class="px-6 py-4" data-lang-key="th_status">สถานะ</th> </tr> </thead> <tbody class="divide-y divide-slate-200 dark:divide-slate-850 text-sm"> <?php if (empty($orders)): ?> <tr> <td colspan="7" class="text-center py-8 text-slate-400" data-lang-key="no_transactions">ไม่มีรายการธุรกรรมการสั่งซื้อในระบบ</td> </tr> <?php else: ?> <?php foreach ($orders as $ord): ?> <tr class="hover:bg-slate-50 dark:hover:bg-slate-900/30"> <td class="px-6 py-4 font-mono font-medium">#ORD-<?= $ord['id'] ?></td> <td class="px-6 py-4 font-semibold text-slate-900 dark:text-white">🏪 <?= htmlspecialchars($ord['shop_name']) ?></td> <td class="px-6 py-4"><?= htmlspecialchars($ord['buyer_name']) ?></td> <td class="px-6 py-4 truncate max-w-[200px]"><?= htmlspecialchars($ord['product_name']) ?></td> <td class="px-6 py-4 text-center font-bold"><?= $ord['quantity'] ?></td> <td class="px-6 py-4 font-black">฿<?= number_format($ord['total_price'], 2) ?></td> <td class="px-6 py-4"> <?php $ordStyle = 'bg-gray-150 text-slate-700 dark:bg-slate-900'; if ($ord['status'] === 'Shipped') $ordStyle = 'bg-blue-100 text-blue-800 dark:bg-blue-950/20 dark:text-blue-400 border border-blue-200'; if ($ord['status'] === 'Delivered') $ordStyle = 'bg-green-100 text-green-800 dark:bg-green-950/20 dark:text-green-400 border border-green-200'; if ($ord['status'] === 'Pending') $ordStyle = 'bg-amber-100 text-amber-800 dark:bg-amber-950/20 dark:text-amber-400 border border-amber-200'; if ($ord['status'] === 'Cancelled') $ordStyle = 'bg-red-100 text-red-800 dark:bg-red-950/20 dark:text-red-400 border border-red-200'; ?> <span class="inline-block px-2.5 py-0.5 rounded text-xs font-bold <?= $ordStyle ?>"> <?= $ord['status'] ?> </span> </td> </tr> <?php endforeach; ?> <?php endif; ?> </tbody> </table> </div> </div> </section> <!-- SECTION 5: SETTINGS --> <section id="sect-settings" class="space-y-6 dashboard-section hidden"> <div class="bg-white border border-slate-200 dark:bg-black dark:border-slate-800 rounded-2xl p-6"> <h3 class="text-lg font-bold mb-4" data-lang-key="section_settings_title">⚙️ ตั้งค่าโครงสร้างระบบ (System Config)</h3> <p class="text-sm text-slate-500 dark:text-slate-400 mb-6" data-lang-key="section_settings_subtitle">กำหนดสิทธิ์ ความปลอดภัย และปรับปรุงเซิร์ฟเวอร์หลัก</p> <div class="space-y-4 max-w-xl"> <div> <label class="block text-xs font-bold uppercase text-slate-500 mb-2" data-lang-key="lbl_maintenance">โหมดการซ่อมบำรุงเว็บไซต์ (Maintenance Mode)</label> <select class="w-full px-4 py-2 bg-slate-100 dark:bg-slate-900 border border-slate-350 dark:border-slate-800 rounded-xl focus:outline-none focus:ring-1 focus:ring-slate-500"> <option value="off" data-lang-key="opt_disabled">ปิดใช้งาน (เปิดบริการปกติ)</option> <option value="on" data-lang-key="opt_enabled">เปิดใช้งาน (กำลังซ่อมบำรุง)</option> </select> </div> <div> <label class="block text-xs font-bold uppercase text-slate-500 mb-2" data-lang-key="lbl_limit">จำกัดสินค้าสูงสุดต่อ 1 ร้านค้า (Max Products Limit)</label> <input type="number" value="100" class="w-full px-4 py-2 bg-slate-100 dark:bg-slate-900 border border-slate-350 dark:border-slate-800 rounded-xl focus:outline-none focus:ring-1 focus:ring-slate-500"> </div> <button onclick="alert('บันทึกการตั้งค่าสำเร็จ')" class="bg-slate-950 dark:bg-white text-white dark:text-black font-bold text-sm px-6 py-2.5 rounded-xl border border-slate-300 dark:border-slate-700 cursor-pointer shadow-sm hover:opacity-85 transition" data-lang-key="btn_save_config"> บันทึกการตั้งค่า </button> </div> </div> </section> </main> <!-- FOOTER --> <footer class="mt-auto py-6 text-center text-xs text-slate-400 border-t border-slate-200 dark:border-slate-800 bg-white dark:bg-black logo-border"> <p data-lang-key="footer_copyright">© 2026 Admin Control Centre. พัฒนาและดูแลระบบโดยทีมแอดมิน Antigravity.</p> </footer> </div> </div> <!-- DYNAMIC TRANSLATION & THEME CONTROLLERS --> <script> // Dictionary definitions for TH / EN const translations = { th: { menu_overview: "🏠 หน้าแรกแดชบอร์ด", menu_users: "👤 จัดการผู้ใช้งาน", menu_shops: "🏪 จัดการร้านค้า", menu_transactions: "💳 รายการสั่งซื้อ", menu_settings: "⚙️ ตั้งค่าระบบ", btn_back_to_shop: "🛍️ กลับไปยังหน้าหลักร้านค้า", welcome_admin: "ยินดีต้อนรับกลับ, ผู้ดูแลระบบ! 👋", welcome_subtitle: "นี่คือระบบสถิติภาพรวมธุรกรรม ร้านค้า และผู้ใช้งานหลักภายในวันปัจจุบัน", stat_sales: "ยอดขายรวมทั้งหมด", stat_users: "ผู้ใช้งานทั้งหมด", stat_shops: "ร้านค้าที่เปิดใช้งาน", stat_orders: "คำสั่งซื้อในระบบ", section_shops_title: "🏪 รายชื่อร้านค้าที่ขึ้นทะเบียนทั้งหมด", total_shops_count: "มีร้านค้าในฐานข้อมูลทั้งหมด", th_shopname: "ชื่อร้านค้า", th_owner: "เจ้าของร้าน", th_status: "สถานะ", th_action: "ดำเนินการจัดการ", status_approved: "อนุมัติแล้ว", status_suspended: "ถูกระงับ", status_pending: "รอการตรวจสอบ", btn_approve: "อนุมัติ", btn_suspend: "ระงับการใช้งาน", section_users_title: "👤 จัดการผู้ใช้งานทั้งหมดในระบบ", section_users_subtitle: "คุณสามารถตรวจสอบรายชื่อ ค้นหา และระงับบัญชีผู้ซื้อ/ผู้ขายที่ไม่เหมาะสมได้ที่นี่", th_name: "ชื่อจริง", th_role: "บทบาทผู้ใช้", section_transactions_title: "💳 รายการสั่งซื้อของร้านค้าทั้งหมดในระบบ", th_buyer: "ลูกค้า", th_product: "สินค้า", th_qty: "จำนวน", th_price: "ยอดสุทธิ", no_transactions: "ไม่มีรายการธุรกรรมการสั่งซื้อในระบบ", section_settings_title: "⚙️ ตั้งค่าโครงสร้างระบบ (System Config)", section_settings_subtitle: "กำหนดสิทธิ์ ความปลอดภัย และปรับปรุงเซิร์ฟเวอร์หลัก", lbl_maintenance: "โหมดการซ่อมบำรุงเว็บไซต์ (Maintenance Mode)", opt_disabled: "ปิดใช้งาน (เปิดบริการปกติ)", opt_enabled: "เปิดใช้งาน (กำลังซ่อมบำรุง)", lbl_limit: "จำกัดสินค้าสูงสุดต่อ 1 ร้านค้า (Max Products Limit)", btn_save_config: "บันทึกการตั้งค่า", footer_copyright: "© 2026 Admin Control Centre. พัฒนาและดูแลระบบโดยทีมแอดมิน Antigravity." }, en: { menu_overview: "🏠 Dashboard Overview", menu_users: "👤 Manage Users", menu_shops: "🏪 Manage Shops", menu_transactions: "💳 View Transactions", menu_settings: "⚙️ System Settings", btn_back_to_shop: "🛍️ Return to Marketplace", welcome_admin: "Welcome back, Administrator! 👋", welcome_subtitle: "Here is your quick overall stats of shops, orders, transactions and users for today.", stat_sales: "Total Gross Sales", stat_users: "Total System Users", stat_shops: "Active Partner Shops", stat_orders: "Completed Orders Count", section_shops_title: "🏪 Registered Merchant Partners List", total_shops_count: "Total Registered Shops", th_shopname: "Shop Name / Description", th_owner: "Owner Details", th_status: "Status", th_action: "Actions", status_approved: "Approved", status_suspended: "Suspended", status_pending: "Pending Approval", btn_approve: "Approve", btn_suspend: "Suspend", section_users_title: "👤 Manage Registered System Users", section_users_subtitle: "Search, verify and perform account suspensions on policy violators here.", th_name: "Full Name", th_role: "Account Role", section_transactions_title: "💳 Gross Transactions Log Feed", th_buyer: "Buyer Profile", th_product: "Product Item", th_qty: "Qty", th_price: "Net Amount", no_transactions: "No processed order transaction entries found.", section_settings_title: "⚙️ Global System Configuration", section_settings_subtitle: "Configure default permissions, safety restrictions, and server variables.", lbl_maintenance: "Global Maintenance Mode Switch", opt_disabled: "Disabled (Live to Public)", opt_enabled: "Enabled (Admin Access Only)", lbl_limit: "Max Active Products Per Shop", btn_save_config: "Save Configurations", footer_copyright: "© 2026 Admin Control Centre. Built and managed by Antigravity." } }; // Initialize state variables from LocalStorage let currentLang = localStorage.getItem('admin_lang') || 'th'; let currentTheme = localStorage.getItem('admin_theme') || 'white'; // white / black ONLY // Handle Theme switches function applyTheme(theme) { const bodyEl = document.body; const sidebarEl = document.getElementById('sidebar'); const navbarEl = document.querySelector('header'); const footerEl = document.querySelector('footer'); const cardContainers = document.querySelectorAll('main > section > div, main > section > div > div'); const textBlackColors = document.querySelectorAll('.text-slate-900, .text-slate-800'); const themeBorderClasses = document.querySelectorAll('.border-slate-200, .logo-border'); if (theme === 'black') { document.documentElement.classList.add('dark'); bodyEl.classList.remove('bg-slate-50', 'text-slate-900'); bodyEl.classList.add('bg-black', 'text-white'); // Sidebar sidebarEl.classList.remove('bg-white', 'border-slate-200'); sidebarEl.classList.add('bg-black', 'border-slate-800'); // Navbar navbarEl.classList.remove('bg-white', 'border-slate-200'); navbarEl.classList.add('bg-black', 'border-slate-800'); // Footer footerEl.classList.remove('bg-white', 'border-slate-200'); footerEl.classList.add('bg-black', 'border-slate-800'); // Card panels cardContainers.forEach(el => { el.classList.remove('bg-white', 'border-slate-200'); el.classList.add('bg-black', 'border-slate-800'); }); // Sun vs moon icons document.getElementById('theme-sun').classList.remove('hidden'); document.getElementById('theme-moon').classList.add('hidden'); } else { document.documentElement.classList.remove('dark'); bodyEl.classList.add('bg-slate-50', 'text-slate-900'); bodyEl.classList.remove('bg-black', 'text-white'); // Sidebar sidebarEl.classList.add('bg-white', 'border-slate-200'); sidebarEl.classList.remove('bg-black', 'border-slate-800'); // Navbar navbarEl.classList.add('bg-white', 'border-slate-200'); navbarEl.classList.remove('bg-black', 'border-slate-800'); // Footer footerEl.classList.add('bg-white', 'border-slate-200'); footerEl.classList.remove('bg-black', 'border-slate-800'); // Card panels cardContainers.forEach(el => { el.classList.add('bg-white', 'border-slate-200'); el.classList.remove('bg-black', 'border-slate-800'); }); // Sun vs moon icons document.getElementById('theme-sun').classList.add('hidden'); document.getElementById('theme-moon').classList.remove('block'); document.getElementById('theme-moon').classList.add('block'); } // Adjust all dynamic component layouts document.querySelectorAll('.logo-border').forEach(el => { if (theme === 'black') { el.classList.remove('border-slate-200'); el.classList.add('border-slate-800'); } else { el.classList.add('border-slate-200'); el.classList.remove('border-slate-800'); } }); } function toggleTheme() { currentTheme = (currentTheme === 'white') ? 'black' : 'white'; localStorage.setItem('admin_theme', currentTheme); applyTheme(currentTheme); } // Handle Language Switch function applyLanguage(lang) { currentLang = lang; localStorage.setItem('admin_lang', lang); // Toggle language pill states if (lang === 'en') { document.getElementById('lang-en').className = "px-2.5 py-1 text-xs font-bold rounded-md transition-all duration-200 bg-white text-black shadow-sm"; document.getElementById('lang-th').className = "px-2.5 py-1 text-xs font-bold rounded-md transition-all duration-200 text-slate-500 dark:text-slate-400"; } else { document.getElementById('lang-th').className = "px-2.5 py-1 text-xs font-bold rounded-md transition-all duration-200 bg-white text-black shadow-sm"; document.getElementById('lang-en').className = "px-2.5 py-1 text-xs font-bold rounded-md transition-all duration-200 text-slate-500 dark:text-slate-400"; } // Iterate and translate all matching key strings document.querySelectorAll('[data-lang-key]').forEach(el => { const key = el.getAttribute('data-lang-key'); if (translations[lang][key]) { // Retain icon prefix tags if present if (el.innerText.includes('🏠') && !translations[lang][key].startsWith('🏠')) { el.innerText = '🏠 ' + translations[lang][key].replace(/^[^\w\s\u0e00-\u0e7f]*/, '').trim(); } else if (el.innerText.includes('👤') && !translations[lang][key].startsWith('👤')) { el.innerText = '👤 ' + translations[lang][key].replace(/^[^\w\s\u0e00-\u0e7f]*/, '').trim(); } else if (el.innerText.includes('🏪') && !translations[lang][key].startsWith('🏪')) { el.innerText = '🏪 ' + translations[lang][key].replace(/^[^\w\s\u0e00-\u0e7f]*/, '').trim(); } else if (el.innerText.includes('💳') && !translations[lang][key].startsWith('💳')) { el.innerText = '💳 ' + translations[lang][key].replace(/^[^\w\s\u0e00-\u0e7f]*/, '').trim(); } else if (el.innerText.includes('⚙️') && !translations[lang][key].startsWith('⚙️')) { el.innerText = '⚙️ ' + translations[lang][key].replace(/^[^\w\s\u0e00-\u0e7f]*/, '').trim(); } else { el.innerText = translations[lang][key]; } } }); // Sync the active Section Header Text const activeMenuBtn = document.querySelector('.active-menu-btn'); if (activeMenuBtn) { const key = activeMenuBtn.getAttribute('data-lang-key'); document.getElementById('section-title').innerText = translations[lang][key].replace(/^[^\w\s\u0e00-\u0e7f]*/, '').trim(); } } function changeLang(lang) { applyLanguage(lang); } // Section Router show/hide helper function showSection(sectId) { // Hide all dashboard sections document.querySelectorAll('.dashboard-section').forEach(sect => { sect.classList.add('hidden'); }); // Show chosen section document.getElementById('sect-' + sectId).classList.remove('hidden'); // Reset menu styling active states document.querySelectorAll('.menu-btn').forEach(btn => { btn.className = "flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium text-slate-700 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-900 menu-btn"; }); // Set current clicked button active style const activeBtn = event.currentTarget; activeBtn.className = "flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium bg-slate-900 text-white dark:bg-white dark:text-black menu-btn active-menu-btn"; // Sync section title text dynamically const key = activeBtn.getAttribute('data-lang-key'); document.getElementById('section-title').innerText = translations[currentLang][key].replace(/^[^\w\s\u0e00-\u0e7f]*/, '').trim(); } // On Page Load Initialization window.addEventListener('DOMContentLoaded', () => { applyTheme(currentTheme); applyLanguage(currentLang); // Handle anchor hashtags if page loaded via PHP redirect postbacks if(window.location.hash) { const hashValue = window.location.hash.substring(1); // e.g. 'shops' const matchBtn = document.querySelector(`[onclick="showSection('${hashValue}')"]`); if(matchBtn) { matchBtn.click(); } } }); </script> </body> </html>
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.25 |
proxy
|
phpinfo
|
Settings