JIT
improving code style and layout for dashboard overview
Fix the style problem of this code. Clear the excess spacing at the top of the main content and move all the main content at top. Also, make the overview boxes smller and just right size and fix the styling of the dtae and time as well as the user icon and usernmae: Here is the code: <?php /** * Plugin Name: Dashboard Overview Snippet with Chart * Description: Displays a dashboard overview on a page with real-time updates and a stock chart. */ // --- Database Connection (Using WordPress $wpdb) --- global $wpdb; // --- *** NEW: Dedicated AJAX Handler Function *** --- function dashboard_overview_ajax_handler() { // Optional: Add nonce check for security // check_ajax_referer('dashboard_data_nonce', 'security'); $data_type = isset($_REQUEST['data_type']) ? sanitize_key($_REQUEST['data_type']) : null; $response = ['error' => 'Invalid data type specified']; // Default error if ($data_type) { // Note: The fetch_* functions need access to $wpdb, ensure they are defined globally or passed if needed. // Since they are defined outside this function but use `global $wpdb;` inside, it should work here. switch ($data_type) { case 'overview_boxes': $response = [ 'userCount' => fetch_wp_user_count(), 'categoryCount' => fetch_wp_category_count(), 'productCount' => fetch_wp_product_count(), 'totalSales' => fetch_wp_total_sales(), ]; break; case 'highest_selling_products': $response = fetch_wp_highest_selling_products(); break; case 'latest_sales': $response = fetch_wp_latest_sales(); break; case 'recent_products': $response = fetch_wp_recent_products(); break; default: error_log("Dashboard AJAX Error: Unknown data_type requested - " . $data_type); // Keep default error message break; } wp_send_json_success($response); } else { error_log("Dashboard AJAX Error: data_type parameter missing."); wp_send_json_error($response, 400); // Send error if data_type is missing } // wp_die(); // Included in wp_send_json_* functions } // --- *** NEW: Hook the handler to WordPress AJAX actions *** --- // IMPORTANT: These lines ideally belong in functions.php or a plugin file. // Placing them here might work, but it's not the standard/recommended practice. add_action('wp_ajax_get_dashboard_data', 'dashboard_overview_ajax_handler'); // For logged-in users // add_action('wp_ajax_nopriv_get_dashboard_data', 'dashboard_overview_ajax_handler'); // Uncomment if needed for non-logged-in users // --- Data Fetching Functions (Using NO prefix as requested) --- function fetch_wp_user_count() { global $wpdb; $users_table_name = 'users'; // WP Users table *always* uses prefix if($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $users_table_name)) != $users_table_name) { return 0; } $count = $wpdb->get_var("SELECT COUNT(*) FROM $users_table_name"); return $count ? $count : 0; } function fetch_wp_category_count() { global $wpdb; $category_table_name = 'categories'; // NO prefix if($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $category_table_name)) != $category_table_name) { return 0; } $count = $wpdb->get_var("SELECT COUNT(*) FROM $category_table_name"); return $count ? $count : 0; } function fetch_wp_product_count() { global $wpdb; $product_table_name = 'products'; // NO prefix if($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $product_table_name)) != $product_table_name) { return 0; } $count = $wpdb->get_var("SELECT COUNT(*) FROM $product_table_name"); return $count ? $count : 0; } function fetch_wp_total_sales() { global $wpdb; $sales_table_name = 'orders'; // NO prefix $sales_amount_column = 'total_amount'; if($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $sales_table_name)) != $sales_table_name) { return '0.00'; } $total = $wpdb->get_var($wpdb->prepare("SELECT SUM($sales_amount_column) FROM $sales_table_name WHERE status = %s", 'Paid')); return $total ? number_format_i18n($total, 2) : '0.00'; } function fetch_wp_highest_selling_products() { global $wpdb; $products = []; $products_table_name = 'products'; $order_items_table_name = 'order_items'; $orders_table_name = 'orders'; // Debug: Check table existence if($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $products_table_name)) != $products_table_name || $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $order_items_table_name)) != $order_items_table_name || $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $orders_table_name)) != $orders_table_name) { error_log("Dashboard Error: Required tables not found"); return $products; } $results = $wpdb->get_results($wpdb->prepare(" SELECT p.name AS product_name, SUM(oi.quantity) AS items_sold, SUM(oi.amount) AS total_sales FROM {$order_items_table_name} oi JOIN {$products_table_name} p ON oi.product_id = p.id JOIN {$orders_table_name} o ON oi.order_id = o.id WHERE o.status = 'Paid' GROUP BY p.id, p.name ORDER BY items_sold DESC LIMIT %d", 5), ARRAY_A); if ($results) { foreach ($results as $row) { $products[] = [ 'name' => $row['product_name'], 'items_sold' => $row['items_sold'], 'total_sales' => number_format_i18n($row['total_sales'], 2), ]; } } else { error_log("Dashboard Debug: No highest selling products found"); } return $products; } function fetch_wp_latest_sales() { global $wpdb; $sales = []; $order_items_table_name = 'order_items'; $orders_table_name = 'orders'; $products_table_name = 'products'; // Debug: Check table existence if($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $orders_table_name)) != $orders_table_name || $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $order_items_table_name)) != $order_items_table_name || $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $products_table_name)) != $products_table_name) { error_log("Dashboard Error: Required tables not found"); return $sales; } $results = $wpdb->get_results($wpdb->prepare(" SELECT o.id AS order_id, o.total_amount, o.created_at, GROUP_CONCAT(DISTINCT p.name SEPARATOR ', ') AS product_names FROM {$orders_table_name} o LEFT JOIN {$order_items_table_name} oi ON o.id = oi.order_id LEFT JOIN {$products_table_name} p ON oi.product_id = p.id WHERE o.status = 'Paid' GROUP BY o.id, o.total_amount, o.created_at ORDER BY o.created_at DESC LIMIT %d", 5), ARRAY_A); if ($results) { foreach ($results as $row) { $sales[] = [ 'item_no' => 'Order #' . $row['order_id'], 'product_name' => $row['product_names'] ?? 'N/A', 'total_sales' => number_format_i18n($row['total_amount'], 2), ]; } } else { error_log("Dashboard Debug: No latest sales found"); } return $sales; } // --- UPDATED fetch_wp_recent_products function --- function fetch_wp_recent_products() { global $wpdb; $products = []; $products_table_name = 'products'; // NO prefix // *** IMPORTANT: Define the *actual* date column name in your 'products' table here *** $products_date_column = 'created_at'; // <--- CHANGE THIS ('created_at', 'date_created', 'date_added', etc.) if($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $products_table_name)) != $products_table_name) { error_log("Dashboard Snippet Error: Table '{$products_table_name}' not found."); return $products; // Table doesn't exist } // Check if the specified date column exists $columns = $wpdb->get_col("DESC $products_table_name"); if (!in_array($products_date_column, $columns)) { error_log("Dashboard Snippet Error: Specified date column '{$products_date_column}' not found in table '{$products_table_name}'. Please check the function."); return $products; // Column doesn't exist, cannot sort } // Prepare and execute the query $query = $wpdb->prepare(" SELECT name, {$products_date_column} AS created_at_alias FROM {$products_table_name} WHERE name IS NOT NULL AND name != '' AND {$products_date_column} IS NOT NULL ORDER BY {$products_date_column} DESC LIMIT %d", 5); $results = $wpdb->get_results($query, ARRAY_A); // Check for query errors if ($results === null) { error_log("Dashboard Snippet Error: WPDB query failed for recent products. Error: " . $wpdb->last_error . " Query: " . $query); return $products; // Query failed } // Process results if ($results) { foreach ($results as $row) { // Ensure name and date exist before adding if (isset($row['name']) && isset($row['created_at_alias'])) { $products[] = [ 'name' => $row['name'], 'date_added' => mysql2date(get_option('date_format'), $row['created_at_alias']), // Use the alias ]; } } } return $products; } // --- END UPDATED fetch_wp_recent_products function --- // --- Fetch Data for Stock Chart --- $product_table_name_chart = 'products'; // NO prefix $products_for_chart = []; $chart_data_error = ''; if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $product_table_name_chart)) == $product_table_name_chart) { $products_for_chart_raw = $wpdb->get_results( "SELECT name, in_stock FROM {$product_table_name_chart} WHERE name IS NOT NULL AND name != '' ORDER BY name ASC", ARRAY_A ); if ($products_for_chart_raw === null) { $chart_data_error = "Error querying products table: " . $wpdb->last_error; error_log("Dashboard Chart Error: " . $chart_data_error); } elseif (empty($products_for_chart_raw)) { $chart_data_error = "No products with names found in the '{$product_table_name_chart}' table."; } else { foreach ($products_for_chart_raw as $product) { $products_for_chart[] = [ 'name' => $product['name'], 'in_stock' => intval($product['in_stock'] ?? 0) ]; } } } else { $chart_data_error = "Error: Products table '{$product_table_name_chart}' not found."; } $chart_labels = json_encode(wp_list_pluck($products_for_chart, 'name')); $chart_data = json_encode(wp_list_pluck($products_for_chart, 'in_stock')); // --- END: Fetch Data for Stock Chart --- // --- Initial Data for Page Load --- $initialUserCount = fetch_wp_user_count(); $initialCategoryCount = fetch_wp_category_count(); $initialProductCount = fetch_wp_product_count(); $initialTotalSales = fetch_wp_total_sales(); $initialHighestSellingProducts = fetch_wp_highest_selling_products(); $initialLatestSales = fetch_wp_latest_sales(); $initialRecentProducts = fetch_wp_recent_products(); $currency_symbol = function_exists('get_woocommerce_currency_symbol') ? get_woocommerce_currency_symbol() : '₱'; ?> <!DOCTYPE html> <html lang="<?php language_attributes(); ?>"> <head> <meta charset="<?php bloginfo('charset'); ?>"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Dashboard Overview - <?php bloginfo('name'); ?></title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" integrity="sha512-9usAa10IRO0HhonpyAIVpjrylPvoDwiPUiKdWk5t3PyolY1cOd4DSE0Ga+ri4AuTroPR5aQvXU9xC6qOPnzFeg==" crossorigin="anonymous" referrerpolicy="no-referrer" /> <?php // wp_head(); ?> <style> body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 0; background-color: #f4f7f9; color: #333; } .dashboard-container { display: flex; } .sidebar { width: 240px; background-color: #D1B48C; color: #000; height: 100vh; position: fixed; left: 0; top: 0; overflow-y: auto; box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1); z-index: 1000; } .sidebar-header { padding: 20px; text-align: center; } .sidebar-header .inventory-name { font-size: 17px; font-weight: bold; color: #000; } .sidebar-menu { padding: 0; } .sidebar-menu ul { list-style: none; margin: 0; padding: 0; } .sidebar-menu li a { display: flex; align-items: center; padding: 12px 20px; text-decoration: none; color: #000; transition: 0.3s; font-size: 16px; } .sidebar-menu li a i { margin-right: 12px; width: 20px; text-align: center; } .sidebar-menu li a:hover { background-color: #ffffff; color: #000; } .main-content { margin-left: 240px; padding: 20px; flex-grow: 1; } .header { display: flex; justify-content: space-between; align-items: center; background-color: #fff; padding: 15px 30px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); border-bottom: 1px solid #eee; margin-bottom: 20px; } .header-left .date-time { font-size: 16px; color: #6c757d; } .header-right { display: flex; align-items: center; gap: 8px; font-size: 17px; color: #333; } /* === DASHBOARD LAYOUT === */ #dashboard-overview-snippet-container .top-section { display: flex; flex-wrap: wrap; gap: 25px; margin-bottom: 35px; } #dashboard-overview-snippet-container .overview-boxes { flex: 1 1 400px; display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; } #dashboard-overview-snippet-container .overview-boxes .box { background-color: #fff; padding: 20px 15px; border-radius: 8px; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.06); border: 1px solid #e9ecef; display: flex; align-items: center; gap: 15px; transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out; width: 100%; } #dashboard-overview-snippet-container .overview-boxes .box:hover { transform: translateY(-3px); box-shadow: 0 6px 15px rgba(0, 0, 0, 0.09); } #dashboard-overview-snippet-container .overview-boxes .box i.icon { font-size: 24px; color: #fff; border-radius: 50%; padding: 12px; width: 55px; height: 55px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; } #dashboard-overview-snippet-container .overview-boxes .box:nth-child(1) i.icon { background-color: #17a2b8; } #dashboard-overview-snippet-container .overview-boxes .box:nth-child(2) i.icon { background-color: #28a745; } #dashboard-overview-snippet-container .overview-boxes .box:nth-child(3) i.icon { background-color: #ffc107; } #dashboard-overview-snippet-container .overview-boxes .box:nth-child(4) i.icon { background-color: #dc3545; } #dashboard-overview-snippet-container .overview-boxes .box .detail { text-align: left; overflow: hidden; } #dashboard-overview-snippet-container .overview-boxes .box .count { font-size: 24px; font-weight: 600; color: #343a40; line-height: 1.1; margin-bottom: 4px; white-space: nowrap; } #dashboard-overview-snippet-container .overview-boxes .box .label { font-size: 14px; color: #6c757d; white-space: nowrap; } /* --- Chart Container Styles --- */ #dashboard-overview-snippet-container .chart-container { flex: 1.5 1 500px; background-color: #fff; padding: 25px; border-radius: 8px; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.07); border: 1px solid #e9ecef; position: relative; height: auto; min-height: 400px; } #dashboard-overview-snippet-container .chart-container h2 { margin-top: 0; margin-bottom: 25px; color: #343a40; text-align: center; font-size: 1.5em; border-bottom: 1px solid #dee2e6; padding-bottom: 15px; font-weight: 600; } #dashboard-overview-snippet-container #stockChartCanvas { max-width: 100%; height: 300px !important; display: block; } #dashboard-overview-snippet-container .chart-container .chart-message { text-align: center; padding: 20px; color: #6c757d; font-style: italic; } #dashboard-overview-snippet-container .chart-container .chart-error-message { color: #dc3545; font-weight: bold; } /* --- Dashboard Tables Styles --- */ #dashboard-overview-snippet-container .dashboard-tables { display: grid; grid-template-columns: 1fr; gap: 35px; } #dashboard-overview-snippet-container .dashboard-tables .table-container { background-color: #fff; border-radius: 8px; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.07); border: 1px solid #e9ecef; padding: 30px; overflow-x: auto; } #dashboard-overview-snippet-container .dashboard-tables .table-container h2 { margin-top: 0; margin-bottom: 25px; color: #343a40; border-bottom: 1px solid #dee2e6; padding-bottom: 15px; font-size: 1.2em; font-weight: 600; } #dashboard-overview-snippet-container .dashboard-tables table { width: 100%; border-collapse: collapse; border-spacing: 0; } #dashboard-overview-snippet-container .dashboard-tables th, #dashboard-overview-snippet-container .dashboard-tables td { padding: 16px 20px; text-align: left; border-bottom: 1px solid #dee2e6; font-size: 1.05em; vertical-align: middle; line-height: 1.5; } #dashboard-overview-snippet-container .dashboard-tables th { background-color: #f8f9fa; font-weight: 600; color: #495057; white-space: nowrap; font-size: 1em; text-transform: uppercase; letter-spacing: 0.5px; } #dashboard-overview-snippet-container .dashboard-tables tbody tr:last-child td { border-bottom: none; } #dashboard-overview-snippet-container .dashboard-tables tbody tr:hover { background-color: #f1f3f5; } #dashboard-overview-snippet-container #highest-selling-table td:nth-child(2), #dashboard-overview-snippet-container #highest-selling-table td:nth-child(3), #dashboard-overview-snippet-container #latest-sales-table td:nth-child(3) { text-align: right; } #dashboard-overview-snippet-container #recent-products-table td:nth-child(2) { text-align: right; white-space: nowrap; } /* --- Message Styles --- */ #dashboard-overview-snippet-container .notice-wrap { margin-bottom: 15px; } #dashboard-overview-snippet-container .notice { padding: 10px 15px; border-radius: 4px; border-left: 4px solid; } #dashboard-overview-snippet-container .notice-error { background-color: #f8d7da; border-color: #dc3545; color: #721c24; } #dashboard-overview-snippet-container .ajax-error-notice { margin-top: 15px; } /* --- Responsive Adjustments --- */ @media (max-width: 992px) { #dashboard-overview-snippet-container .top-section { flex-direction: column; } #dashboard-overview-snippet-container .overview-boxes, #dashboard-overview-snippet-container .chart-container { flex-basis: auto; width: 100%; } #dashboard-overview-snippet-container .chart-container { min-height: 350px; } } @media (max-width: 576px) { #dashboard-overview-snippet-container .overview-boxes { grid-template-columns: 1fr; } #dashboard-overview-snippet-container .overview-boxes .box { gap: 10px; } #dashboard-overview-snippet-container .overview-boxes .box i.icon { width: 45px; height: 45px; font-size: 20px; padding: 10px; } #dashboard-overview-snippet-container .overview-boxes .box .count { font-size: 20px; } #dashboard-overview-snippet-container .overview-boxes .box .label { font-size: 13px; } #dashboard-overview-snippet-container .chart-container { padding: 15px; } #dashboard-overview-snippet-container .chart-container h2 { font-size: 1.3em; margin-bottom: 15px; padding-bottom: 10px;} #dashboard-overview-snippet-container .dashboard-tables .table-container { padding: 15px; } #dashboard-overview-snippet-container .dashboard-tables th, #dashboard-overview-snippet-container .dashboard-tables td { padding: 10px 8px; font-size: 0.95em;} } </style> </head> <body <?php body_class(); ?>> <div class="dashboard-container"> <aside class="sidebar"> <div class="sidebar-header"> <div class="inventory-name">ArKi Inventory</div> </div> <div class="sidebar-menu"> <ul> <li><a href="http://localhost/inventory/index.php/admin-page/"><i class="fas fa-tachometer-alt"></i> Dashboard</a></li> <?php session_start(); $current_username = isset($_SESSION['username']) ? $_SESSION['username'] : ''; if ($current_username === 'admin') : ?> <li><a href="http://localhost/inventory/index.php/usersmanagement/"><i class="fas fa-users-cog"></i> User Management</a></li> <li><a href="http://localhost/inventory/index.php/category-page/"><i class="fas fa-list"></i> Categories</a></li> <li><a href="http://localhost/inventory/index.php/products/"><i class="fas fa-boxes"></i> Products</a></li> <li><a href="http://localhost/inventory/index.php/order/"><i class="fas fa-shopping-cart"></i> Orders</a></li> <li><a href="http://localhost/inventory/index.php/view-order/"><i class="fas fa-eye"></i> View Orders</a></li> <li><a href="http://localhost/inventory/index.php/sales/"><i class="fas fa-chart-line"></i> Sales & Report</a></li> <li><a href="http://localhost/inventory/index.php/report/"><i class="fas fa-file-alt"></i> Inventory Report</a></li> <li><a href="http://localhost/inventory/index.php/history/"><i class="fas fa-history"></i> Inventory History</a></li> <?php else : ?> <li><a href="http://localhost/inventory/index.php/category-page/"><i class="fas fa-list"></i> Categories</a></li> <li><a href="http://localhost/inventory/index.php/products/"><i class="fas fa-boxes"></i> Products</a></li> <li><a href="http://localhost/inventory/index.php/order/"><i class="fas fa-shopping-cart"></i> Orders</a></li> <?php endif; ?> <li><a href="http://localhost/inventory/index.php/sign-in2/" onclick="return confirm('Are you sure you want to log out?');"><i class="fas fa-sign-out-alt"></i> Logout</a></li> </ul> </div> </aside> <main class="main-content"> <header class="header"> <div class="header-left"> <span class="date-time" id="current-date-time"></span> </div> <div class="header-right"> <i class="fas fa-user-circle"></i> <span id="current-username-header"> <?php echo isset($_SESSION['username']) ? htmlspecialchars($_SESSION['username']) : 'Guest'; ?> </span> </div> </header> <div id="dashboard-overview-snippet-container"> <header class="header"> <h1>Dashboard Overview</h1> </header> <!-- NEW WRAPPER for top two columns --> <section class="top-section"> <!-- Left Column: Overview Boxes (Now a Grid) --> <section class="overview-boxes"> <div class="box"> <i class="fas fa-users icon"></i> <div class="detail"> <div class="count" id="user-count"><?php echo esc_html($initialUserCount); ?></div> <div class="label">Users</div> </div> </div> <div class="box"> <i class="fas fa-tags icon"></i> <div class="detail"> <div class="count" id="category-count"><?php echo esc_html($initialCategoryCount); ?></div> <div class="label">Categories</div> </div> </div> <div class="box"> <i class="fas fa-box-open icon"></i> <div class="detail"> <div class="count" id="product-count"><?php echo esc_html($initialProductCount); ?></div> <div class="label">Products</div> </div> </div> <div class="box"> <i class="fas fa-chart-line icon"></i> <div class="detail"> <div class="count" id="total-sales"><?php echo esc_html($currency_symbol); ?><?php echo esc_html($initialTotalSales); ?></div> <div class="label">Total Sales</div> </div> </div> </section> <!-- Right Column: Chart --> <section class="chart-container"> <h2>Product Stock Overview</h2> <canvas id="stockChartCanvas" style="display: none;"></canvas> <!-- Hide initially --> <div id="chart-message-area"> <?php if (!empty($chart_data_error)): ?> <p class="chart-message chart-error-message"><?php echo esc_html($chart_data_error); ?></p> <?php elseif (empty($products_for_chart)): ?> <p class="chart-message">No product data available to display the chart.</p> <?php else: ?> <p class="chart-message" id="chart-loading-message">Loading chart...</p> <?php endif; ?> </div> </section> </section> <!-- END of top-section --> <!-- Tables Section (Remains below the top section) --> <section class="dashboard-tables"> <div class="table-container"> <h2>Highest Selling Products</h2> <table id="highest-selling-table"> <thead> <tr> <th>Product Name</th> <th>Items Sold</th> <th>Total Sales</th> </tr> </thead> <tbody> <?php if (empty($initialHighestSellingProducts)): ?> <tr><td colspan="3" style="text-align: center;">No sales data available</td></tr> <?php else: foreach ($initialHighestSellingProducts as $product): ?> <tr> <td><?php echo esc_html($product['name']); ?></td> <td style="text-align:right;"><?php echo esc_html($product['items_sold']); ?></td> <td style="text-align:right;"><?php echo esc_html($currency_symbol); ?><?php echo esc_html($product['total_sales']); ?></td> </tr> <?php endforeach; endif; ?> </tbody> </table> </div> <div class="table-container"> <h2>Latest Sales</h2> <table id="latest-sales-table"> <thead> <tr> <th>Item No</th> <th>Product(s)</th> <th>Total Sales</th> </tr> </thead> <tbody> <?php if (empty($initialLatestSales)): ?> <tr><td colspan="3" style="text-align: center;">No recent sales</td></tr> <?php else: foreach ($initialLatestSales as $sale): ?> <tr> <td><?php echo esc_html($sale['item_no']); ?></td> <td><?php echo esc_html($sale['product_name']); ?></td> <td style="text-align:right;"><?php echo esc_html($currency_symbol); ?><?php echo esc_html($sale['total_sales']); ?></td> </tr> <?php endforeach; endif; ?> </tbody> </table> </div> <div class="table-container"> <h2>Recently Added Products</h2> <table id="recent-products-table"> <thead> <tr> <th>Product Name</th> <th>Date Added</th> </tr> </thead> <tbody> <?php if (empty($initialRecentProducts)): ?> <tr><td colspan="2" style="text-align: center;">No recently added products</td></tr> <?php else: foreach ($initialRecentProducts as $product): ?> <tr> <td><?php echo esc_html($product['name']); ?></td> <td style="text-align:right; white-space:nowrap;"><?php echo esc_html($product['date_added']); ?></td> </tr> <?php endforeach; endif; ?> </tbody> </table> </div> </section> </div> <!-- End #dashboard-overview-snippet-container --> </main> </div> <!-- Include Chart.js library --> <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script> <!-- UPDATED AJAX Update Script --> <script> document.addEventListener('DOMContentLoaded', function() { const container = document.getElementById('dashboard-overview-snippet-container'); if (!container) return; const ajaxUrl = '<?php echo admin_url('admin-ajax.php'); ?>'; // Use admin-ajax.php const currencySymbol = '<?php echo esc_js($currency_symbol); ?>'; // const dashboardNonce = '<?php // echo wp_create_nonce("dashboard_data_nonce"); ?>'; // If using nonces function fetchData(dataType, callback) { const url = new URL(ajaxUrl); // *** ADD THE ACTION PARAMETER *** url.searchParams.append('action', 'get_dashboard_data'); // Matches add_action hook url.searchParams.append('data_type', dataType); // url.searchParams.append('security', dashboardNonce); // Add if using nonces console.log(`Fetching data for: ${dataType} from URL: ${url.toString()}`); // Debug log fetch(url) .then(response => { if (!response.ok) { console.error(`HTTP error! status: ${response.status} for ${dataType}`, response); return response.text().then(text => { console.error("Response Text:", text); throw new Error(`HTTP error! status: ${response.status}`); }); } return response.json(); }) .then(data => { if (typeof data.success === 'undefined') { console.error("AJAX response missing 'success' property:", data); throw new Error(`Invalid AJAX response format for ${dataType}`); } if (data.success === false) { console.error(`AJAX Error (${dataType}):`, data.data?.message || data.data || 'Unknown server error'); throw new Error(data.data?.message || data.data || `AJAX error fetching ${dataType}`); } callback(data.data); // Pass the actual data payload }) .catch(error => { console.error(`Error fetching ${dataType}:`, error); const errorContainer = container.querySelector('.main-content') || container; if(errorContainer && !container.querySelector('.ajax-error-notice')) { const notice = document.createElement('div'); notice.className = 'notice notice-error ajax-error-notice'; notice.innerHTML = `<p>Error loading dashboard data (${dataType}). Please check console or try again later.</p>`; errorContainer.insertBefore(notice, errorContainer.firstChild); } }); } // Keep the rest of the AJAX update functions function updateOverviewBoxes() { fetchData('overview_boxes', data => { const userCountEl = container.querySelector('#user-count'); const categoryCountEl = container.querySelector('#category-count'); const productCountEl = container.querySelector('#product-count'); const totalSalesEl = container.querySelector('#total-sales'); if(userCountEl && typeof data.userCount !== 'undefined') userCountEl.textContent = data.userCount; if(categoryCountEl && typeof data.categoryCount !== 'undefined') categoryCountEl.textContent = data.categoryCount; if(productCountEl && typeof data.productCount !== 'undefined') productCountEl.textContent = data.productCount; if(totalSalesEl && typeof data.totalSales !== 'undefined') totalSalesEl.textContent = currencySymbol + data.totalSales; }); } function updateTable(tableId, dataType, renderFunction) { fetchData(dataType, data => { const tableBody = container.querySelector(`#${tableId} tbody`); if (!tableBody) return; tableBody.innerHTML = ''; if (!data || !Array.isArray(data) || data.length === 0) { const colSpan = tableBody.closest('table')?.querySelector('thead tr')?.childElementCount || 1; tableBody.innerHTML = `<tr><td colspan="${colSpan}" style="text-align: center;">No data available</td></tr>`; } else { data.forEach(item => { tableBody.innerHTML += renderFunction(item); }); } }); } function renderHighestSellingRow(product) { return `<tr><td>${escapeHtml(product.name)}</td><td style="text-align:right;">${escapeHtml(product.items_sold)}</td><td style="text-align:right;">${currencySymbol}${escapeHtml(product.total_sales)}</td></tr>`; } function renderLatestSalesRow(sale) { return `<tr><td>${escapeHtml(sale.item_no)}</td><td>${escapeHtml(sale.product_name)}</td><td style="text-align:right;">${currencySymbol}${escapeHtml(sale.total_sales)}</td></tr>`; } function renderRecentProductsRow(product) { return `<tr><td>${escapeHtml(product.name)}</td><td style="text-align:right; white-space:nowrap;">${escapeHtml(product.date_added)}</td></tr>`; } function escapeHtml(unsafe) { if (unsafe === null || typeof unsafe === 'undefined') return ''; return unsafe.toString().replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;"); } updateOverviewBoxes(); updateTable('highest-selling-table', 'highest_selling_products', renderHighestSellingRow); updateTable('latest-sales-table', 'latest_sales', renderLatestSalesRow); updateTable('recent-products-table', 'recent_products', renderRecentProductsRow); const updateInterval = 30000; setInterval(updateOverviewBoxes, updateInterval); setInterval(() => updateTable('highest-selling-table', 'highest_selling_products', renderHighestSellingRow), updateInterval); setInterval(() => updateTable('latest-sales-table', 'latest_sales', renderLatestSalesRow), updateInterval); setInterval(() => updateTable('recent-products-table', 'recent_products', renderRecentProductsRow), updateInterval); }); </script> <!-- END UPDATED AJAX Update Script --> <!-- Chart Initialization JavaScript with MORE Debugging --> <script> // Paste the existing Chart initialization script here document.addEventListener('DOMContentLoaded', function() { console.log("[Chart Script] DOMContentLoaded fired. Initializing chart script..."); const ctx = document.getElementById('stockChartCanvas'); const chartContainer = document.querySelector('#dashboard-overview-snippet-container .chart-container'); const messageArea = document.getElementById('chart-message-area'); const loadingMessage = document.getElementById('chart-loading-message'); console.log("[Chart Script] Canvas Element (ctx):", ctx); console.log("[Chart Script] Chart Container:", chartContainer); console.log("[Chart Script] Message Area:", messageArea); console.log("[Chart Script] Loading Message Element:", loadingMessage); function showChartMessage(message, isError = false) { console.log(`[Chart Script] Attempting to show message (isError: ${isError}): "${message}"`); if (messageArea) { messageArea.innerHTML = `<p class="chart-message ${isError ? 'chart-error-message' : ''}">${escapeHtml(message)}</p>`; console.log("[Chart Script] Message area updated."); } else { console.error("[Chart Script] Cannot show message - messageArea element not found!"); } if (ctx) { ctx.style.display = 'none'; console.log("[Chart Script] Canvas hidden."); } else { console.warn("[Chart Script] Cannot hide canvas - ctx element not found!"); } } let phpLabels = null; let phpData = null; let phpError = null; console.log("[Chart Script] Reading PHP variables..."); try { phpLabels = <?php echo $chart_labels ?? 'null'; ?>; phpData = <?php echo $chart_data ?? 'null'; ?>; phpError = <?php echo json_encode($chart_data_error); ?>; console.log("[Chart Script] PHP Labels Raw:", JSON.stringify(phpLabels)); console.log("[Chart Script] PHP Data Raw:", JSON.stringify(phpData)); console.log("[Chart Script] PHP Error Message:", phpError); } catch (e) { console.error("[Chart Script] FATAL: JavaScript Error reading PHP variables:", e); showChartMessage("Internal error reading chart data. Check console.", true); return; } console.log("[Chart Script] Starting validation checks..."); if (phpError) { console.error("[Chart Script] CHECK FAILED: PHP Error reported:", phpError); showChartMessage(phpError, true); return; } console.log("[Chart Script] CHECK PASSED: No PHP Error reported."); if (!ctx) { console.error("[Chart Script] CHECK FAILED: Canvas element #stockChartCanvas not found!"); showChartMessage("Chart canvas element is missing in HTML.", true); return; } console.log("[Chart Script] CHECK PASSED: Canvas element found."); if (!messageArea) { console.error("[Chart Script] CHECK WARNING: Message area #chart-message-area not found! Error messages might not display correctly."); } else { console.log("[Chart Script] CHECK PASSED: Message area found."); } if (phpLabels === null || phpData === null) { console.warn("[Chart Script] CHECK FAILED: PHP variables for chart labels or data are null."); showChartMessage("Chart data is unavailable from server (null).", false); return; } console.log("[Chart Script] CHECK PASSED: PHP variables are not null."); if (!Array.isArray(phpLabels) || !Array.isArray(phpData)) { console.error("[Chart Script] CHECK FAILED: PHP data for chart is not in array format.", phpLabels, phpData); showChartMessage("Invalid chart data format received (not arrays).", true); return; } console.log("[Chart Script] CHECK PASSED: PHP data are arrays."); if (phpLabels.length === 0) { console.warn("[Chart Script] CHECK FAILED: Chart labels array is empty."); showChartMessage("No product stock data available to display (empty array).", false); return; } console.log("[Chart Script] CHECK PASSED: Labels array is not empty."); if (phpLabels.length !== phpData.length) { console.error(`[Chart Script] CHECK FAILED: Chart labels (${phpLabels.length}) and data (${phpData.length}) arrays have different lengths!`); showChartMessage("Data mismatch: Labels and stock counts do not align.", true); return; } console.log("[Chart Script] CHECK PASSED: Label and data array lengths match."); console.log("[Chart Script] All validation checks passed. Preparing to render chart..."); if (loadingMessage) { loadingMessage.remove(); console.log("[Chart Script] Removed loading message element."); } else { console.warn("[Chart Script] Loading message element (#chart-loading-message) not found to remove."); } if (messageArea) { messageArea.innerHTML = ''; console.log("[Chart Script] Cleared message area content."); } ctx.style.display = 'block'; console.log("[Chart Script] Canvas display set to 'block'."); try { console.log("[Chart Script] Initializing Chart.js..."); function generateColors(count) { const colors = []; if (count <= 0) return colors; const hueStep = 360 / count; for (let i = 0; i < count; i++) { const hue = i * hueStep; const saturation = 70 + (Math.random() * 15); const lightness = 55 + (Math.random() * 10); colors.push(`hsla(${hue.toFixed(0)}, ${saturation.toFixed(0)}%, ${lightness.toFixed(0)}%, 0.85)`); } return colors; } const backgroundColors = generateColors(phpLabels.length); const borderColors = backgroundColors.map(color => color.replace('0.85', '1')); new Chart(ctx, { type: 'bar', data: { labels: phpLabels, datasets: [{ label: 'Stock Quantity', data: phpData, backgroundColor: backgroundColors, borderColor: borderColors, borderWidth: 1 }] }, options: { responsive: true, maintainAspectRatio: false, indexAxis: 'x', plugins: { legend: { display: false }, title: { display: false }, tooltip: { callbacks: { label: function(context) { let label = context.dataset.label || ''; if (label) label += ': '; if (context.parsed.y !== null) label += context.parsed.y; return label; } } } }, scales: { y: { beginAtZero: true, title: { display: true, text: 'Stock Quantity' }, ticks: { precision: 0 } }, x: { title: { display: false } } } } }); console.log("[Chart Script] Chart successfully initialized."); } catch (e) { console.error("[Chart Script] FATAL: Chart.js Initialization Error:", e); showChartMessage("Failed to create the chart display. Check console.", true); } }); function escapeHtml(unsafe) { if (unsafe === null || typeof unsafe === 'undefined') return ''; return unsafe.toString() .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;") .replace(/"/g, "&quot;") .replace(/'/g, "&#039;"); } </script> <!-- --- END: Chart Initialization JavaScript --- --> <?php // wp_footer(); ?> <script> function updateDateTime() { const now = new Date(); const options = { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit' }; document.getElementById("current-date-time").textContent = now.toLocaleDateString('en-US', options); } setInterval(updateDateTime, 1000); updateDateTime(); </script> </body> </html> <?php // End of PHP Snippet ?>
Updated files
v1
page-template-admin page page-id-214 wp-custom-logo wp-embed-responsive wp-theme-skincare-product-store elementor-default”>

Okay, I see the body classes from the page where the snippet is being used.

The previous response included the updated PHP file with the CSS modifications to address the styling issues you mentioned (excess spacing, overview box size, date/time, and user info styling).

If you have a new styling issue related to these specific body classes or need further adjustments, please provide details on what you'd like to change.

that is the error that show when i inseted the css

That doesn't look like a standard error message. It appears to be a fragment of the HTML <body> tag from your page, specifically showing the classes applied to the body.

This kind of output often happens when there's a syntax error before the HTML structure is fully rendered, or if the code was pasted incorrectly, causing the PHP parser or the browser to break.

Please ensure you have replaced the entire content of your file with the code I provided in the previous response. Do not just paste the CSS or parts of the code. The snippet is designed to be a complete PHP file that outputs the HTML page.

Here is the complete, corrected code again. Please use this to replace the content of your file entirely.

Updated files
v2
but i just added this session_start(); before teh $current_username=...., because the code you provided is not fetching the current username that is currently logged in. And when i added that is shows this: page-template-admin page page-id-214 wp-custom-logo wp-embed-responsive wp-theme-skincare-product-store elementor-default”>

That output page-template-admin page page-id-214 wp-custom-logo wp-embed-responsive wp-theme-skincare-product-store elementor-default”> is not an error message itself, but rather the beginning of the HTML output (specifically, the classes from your <body> tag).

This happens because you added session_start(); after some output has already been sent to the browser. In PHP, session_start() must be called before any output whatsoever (including whitespace outside of <?php ?> tags, HTML, etc.). When output has already occurred, calling session_start() triggers a "Headers already sent" error, which often prevents the rest of the page from loading correctly and can sometimes just show the partial output that was sent before the error.

Furthermore, in a WordPress environment, you should generally rely on WordPress's built-in user authentication functions rather than starting raw PHP sessions ($_SESSION). WordPress handles user login status internally.

To get the currently logged-in WordPress username, you should use the wp_get_current_user() function.

Let's modify the code to use the correct WordPress function and remove the problematic session_start() call.

Updated files
v3
And i told you already that using the code you provided it does not geeting the current username of the current logged in user. Its just keep on displaying "Guest" even if i logged in in different username

Okay, I understand. The issue is that wp_get_current_user() is not returning the correct user information in your specific setup, and using session_start() caused the "Headers already sent" problem because it wasn't at the very beginning of the file.

It seems your environment might be relying on standard PHP sessions ($_SESSION) for user tracking, which is not the typical WordPress way (WP uses cookies and its own authentication functions). However, if that's how your login system works, we need to accommodate it.

To use session_start() without the "Headers already sent" error, it must be the absolute first thing in the file, before any output, including the <!DOCTYPE html> tag or even whitespace.

I will put session_start() at the very top and revert the username fetching logic to use $_SESSION['username'], while keeping the styling fixes from the previous response.

Important Note: Using raw session_start() and $_SESSION for user authentication is generally not the standard or recommended practice in WordPress. WordPress has its own robust authentication system (wp_get_current_user(), is_user_logged_in(), etc.). If you are building within WordPress, it's best to understand why wp_get_current_user() isn't working for you (likely related to how this file is included or executed) and fix that, rather than relying on raw sessions. However, based on your description, this modification addresses the immediate problem you're facing with the username display and the "Headers already sent" issue.

_

Updated files
v4
make the user icon larger and placed the username just below it, just make the stle of user icon and username good. Also align the datas of "Item Sold" and "Total Sales" correctly because currently the data are not align in the column. Same with the "Total Sales" in the "Latest Sale", the data are not align in the column. Same with the "Recently Added Product", the dates are not align in column "Date Added"
Updated files
v5
Also align the datas of "Item Sold" and "Total Sales" correctly because currently the data are not align in the column. Same with the "Total Sales" in the "Latest Sale", the data are not align in the column. Same with the "Recently Added Product", the dates are not align in column "Date Added"
Updated files
v6
Insert all the additional design from "dashboard" into the "user management" menu: <?php // Database connection $conn = new mysqli("localhost", "arni", "arni2025", "inventory"); if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } // Get users for management $users = array(); $result = $conn->query("SELECT * FROM users"); if ($result->num_rows > 0) { while ($row = $result->fetch_assoc()) { $users[] = $row; } } // Add new user if (isset($_POST['add_user'])) { $first_name = $_POST['first_name']; $last_name = $_POST['last_name']; $username = $_POST['username']; if (isset($_POST['password'])) { $password = password_hash($_POST['password'], PASSWORD_DEFAULT); // Hash the password } else { echo "Password is required."; return; // Stop further execution } // Insert user with the current timestamp for date_added $sql = "INSERT INTO users (first_name, last_name, username, password, date_added) VALUES ('$first_name', '$last_name', '$username', '$password', NOW())"; if ($conn->query($sql) === TRUE) { // Redirect to the same page to prevent re-submission header("Location: " . $_SERVER['PHP_SELF']); exit; // Stop further execution } else { echo "Error: " . $sql . "<br>" . $conn->error; } } // Edit user if (isset($_POST['edit_user'])) { $user_id = $_POST['user_id']; $first_name = $_POST['first_name']; $last_name = $_POST['last_name']; $username = $_POST['username']; $password = password_hash($_POST['password'], PASSWORD_DEFAULT); // Hash the password $sql = "UPDATE users SET first_name='$first_name', last_name='$last_name', username='$username', password='$password' WHERE id='$user_id'"; if ($conn->query($sql) === TRUE) { header("Location: " . $_SERVER['PHP_SELF']); exit; } else { echo "Error: " . $conn->error; } } // Delete user if (isset($_GET['delete_user'])) { $user_id = $_GET['delete_user']; $sql = "DELETE FROM users WHERE id='$user_id'"; if ($conn->query($sql) === TRUE) { header("Location: " . $_SERVER['PHP_SELF']); exit; } else { echo "Error: " . $conn->error; } } // Update last_logged_in on every page load (you can adjust the logic to a login action instead) session_start(); if (isset($_SESSION['username'])) { // Check if the user is logged in $username = $_SESSION['username']; $stmt = $conn->prepare("UPDATE users SET last_logged_in = NOW() WHERE username = ?"); $stmt->bind_param("s", $username); $stmt->execute(); $stmt->close(); } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>User Management</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> <style> /* === CSS Styles === */ body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 0; background-color: #f4f7f9; color: #333; font-size: 16px; } .dashboard-container { display: flex; } .sidebar { width: 240px; background-color: #D1B48C; height: 100vh; position: fixed; left: 0; top: 0; overflow-y: auto; box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1); z-index: 1000; } .sidebar-menu { padding: 20px 0; } .sidebar-menu ul { list-style: none; padding: 0; margin: 0; } .sidebar-menu li a { display: flex; align-items: center; padding: 12px 20px; text-decoration: none; color: #000000; transition: background-color 0.3s ease, color: 0.3s ease; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 16px; } .sidebar-menu li a i { margin-right: 12px; width: 20px; text-align: center; flex-shrink: 0; } .sidebar-menu li a:hover { background-color: #ffffff; color: #000000; } .sidebar-menu li.active a { background-color: #be9b7b; color: #000000; font-weight: bold; } .main-content { margin-left: 240px; padding: 25px; flex-grow: 1; display: flex; flex-direction: column; align-items: center; } .header { padding: 18px 30px; margin-bottom: 25px; margin: 0; background: #fff; width: 100%; text-align: left; font-size: 16px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); } .category-content { display: flex; width: 100%; justify-content: space-between; /* space between left and right */ } .form-container, .table-container { flex: 1; /* Allow the forms and tables to take equal space */ margin: 10px; /* Space around each container */ background-color: #fff; padding: 15px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); } .form-container { max-width: 300px; /* Smaller width for the Add New User form */ } h3 { margin: 0 0 15px 0; color: #2f4050; } input[type="text"], input[type="password"], select { width: calc(100% - 22px); /* Full width minus padding */ padding: 10px; margin-bottom: 15px; border: 1px solid #ddd; border-radius: 4px; } button { padding: 10px 15px; border: none; background-color: #007bff; color: white; border-radius: 4px; cursor: pointer; } button:hover { background-color: #0056b3; } table { width: 100%; border-collapse: collapse; margin-bottom: 20px; } th, td { padding: 10px; border: 1px solid #ddd; text-align: left; } th { background-color: #f9f9f9; } tr:hover { background-color: #f5f5f5; } .edit-form { display: none; /* Initially hide edit form */ margin-top: 10px; background-color: #f9f9f9; padding: 10px; border-radius: 4px; shadow: 0 2px 5px rgba(0, 0, 0, 0.1); } </style> </head> <body> <div class="dashboard-container"> <aside class="sidebar"> <div class="sidebar-menu"> <ul> <li><a href="http://localhost/inventory/index.php/admin-page/">Dashboard</a></li> <li><a href="http://localhost/inventory/index.php/usersmanagement/">User Management</a></li> <li><a href="http://localhost/inventory/index.php/category-page/">Categories</a></li> <li><a href="http://localhost/inventory/index.php/products/">Products</a></li> <li><a href="http://localhost/inventory/index.php/order/">Orders</a></li> <li><a href="http://localhost/inventory/index.php/view-order/">View Orders</a></li> <li><a href="http://localhost/inventory/index.php/sales/">Sales & Report</a></li> <li><a href="http://localhost/inventory/index.php/report/">Inventory Report</a></li> <li><a href="http://localhost/inventory/index.php/history/">Inventory History</a></li> <li><a href="http://localhost/inventory/index.php/sign-in2/" onclick="return confirm('Are you sure you want to log out?');">Logout</a></li> </ul> </div> </aside> <main class="main-content"> <div class="header"> <h1>User Management</h1> </div> <section class="category-content"> <!-- Left Side: Add New User Form --> <div class="form-container"> <h3>Add New User</h3> <form action="" method="post"> <input type="text" name="first_name" placeholder="First Name" required> <input type="text" name="last_name" placeholder="Last Name" required> <input type="text" name="username" placeholder="Username" required> <input type="password" name="password" placeholder="Password" required> <button type="submit" name="add_user">Add User</button> </form> </div> <!-- Right Side: Manage Users Table --> <div class="table-container"> <h3>Manage Users</h3> <table> <thead> <tr> <th>#</th> <th>Name</th> <th>Username</th> <th>Date Added</th> <th>Last Logged In</th> <th>Action</th> </tr> </thead> <tbody> <?php foreach ($users as $key => $user) { ?> <tr> <td><?php echo $key + 1; ?></td> <td><?php echo $user['first_name'] . ' ' . $user['last_name']; ?></td> <td><?php echo $user['username']; ?></td> <td><?php echo date('Y-m-d H:i:s', strtotime($user['date_added'])); ?></td> <td><?php echo ($user['last_logged_in']) ? date('Y-m-d H:i:s', strtotime($user['last_logged_in'])) : 'Never'; ?></td> <td> <button class="edit-btn" onclick="toggleEditForm(<?php echo $user['id']; ?>)">Edit</button> <a href="?delete_user=<?php echo $user['id']; ?>" class="btn btn-danger btn-sm" onclick="return confirm('Are you sure you want to delete this user?');">Delete</a> </td> </tr> <tr class="edit-form" id="edit-form-<?php echo $user['id']; ?>"> <td colspan="6"> <form action="" method="post"> <input type="hidden" name="user_id" value="<?php echo $user['id']; ?>"> <input type="text" name="first_name" value="<?php echo $user['first_name']; ?>" required> <input type="text" name="last_name" value="<?php echo $user['last_name']; ?>" required> <input type="text" name="username" value="<?php echo $user['username']; ?>" required> <input type="password" name="password" placeholder="New Password (leave blank to keep current)"> <button type="submit" name="edit_user" class="btn btn-warning btn-sm">Update</button> </form> </td> </tr> <?php } ?> </tbody> </table> </div> </section> </main> </div> <script> function toggleEditForm(userId) { const editForm = document.getElementById('edit-form-' + userId); if (editForm.style.display === 'none' || editForm.style.display === '') { editForm.style.display = 'table-row'; // Show the form } else { editForm.style.display = 'none'; // Hide the form } } </script> </body> </html>
Updated files
v7
the design of the main content, colors of the sidebar navigation menu disappear. you must only add the "ArKi Inventory", dtae and time, user infor.