The first code has no excess space on top of the main content because:
<?php is at the very first line of the file with no whitespace before it?>Here's the key difference from files that might have excess space:
<?php // This is at the very first line with no whitespace before
// All code here
?>
<!-- HTML starts immediately after closing tag -->
<?php // This is at the very first line with no whitespace before
// All code here
?>
<!-- HTML starts immediately after closing tag -->
Versus files with excess space:
// Blank lines or whitespace here
<?php // PHP starts after whitespace
// code
?>
// More whitespace here
<!-- HTML content -->
// Blank lines or whitespace here
<?php // PHP starts after whitespace
// code
?>
// More whitespace here
<!-- HTML content -->
The absence of any whitespace before the opening PHP tag and between the closing PHP tag and HTML content ensures no extra space appears at the top of the rendered page.
The excess space at the top of your page is coming from the WordPress environment and how it processes PHP files. Here are the key reasons and solutions:
WordPress Output Buffering: WordPress starts output buffering before your template loads, which can add whitespace.
Multiple PHP Opening Tags: You have two separate <?php opening tags at the top of your file.
WordPress Headers: WordPress may be sending HTTP headers before your content.
Here's the fixed version that minimizes top space:
<?php
session_start();
global $wpdb;
// --- Configuration ---
$user_table_name = 'users';
$message = '';
$message_type = '';
if (isset($_SESSION['username'])) {
$username = $_SESSION['username'];
$wpdb->update(
$user_table_name,
['last_logged_in' => current_time('mysql')],
['username' => $username]
);
}
// Rest of your PHP code remains exactly the same...
?>
<!DOCTYPE html>
<html lang="en">
<!-- Rest of your HTML remains exactly the same... -->
<?php
session_start();
global $wpdb;
// --- Configuration ---
$user_table_name = 'users';
$message = '';
$message_type = '';
if (isset($_SESSION['username'])) {
$username = $_SESSION['username'];
$wpdb->update(
$user_table_name,
['last_logged_in' => current_time('mysql')],
['username' => $username]
);
}
// Rest of your PHP code remains exactly the same...
?>
<!DOCTYPE html>
<html lang="en">
<!-- Rest of your HTML remains exactly the same... -->
Key changes to implement:
<?phpIf the space persists, it's likely coming from:
To completely eliminate the space, you would need to:
The most reliable solution is to use WordPress's template system properly by:
get_header() and get_footer() functionsYou're right - if the first code works without extra space, then the issue must be in this specific file. Let's fix it by ensuring absolutely no whitespace is output before the HTML. Here's the corrected version:
<?php
session_start();
global $wpdb;
// --- Configuration ---
$user_table_name = 'users'; // Adjust if you use prefixes: $wpdb->prefix . 'users';
$message = ''; // For success/error messages
$message_type = ''; // 'success' or 'error'
if (isset($_SESSION['username'])) {
$username = $_SESSION['username'];
$wpdb->update(
$user_table_name,
['last_logged_in' => current_time('mysql')],
['username' => $username]
);
}
// --- Handle Delete User Action ---
if (isset($_GET['action']) && $_GET['action'] === 'delete_user' && isset($_GET['id']) && isset($_GET['_wpnonce']) && wp_verify_nonce($_GET['_wpnonce'], 'delete_user_' . absint($_GET['id']))) {
$user_id_to_delete = absint($_GET['id']);
if ($user_id_to_delete) {
// Delete user record
$deleted = $wpdb->delete(
$user_table_name,
array('id' => $user_id_to_delete),
array('%d')
);
if ($deleted) {
$message = 'User deleted successfully!';
$message_type = 'success';
} else {
$message = 'Error deleting user.';
$message_type = 'error';
}
}
}
// --- Handle Edit User Action (Prepare form) ---
$editing_user = null; // Initialize editing user variable
if (isset($_GET['action']) && $_GET['action'] === 'edit_user' && isset($_GET['id'])) {
$user_id_to_edit = absint($_GET['id']);
if ($user_id_to_edit) {
$editing_user = $wpdb->get_row(
$wpdb->prepare("SELECT * FROM $user_table_name WHERE id = %d", $user_id_to_edit),
ARRAY_A
);
if (!$editing_user) {
$message = 'User not found for editing.';
$message_type = 'error';
}
}
}
// --- Handle Add/Update User Form Submission ---
if (isset($_POST['add_user'])) {
$first_name = sanitize_text_field($_POST['first_name']);
$last_name = sanitize_text_field($_POST['last_name']);
$username = sanitize_text_field($_POST['username']);
$password = $_POST['password'];
$confirm_password = $_POST['confirm_password'];
if ($password === $confirm_password) {
$hashed_password = password_hash($password, PASSWORD_DEFAULT); // Hash the password
// Insert user with the current timestamp for date_added
$sql = "INSERT INTO $user_table_name (first_name, last_name, username, password, date_added) VALUES ('$first_name', '$last_name', '$username', '$hashed_password', NOW())";
if ($wpdb->query($sql)) {
$message = 'User added successfully!';
$message_type = 'success';
} else {
$message = 'Error adding user.';
$message_type = 'error';
}
} else {
$message = 'Passwords do not match.';
$message_type = 'error';
}
} elseif (isset($_POST['edit_user'])) {
$user_id = absint($_POST['user_id']);
$first_name = sanitize_text_field($_POST['first_name']);
$last_name = sanitize_text_field($_POST['last_name']);
$username = sanitize_text_field($_POST['username']);
$password = $_POST['password'];
$confirm_password = $_POST['confirm_password'];
$user_data = [
'first_name' => $first_name,
'last_name' => $last_name,
'username' => $username
];
if (!empty($password) && $password === $confirm_password) {
$user_data['password'] = password_hash($password, PASSWORD_DEFAULT); // Hash the password
}
$updated = $wpdb->update($user_table_name, $user_data, ['id' => $user_id]);
if ($updated !== false) {
$message = 'User updated successfully!';
$message_type = 'success';
$editing_user = null; // Reset editing user
} else {
$message = 'Error updating user.';
$message_type = 'error';
}
}
// Fetch all users for display
$users = $wpdb->get_results("SELECT * FROM $user_table_name", ARRAY_A);
?><!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>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
background-color: #f4f7f9;
color: #333;
overflow-x: hidden; }
.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 {
position: relative;
top: 0;
left: 240px;
width: calc(100% - 240px);
display: flex;
justify-content: space-between;
align-items: center;
background-color: #77693A;
padding: 15px 30px;
border-bottom: 1px solid #eee;
margin: 0;
z-index: 999;
}
.header-left .date-time {
font-size: 15px; /* Slightly smaller */
color: #fff; /* Darker color */
font-weight: 500; /* Slightly bolder */
}
.header-right {
display: flex;
align-items: center;
/* Removed gap here, gap is now on .user-info */
font-size: 16px; /* Slightly smaller */
color: #ffffff;
}
/* New style for user info container */
.header-right .user-info {
display: flex;
align-items: center; /* Center items horizontally */
gap: 1px; /* Small gap between icon and text */
}
.header-right i {
color: #ffffff; /* Icon color */
font-size:40px; /* Larger icon */
/* Remove margin-right when stacked */
}
.header-right span {
font-size: 15px; /* Smaller font for username */
color: #ffffff;
}
.main-content {
margin-left: 240px;
padding: 0 20px 20px 20px;
flex-grow: 1;
}
.user-management {
display: flex;
flex-wrap: wrap; /* Enables wrapping on smaller screens */
justify-content: space-between;
gap: 20px; /* Adds gap between form and table */
}
.form-container, .table-container {
background-color: #fff;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
padding: 15px;
margin: 10px;
width: 48%; /* Set width for each column */
}
h3 {
margin: 0 0 15px 0;
color: #2f4050;
font-size: 1.5em;
}
input[type="text"], input[type="password"], input[type="email"], select {
width: calc(100% - 22px);
padding: 10px;
margin-bottom: 15px; /* Space between inputs */
border: 1px solid #ddd;
border-radius: 4px;
}
button {
padding: 10px 15px;
border: none;
background-color: #D1B48C;
color: white;
border-radius: 4px;
cursor: pointer;
margin-top: 10px; /** Space above button */
}
.table-container{ flex: 1;}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
th, td {
padding: 10px;
border: 1px solid #ddd;
text-align: left;
}
th {
background-color: #f9f9f9;
}
tr:hover {
background-color: #f5f5f5;
}
.notice-container {
width: 100%;
margin-bottom: 20px;
background-color: #f9f9f9;
}
.notice {
padding: 15px;
margin: 0 10px 20px 10px;
border-radius: 4px;
border-left: 4px solid;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
display: flex;
align-items: center;
}
.notice p {
margin: 0;
padding: 0;
font-size: 16px;
}
.notice-success {
background-color: #f0fff4;
border-color: #38a169;
color: #2f855a;
}
.notice-error {
background-color: #fff5f5;
border-color: #e53e3e;
color: #c53030;
}
.notice i {
margin-right: 10px;
font-size: 18px;
}
.notice-success i {
color: #38a169;
}
.notice-error i {
color: #e53e3e;
}
</style>
</head>
<body>
<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
$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">
<div class="user-info">
<span id="current-username-header">
<?php echo esc_html($current_username); ?>
<i class="fas fa-user-circle"></i>
</span>
</div>
</div>
</header>
<h1>User Management</h1>
<hr/>
<section class="user-management">
<div class="notice-container">
<?php if ($message): ?>
<div class="notice notice-<?php echo esc_attr($message_type); ?>">
<p><?php echo esc_html($message); ?></p>
</div>
<?php endif; ?>
</div>
<div class="form-container"style="max-width: 400px;">
<h2><?php echo $editing_user ? 'Edit User' : 'Add New User'; ?></h2>
<form action="" method="post">
<input type="hidden" name="user_id" value="<?php echo esc_attr($editing_user['id'] ?? ''); ?>">
<input type="text" name="first_name" placeholder="First Name" value="<?php echo esc_attr($editing_user['first_name'] ?? ''); ?>" required>
<input type="text" name="last_name" placeholder="Last Name" value="<?php echo esc_attr($editing_user['last_name'] ?? ''); ?>" required>
<input type="text" name="username" placeholder="Username" value="<?php echo esc_attr($editing_user['username'] ?? ''); ?>" required>
<input type="password" name="password" placeholder="Password (leave blank to keep current)">
<input type="password" name="confirm_password" placeholder="Confirm Password">
<button type="submit" name="<?php echo $editing_user ? 'edit_user' : 'add_user'; ?>">
<?php echo $editing_user ? 'Update User' : 'Add User'; ?>
</button>
</form>
</div>
<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 esc_html($user['first_name'] . ' ' . $user['last_name']); ?></td>
<td><?php echo esc_html($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>
<a href="<?php echo add_query_arg(['action' => 'edit_user', 'id' => $user['id']]); ?>" class="edit">Edit</a>
<a href="<?php echo add_query_arg(['action' => 'delete_user', 'id' => $user['id'], '_wpnonce' => wp_create_nonce('delete_user_' . $user['id'])]); ?>" class="delete" onclick="return confirm('Are you sure you want to delete this user?');">Delete</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</section>
</main>
</div>
<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
session_start();
global $wpdb;
// --- Configuration ---
$user_table_name = 'users'; // Adjust if you use prefixes: $wpdb->prefix . 'users';
$message = ''; // For success/error messages
$message_type = ''; // 'success' or 'error'
if (isset($_SESSION['username'])) {
$username = $_SESSION['username'];
$wpdb->update(
$user_table_name,
['last_logged_in' => current_time('mysql')],
['username' => $username]
);
}
// --- Handle Delete User Action ---
if (isset($_GET['action']) && $_GET['action'] === 'delete_user' && isset($_GET['id']) && isset($_GET['_wpnonce']) && wp_verify_nonce($_GET['_wpnonce'], 'delete_user_' . absint($_GET['id']))) {
$user_id_to_delete = absint($_GET['id']);
if ($user_id_to_delete) {
// Delete user record
$deleted = $wpdb->delete(
$user_table_name,
array('id' => $user_id_to_delete),
array('%d')
);
if ($deleted) {
$message = 'User deleted successfully!';
$message_type = 'success';
} else {
$message = 'Error deleting user.';
$message_type = 'error';
}
}
}
// --- Handle Edit User Action (Prepare form) ---
$editing_user = null; // Initialize editing user variable
if (isset($_GET['action']) && $_GET['action'] === 'edit_user' && isset($_GET['id'])) {
$user_id_to_edit = absint($_GET['id']);
if ($user_id_to_edit) {
$editing_user = $wpdb->get_row(
$wpdb->prepare("SELECT * FROM $user_table_name WHERE id = %d", $user_id_to_edit),
ARRAY_A
);
if (!$editing_user) {
$message = 'User not found for editing.';
$message_type = 'error';
}
}
}
// --- Handle Add/Update User Form Submission ---
if (isset($_POST['add_user'])) {
$first_name = sanitize_text_field($_POST['first_name']);
$last_name = sanitize_text_field($_POST['last_name']);
$username = sanitize_text_field($_POST['username']);
$password = $_POST['password'];
$confirm_password = $_POST['confirm_password'];
if ($password === $confirm_password) {
$hashed_password = password_hash($password, PASSWORD_DEFAULT); // Hash the password
// Insert user with the current timestamp for date_added
$sql = "INSERT INTO $user_table_name (first_name, last_name, username, password, date_added) VALUES ('$first_name', '$last_name', '$username', '$hashed_password', NOW())";
if ($wpdb->query($sql)) {
$message = 'User added successfully!';
$message_type = 'success';
} else {
$message = 'Error adding user.';
$message_type = 'error';
}
} else {
$message = 'Passwords do not match.';
$message_type = 'error';
}
} elseif (isset($_POST['edit_user'])) {
$user_id = absint($_POST['user_id']);
$first_name = sanitize_text_field($_POST['first_name']);
$last_name = sanitize_text_field($_POST['last_name']);
$username = sanitize_text_field($_POST['username']);
$password = $_POST['password'];
$confirm_password = $_POST['confirm_password'];
$user_data = [
'first_name' => $first_name,
'last_name' => $last_name,
'username' => $username
];
if (!empty($password) && $password === $confirm_password) {
$user_data['password'] = password_hash($password, PASSWORD_DEFAULT); // Hash the password
}
$updated = $wpdb->update($user_table_name, $user_data, ['id' => $user_id]);
if ($updated !== false) {
$message = 'User updated successfully!';
$message_type = 'success';
$editing_user = null; // Reset editing user
} else {
$message = 'Error updating user.';
$message_type = 'error';
}
}
// Fetch all users for display
$users = $wpdb->get_results("SELECT * FROM $user_table_name", ARRAY_A);
?><!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>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
background-color: #f4f7f9;
color: #333;
overflow-x: hidden; }
.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 {
position: relative;
top: 0;
left: 240px;
width: calc(100% - 240px);
display: flex;
justify-content: space-between;
align-items: center;
background-color: #77693A;
padding: 15px 30px;
border-bottom: 1px solid #eee;
margin: 0;
z-index: 999;
}
.header-left .date-time {
font-size: 15px; /* Slightly smaller */
color: #fff; /* Darker color */
font-weight: 500; /* Slightly bolder */
}
.header-right {
display: flex;
align-items: center;
/* Removed gap here, gap is now on .user-info */
font-size: 16px; /* Slightly smaller */
color: #ffffff;
}
/* New style for user info container */
.header-right .user-info {
display: flex;
align-items: center; /* Center items horizontally */
gap: 1px; /* Small gap between icon and text */
}
.header-right i {
color: #ffffff; /* Icon color */
font-size:40px; /* Larger icon */
/* Remove margin-right when stacked */
}
.header-right span {
font-size: 15px; /* Smaller font for username */
color: #ffffff;
}
.main-content {
margin-left: 240px;
padding: 0 20px 20px 20px;
flex-grow: 1;
}
.user-management {
display: flex;
flex-wrap: wrap; /* Enables wrapping on smaller screens */
justify-content: space-between;
gap: 20px; /* Adds gap between form and table */
}
.form-container, .table-container {
background-color: #fff;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
padding: 15px;
margin: 10px;
width: 48%; /* Set width for each column */
}
h3 {
margin: 0 0 15px 0;
color: #2f4050;
font-size: 1.5em;
}
input[type="text"], input[type="password"], input[type="email"], select {
width: calc(100% - 22px);
padding: 10px;
margin-bottom: 15px; /* Space between inputs */
border: 1px solid #ddd;
border-radius: 4px;
}
button {
padding: 10px 15px;
border: none;
background-color: #D1B48C;
color: white;
border-radius: 4px;
cursor: pointer;
margin-top: 10px; /** Space above button */
}
.table-container{ flex: 1;}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
th, td {
padding: 10px;
border: 1px solid #ddd;
text-align: left;
}
th {
background-color: #f9f9f9;
}
tr:hover {
background-color: #f5f5f5;
}
.notice-container {
width: 100%;
margin-bottom: 20px;
background-color: #f9f9f9;
}
.notice {
padding: 15px;
margin: 0 10px 20px 10px;
border-radius: 4px;
border-left: 4px solid;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
display: flex;
align-items: center;
}
.notice p {
margin: 0;
padding: 0;
font-size: 16px;
}
.notice-success {
background-color: #f0fff4;
border-color: #38a169;
color: #2f855a;
}
.notice-error {
background-color: #fff5f5;
border-color: #e53e3e;
color: #c53030;
}
.notice i {
margin-right: 10px;
font-size: 18px;
}
.notice-success i {
color: #38a169;
}
.notice-error i {
color: #e53e3e;
}
</style>
</head>
<body>
<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
$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">
<div class="user-info">
<span id="current-username-header">
<?php echo esc_html($current_username); ?>
<i class="fas fa-user-circle"></i>
</span>
</div>
</div>
</header>
<h1>User Management</h1>
<hr/>
<section class="user-management">
<div class="notice-container">
<?php if ($message): ?>
<div class="notice notice-<?php echo esc_attr($message_type); ?>">
<p><?php echo esc_html($message); ?></p>
</div>
<?php endif; ?>
</div>
<div class="form-container"style="max-width: 400px;">
<h2><?php echo $editing_user ? 'Edit User' : 'Add New User'; ?></h2>
<form action="" method="post">
<input type="hidden" name="user_id" value="<?php echo esc_attr($editing_user['id'] ?? ''); ?>">
<input type="text" name="first_name" placeholder="First Name" value="<?php echo esc_attr($editing_user['first_name'] ?? ''); ?>" required>
<input type="text" name="last_name" placeholder="Last Name" value="<?php echo esc_attr($editing_user['last_name'] ?? ''); ?>" required>
<input type="text" name="username" placeholder="Username" value="<?php echo esc_attr($editing_user['username'] ?? ''); ?>" required>
<input type="password" name="password" placeholder="Password (leave blank to keep current)">
<input type="password" name="confirm_password" placeholder="Confirm Password">
<button type="submit" name="<?php echo $editing_user ? 'edit_user' : 'add_user'; ?>">
<?php echo $editing_user ? 'Update User' : 'Add User'; ?>
</button>
</form>
</div>
<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 esc_html($user['first_name'] . ' ' . $user['last_name']); ?></td>
<td><?php echo esc_html($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>
<a href="<?php echo add_query_arg(['action' => 'edit_user', 'id' => $user['id']]); ?>" class="edit">Edit</a>
<a href="<?php echo add_query_arg(['action' => 'delete_user', 'id' => $user['id'], '_wpnonce' => wp_create_nonce('delete_user_' . $user['id'])]); ?>" class="delete" onclick="return confirm('Are you sure you want to delete this user?');">Delete</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</section>
</main>
</div>
<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>
Key changes made:
<?php tag (your editor might show line 1 as empty but it shouldn't contain any invisible characters)If you still see space after this fix:
Here's the fixed code with a working "Cancel" button that removes the product from the order list and restores the stock quantity:
<?php
session_start();
global $wpdb;
// Define your tables
$table_name_categories = 'categories';
$table_name_products = 'products';
$table_name_orders = 'orders';
$table_name_order_items = 'order_items';
$inventory_history_table_name = 'inventory_history';
$message = '';
// Function to log inventory actions
function log_inventory_action($action_type, $item_type, $item_name, $description) {
global $wpdb;
$username = wp_get_current_user()->user_login;
$result = $wpdb->insert(
'inventory_history',
array(
'username' => $username,
'action_type' => $action_type,
'item_type' => $item_type,
'item_name' => $item_name,
'description' => $description,
'timestamp' => current_time('mysql')
),
array('%s', '%s', '%s', '%s', '%s', '%s')
);
return $result;
}
// --- Fetch Categories ---
$categories = $wpdb->get_results("SELECT * FROM $table_name_categories ORDER BY name ASC", ARRAY_A);
// --- Handle Add Order Form Submission ---
if (isset($_POST['add_order']) && isset($_POST['_wpnonce_order_form']) && wp_verify_nonce($_POST['_wpnonce_order_form'], 'add_order_action')) {
$product_name = isset($_POST['product_name']) ? sanitize_text_field($_POST['product_name']) : '';
$quantity = isset($_POST['quantity']) ? absint($_POST['quantity']) : 0;
$unit_price = isset($_POST['unit_price']) ? floatval($_POST['unit_price']) : 0.00;
if (empty($product_name) || !$quantity || !$unit_price) {
$message = 'Invalid product name, quantity, or unit price!';
} else {
$product = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table_name_products WHERE name = %s", $product_name));
if ($product) {
if ($quantity <= $product->{'in_stock'}) {
$amount = $unit_price * $quantity;
// Insert into orders table
$wpdb->insert($table_name_orders, [
'customer_name' => 'Default Customer',
'total_amount' => $amount,
'status' => 'Pending',
'created_at' => current_time('mysql'),
'amount_tendered' => 0.00,
'amount_change' => 0.00
]);
$order_id = $wpdb->insert_id;
// Insert the order item
$wpdb->insert($table_name_order_items, [
'order_id' => $order_id,
'product_id' => $product->id,
'quantity' => $quantity,
'unit_price' => $unit_price,
'amount' => $amount
]);
// Update product stock
$new_stock = $product->{'in_stock'} - $quantity;
$wpdb->update($table_name_products, ['in_stock' => $new_stock], ['id' => $product->id]);
// Log the sale in inventory history
log_inventory_action(
'sell',
'product',
$product_name,
"Sold {$quantity} units of {$product_name}. New stock: {$new_stock}"
);
wp_redirect($_SERVER['REQUEST_URI']);
exit;
} else {
$message = 'Insufficient stock for the product!';
}
} else {
$message = 'Product not found!';
}
}
}
// --- Handle Payment and Cancellation of Orders ---
if (isset($_POST['pay_orders'])) {
$amount_tendered = isset($_POST['amount_tendered']) ? floatval($_POST['amount_tendered']) : 0.00;
$total_orders = $wpdb->get_results("SELECT * FROM $table_name_orders WHERE status = 'Pending'");
foreach ($total_orders as $order) {
$total_amount = $order->total_amount;
$amount_change = $amount_tendered - $total_amount;
$wpdb->update($table_name_orders, [
'status' => 'Paid',
'amount_tendered' => $amount_tendered,
'amount_change' => $amount_change
], ['id' => $order->id]);
}
log_inventory_action(
'update',
'order',
'Multiple Products',
"Marked all pending orders as paid"
);
wp_redirect($_SERVER['REQUEST_URI']);
exit;
}
// --- Handle Order Cancellation ---
if (isset($_POST['cancel_order']) && isset($_POST['_wpnonce_cancel_order']) && wp_verify_nonce($_POST['_wpnonce_cancel_order'], 'cancel_order_action')) {
$order_id = isset($_POST['order_id']) ? absint($_POST['order_id']) : 0;
$product_id = isset($_POST['product_id']) ? absint($_POST['product_id']) : 0;
if ($order_id && $product_id) {
// Get the order item details
$order_item = $wpdb->get_row($wpdb->prepare(
"SELECT oi.*, p.name AS product_name
FROM $table_name_order_items oi
JOIN $table_name_products p ON oi.product_id = p.id
WHERE oi.order_id = %d AND oi.product_id = %d",
$order_id,
$product_id
));
if ($order_item) {
// Restore the product stock
$wpdb->query($wpdb->prepare(
"UPDATE $table_name_products
SET in_stock = in_stock + %d
WHERE id = %d",
$order_item->quantity,
$product_id
));
// Log the stock restoration
log_inventory_action(
'update',
'product',
$order_item->product_name,
"Restored {$order_item->quantity} units of {$order_item->product_name} from cancelled order"
);
// Delete the order item
$wpdb->delete($table_name_order_items, [
'order_id' => $order_id,
'product_id' => $product_id
], ['%d', '%d']);
// Check if this was the last item in the order
$remaining_items = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM $table_name_order_items WHERE order_id = %d",
$order_id
));
if ($remaining_items == 0) {
// Delete the order if no items left
$wpdb->delete($table_name_orders, ['id' => $order_id], ['%d']);
log_inventory_action(
'delete',
'order',
"Order #{$order_id}",
"Cancelled entire order #{$order_id}"
);
}
wp_redirect($_SERVER['REQUEST_URI']);
exit;
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Orders Management</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<style>
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 0; }
.dashboard-container { display: flex; }
.sidebar { width: 240px; background-color: #D1B48C; color: #000000; 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: 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; }
.main-content { margin-left: 240px; padding: 25px; flex-grow: 1; }
.header . h1 { font-size: 20px; font-weight: 500; }
.header {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #77693A;
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: 15px;
color: #ffffff;
font-weight: 500;
}
.header-right {
display: flex;
align-items: center;
font-size: 16px;
color: #ffffff;
}
.header-right .user-info {
display: flex;
align-items: center;
gap: 1px;
}
.header-right i {
color: #ffffff;
font-size:40px;
margin-right: 0;
}
.header-right span {
font-size: 15px;
color: #ffffff;
}
.order-row {
display: flex;
justify-content: space-between;
align-items: center;
gap: 10px;
flex-wrap: nowrap;
}
.order-row input[type="text"],
.order-row input[type="number"] {
width: 20%;
padding: 10px;
}
.order-row button {
padding: 10px 20px;
white-space: nowrap;
}
.form-container, .orders-container { background-color: #fff; padding: 15px; margin-bottom: 20px; }
input, select { width: 100%; padding: 10px; margin: 10px 0; }
button { padding: 12px 24px; font-size: 16px; padding: 10px; background-color: #D1B48C; color: #000000; border: none; cursor: pointer; text-align: middle; }
table { width: 100%; border-collapse: collapse; }
th, td { padding: 10px; border: 1px solid #ddd; font-size: 16px; text-align: center; }
th { background-color: #f2f2f2; }
.align-right {text-align: right; }
</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
$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">
<div class="user-info">
<span id="current-username-header">
<?php echo esc_html($current_username); ?>
<i class="fas fa-user-circle"></i>
</span>
</div>
</div>
</header>
<h1>Order Management</h1>
<hr/>
<?php if (!empty($message)): ?>
<div style="color: red;"><?= esc_html($message); ?></div>
<?php endif; ?>
<div class="form-container">
<h2>Add Order</h2>
<form method="post" action="">
<?php wp_nonce_field('add_order_action', '_wpnonce_order_form'); ?>
<div class="order-row">
<input type="text" id="product_name" name="product_name" required placeholder="Product Name">
<input type="number" id="quantity" name="quantity" min="1" required placeholder="Quantity">
<input type="number" id="unit_price" name="unit_price" step="0.01" required placeholder="Retail Price">
<button type="submit" name="add_order">Add Order</button>
</div>
</form>
</div>
<div class="orders-container">
<h2>Order List</h2>
<table>
<thead>
<tr>
<th>ID</th>
<th>Product</th>
<th>Quantity</th>
<th>Retail Price</th>
<th>Amount</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php
$orders = $wpdb->get_results("SELECT o.*, oi.*, p.name AS product_name FROM $table_name_orders o INNER JOIN $table_name_order_items oi ON o.id = oi.order_id INNER JOIN $table_name_products p ON oi.product_id = p.id WHERE o.status = 'Pending'", ARRAY_A);
$total_amount = 0;
if ($orders) foreach ($orders as $order):
$amount = $order['quantity'] * $order['unit_price'];
$total_amount += $amount;
?>
<tr>
<td><?php echo esc_html($order['id']); ?></td>
<td><?php echo esc_html($order['product_name']); ?></td>
<td><?php echo esc_html($order['quantity']); ?></td>
<td>₱<?php echo esc_html($order['unit_price']); ?></td>
<td>₱<?php echo esc_html($amount); ?></td>
<td><?php echo esc_html($order['status']); ?></td>
<td>
<form method="post" action="" style="display: inline;">
<?php wp_nonce_field('cancel_order_action', '_wpnonce_cancel_order'); ?>
<input type="hidden" name="order_id" value="<?php echo esc_attr($order['id']); ?>">
<input type="hidden" name="product_id" value="<?php echo esc_attr($order['product_id']); ?>">
<button type="submit" name="cancel_order" onclick="return confirm('Are you sure you want to cancel this order? The product quantity will be restored to stock.');">Cancel</button>
</form>
</td>
</tr>
<?php endforeach; ?>
<tr>
<td colspan="5" style="text-align: right;"><strong>Total (₱):</strong></td>
<td colspan="2">₱<?php echo esc_html($total_amount); ?></td>
</tr>
<tr>
<td colspan="5" style="text-align: right;"><strong>Amount Tendered (₱):</strong></td>
<td colspan="3">
<input type="number" id="amount_tendered" name="amount_tendered" placeholder="Enter Amount" step="0.01" value="0.00">
</td>
</tr>
<tr>
<td colspan="5" style="text-align: right;"><strong>Change (₱):</strong></td>
<td colspan="3" id="change_display">₱0.00</td>
</tr>
</tbody>
</table>
<form method="post" action="" style="margin-top: 15px;">
<button type="submit" name="pay_orders">Pay</button>
</form>
</div>
</main>
</div>
<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>
<script>
document.getElementById('amount_tendered').addEventListener('input', function() {
const amountTendered = parseFloat(this.value) || 0;
const totalAmount = <?php echo json_encode($total_amount); ?>;
const change = amountTendered - totalAmount;
document.getElementById('change_display').textContent = '₱' + change.toFixed(2);
});
</script>
</body>
</html>
<?php
session_start();
global $wpdb;
// Define your tables
$table_name_categories = 'categories';
$table_name_products = 'products';
$table_name_orders = 'orders';
$table_name_order_items = 'order_items';
$inventory_history_table_name = 'inventory_history';
$message = '';
// Function to log inventory actions
function log_inventory_action($action_type, $item_type, $item_name, $description) {
global $wpdb;
$username = wp_get_current_user()->user_login;
$result = $wpdb->insert(
'inventory_history',
array(
'username' => $username,
'action_type' => $action_type,
'item_type' => $item_type,
'item_name' => $item_name,
'description' => $description,
'timestamp' => current_time('mysql')
),
array('%s', '%s', '%s', '%s', '%s', '%s')
);
return $result;
}
// --- Fetch Categories ---
$categories = $wpdb->get_results("SELECT * FROM $table_name_categories ORDER BY name ASC", ARRAY_A);
// --- Handle Add Order Form Submission ---
if (isset($_POST['add_order']) && isset($_POST['_wpnonce_order_form']) && wp_verify_nonce($_POST['_wpnonce_order_form'], 'add_order_action')) {
$product_name = isset($_POST['product_name']) ? sanitize_text_field($_POST['product_name']) : '';
$quantity = isset($_POST['quantity']) ? absint($_POST['quantity']) : 0;
$unit_price = isset($_POST['unit_price']) ? floatval($_POST['unit_price']) : 0.00;
if (empty($product_name) || !$quantity || !$unit_price) {
$message = 'Invalid product name, quantity, or unit price!';
} else {
$product = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table_name_products WHERE name = %s", $product_name));
if ($product) {
if ($quantity <= $product->{'in_stock'}) {
$amount = $unit_price * $quantity;
// Insert into orders table
$wpdb->insert($table_name_orders, [
'customer_name' => 'Default Customer',
'total_amount' => $amount,
'status' => 'Pending',
'created_at' => current_time('mysql'),
'amount_tendered' => 0.00,
'amount_change' => 0.00
]);
$order_id = $wpdb->insert_id;
// Insert the order item
$wpdb->insert($table_name_order_items, [
'order_id' => $order_id,
'product_id' => $product->id,
'quantity' => $quantity,
'unit_price' => $unit_price,
'amount' => $amount
]);
// Update product stock
$new_stock = $product->{'in_stock'} - $quantity;
$wpdb->update($table_name_products, ['in_stock' => $new_stock], ['id' => $product->id]);
// Log the sale in inventory history
log_inventory_action(
'sell',
'product',
$product_name,
"Sold {$quantity} units of {$product_name}. New stock: {$new_stock}"
);
wp_redirect($_SERVER['REQUEST_URI']);
exit;
} else {
$message = 'Insufficient stock for the product!';
}
} else {
$message = 'Product not found!';
}
}
}
// --- Handle Payment and Cancellation of Orders ---
if (isset($_POST['pay_orders'])) {
$amount_tendered = isset($_POST['amount_tendered']) ? floatval($_POST['amount_tendered']) : 0.00;
$total_orders = $wpdb->get_results("SELECT * FROM $table_name_orders WHERE status = 'Pending'");
foreach ($total_orders as $order) {
$total_amount = $order->total_amount;
$amount_change = $amount_tendered - $total_amount;
$wpdb->update($table_name_orders, [
'status' => 'Paid',
'amount_tendered' => $amount_tendered,
'amount_change' => $amount_change
], ['id' => $order->id]);
}
log_inventory_action(
'update',
'order',
'Multiple Products',
"Marked all pending orders as paid"
);
wp_redirect($_SERVER['REQUEST_URI']);
exit;
}
// --- Handle Order Cancellation ---
if (isset($_POST['cancel_order']) && isset($_POST['_wpnonce_cancel_order']) && wp_verify_nonce($_POST['_wpnonce_cancel_order'], 'cancel_order_action')) {
$order_id = isset($_POST['order_id']) ? absint($_POST['order_id']) : 0;
$product_id = isset($_POST['product_id']) ? absint($_POST['product_id']) : 0;
if ($order_id && $product_id) {
// Get the order item details
$order_item = $wpdb->get_row($wpdb->prepare(
"SELECT oi.*, p.name AS product_name
FROM $table_name_order_items oi
JOIN $table_name_products p ON oi.product_id = p.id
WHERE oi.order_id = %d AND oi.product_id = %d",
$order_id,
$product_id
));
if ($order_item) {
// Restore the product stock
$wpdb->query($wpdb->prepare(
"UPDATE $table_name_products
SET in_stock = in_stock + %d
WHERE id = %d",
$order_item->quantity,
$product_id
));
// Log the stock restoration
log_inventory_action(
'update',
'product',
$order_item->product_name,
"Restored {$order_item->quantity} units of {$order_item->product_name} from cancelled order"
);
// Delete the order item
$wpdb->delete($table_name_order_items, [
'order_id' => $order_id,
'product_id' => $product_id
], ['%d', '%d']);
// Check if this was the last item in the order
$remaining_items = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM $table_name_order_items WHERE order_id = %d",
$order_id
));
if ($remaining_items == 0) {
// Delete the order if no items left
$wpdb->delete($table_name_orders, ['id' => $order_id], ['%d']);
log_inventory_action(
'delete',
'order',
"Order #{$order_id}",
"Cancelled entire order #{$order_id}"
);
}
wp_redirect($_SERVER['REQUEST_URI']);
exit;
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Orders Management</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<style>
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 0; }
.dashboard-container { display: flex; }
.sidebar { width: 240px; background-color: #D1B48C; color: #000000; 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: 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; }
.main-content { margin-left: 240px; padding: 25px; flex-grow: 1; }
.header . h1 { font-size: 20px; font-weight: 500; }
.header {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #77693A;
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: 15px;
color: #ffffff;
font-weight: 500;
}
.header-right {
display: flex;
align-items: center;
font-size: 16px;
color: #ffffff;
}
.header-right .user-info {
display: flex;
align-items: center;
gap: 1px;
}
.header-right i {
color: #ffffff;
font-size:40px;
margin-right: 0;
}
.header-right span {
font-size: 15px;
color: #ffffff;
}
.order-row {
display: flex;
justify-content: space-between;
align-items: center;
gap: 10px;
flex-wrap: nowrap;
}
.order-row input[type="text"],
.order-row input[type="number"] {
width: 20%;
padding: 10px;
}
.order-row button {
padding: 10px 20px;
white-space: nowrap;
}
.form-container, .orders-container { background-color: #fff; padding: 15px; margin-bottom: 20px; }
input, select { width: 100%; padding: 10px; margin: 10px 0; }
button { padding: 12px 24px; font-size: 16px; padding: 10px; background-color: #D1B48C; color: #000000; border: none; cursor: pointer; text-align: middle; }
table { width: 100%; border-collapse: collapse; }
th, td { padding: 10px; border: 1px solid #ddd; font-size: 16px; text-align: center; }
th { background-color: #f2f2f2; }
.align-right {text-align: right; }
</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
$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">
<div class="user-info">
<span id="current-username-header">
<?php echo esc_html($current_username); ?>
<i class="fas fa-user-circle"></i>
</span>
</div>
</div>
</header>
<h1>Order Management</h1>
<hr/>
<?php if (!empty($message)): ?>
<div style="color: red;"><?= esc_html($message); ?></div>
<?php endif; ?>
<div class="form-container">
<h2>Add Order</h2>
<form method="post" action="">
<?php wp_nonce_field('add_order_action', '_wpnonce_order_form'); ?>
<div class="order-row">
<input type="text" id="product_name" name="product_name" required placeholder="Product Name">
<input type="number" id="quantity" name="quantity" min="1" required placeholder="Quantity">
<input type="number" id="unit_price" name="unit_price" step="0.01" required placeholder="Retail Price">
<button type="submit" name="add_order">Add Order</button>
</div>
</form>
</div>
<div class="orders-container">
<h2>Order List</h2>
<table>
<thead>
<tr>
<th>ID</th>
<th>Product</th>
<th>Quantity</th>
<th>Retail Price</th>
<th>Amount</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php
$orders = $wpdb->get_results("SELECT o.*, oi.*, p.name AS product_name FROM $table_name_orders o INNER JOIN $table_name_order_items oi ON o.id = oi.order_id INNER JOIN $table_name_products p ON oi.product_id = p.id WHERE o.status = 'Pending'", ARRAY_A);
$total_amount = 0;
if ($orders) foreach ($orders as $order):
$amount = $order['quantity'] * $order['unit_price'];
$total_amount += $amount;
?>
<tr>
<td><?php echo esc_html($order['id']); ?></td>
<td><?php echo esc_html($order['product_name']); ?></td>
<td><?php echo esc_html($order['quantity']); ?></td>
<td>₱<?php echo esc_html($order['unit_price']); ?></td>
<td>₱<?php echo esc_html($amount); ?></td>
<td><?php echo esc_html($order['status']); ?></td>
<td>
<form method="post" action="" style="display: inline;">
<?php wp_nonce_field('cancel_order_action', '_wpnonce_cancel_order'); ?>
<input type="hidden" name="order_id" value="<?php echo esc_attr($order['id']); ?>">
<input type="hidden" name="product_id" value="<?php echo esc_attr($order['product_id']); ?>">
<button type="submit" name="cancel_order" onclick="return confirm('Are you sure you want to cancel this order? The product quantity will be restored to stock.');">Cancel</button>
</form>
</td>
</tr>
<?php endforeach; ?>
<tr>
<td colspan="5" style="text-align: right;"><strong>Total (₱):</strong></td>
<td colspan="2">₱<?php echo esc_html($total_amount); ?></td>
</tr>
<tr>
<td colspan="5" style="text-align: right;"><strong>Amount Tendered (₱):</strong></td>
<td colspan="3">
<input type="number" id="amount_tendered" name="amount_tendered" placeholder="Enter Amount" step="0.01" value="0.00">
</td>
</tr>
<tr>
<td colspan="5" style="text-align: right;"><strong>Change (₱):</strong></td>
<td colspan="3" id="change_display">₱0.00</td>
</tr>
</tbody>
</table>
<form method="post" action="" style="margin-top: 15px;">
<button type="submit" name="pay_orders">Pay</button>
</form>
</div>
</main>
</div>
<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>
<script>
document.getElementById('amount_tendered').addEventListener('input', function() {
const amountTendered = parseFloat(this.value) || 0;
const totalAmount = <?php echo json_encode($total_amount); ?>;
const change = amountTendered - totalAmount;
document.getElementById('change_display').textContent = '₱' + change.toFixed(2);
});
</script>
</body>
</html>
Key improvements made to the cancel functionality:
The cancel button now:
I see the issue. The problem is that the cancel_order form isn't properly submitting the data to handle the cancellation. Let me provide a corrected version with a working cancellation functionality:
<?php
// Database connection and start session
session_start();
global $wpdb;
// Define table names
$table_name_products = 'products';
$table_name_orders = 'orders';
$table_name_order_items = 'order_items';
$message = '';
// Handle order cancellation
if (isset($_POST['cancel_order_item']) && isset($_POST['order_id']) && isset($_POST['product_id'])) {
$order_id = intval($_POST['order_id']);
$product_id = intval($_POST['product_id']);
// Get the order item to be cancelled
$order_item = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $table_name_order_items
WHERE order_id = %d AND product_id = %d",
$order_id, $product_id
));
if ($order_item) {
// Restore the product quantity
$wpdb->query($wpdb->prepare(
"UPDATE $table_name_products
SET in_stock = in_stock + %d
WHERE id = %d",
$order_item->quantity,
$product_id
));
// Delete the order item
$wpdb->delete($table_name_order_items, [
'order_id' => $order_id,
'product_id' => $product_id
], ['%d', '%d']);
// Check if this order has any remaining items
$remaining_items = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM $table_name_order_items
WHERE order_id = %d",
$order_id
));
if ($remaining_items == 0) {
// Delete the entire order if no items left
$wpdb->delete($table_name_orders, ['id' => $order_id], ['%d']);
}
$message = "Order item cancelled successfully. Stock has been restored.";
wp_redirect($_SERVER['REQUEST_URI']);
exit;
} else {
$message = "Failed to cancel order item.";
}
}
// Fetch pending orders
$orders = $wpdb->get_results("
SELECT o.id as order_id, oi.*, p.name as product_name
FROM $table_name_orders o
JOIN $table_name_order_items oi ON o.id = oi.order_id
JOIN $table_name_products p ON oi.product_id = p.id
WHERE o.status = 'Pending'
");
// Calculate total amount
$total_amount = 0;
foreach ($orders as $order) {
$total_amount += ($order->quantity * $order->unit_price);
}
?>
<!-- HTML remains the same until the order table -->
<table>
<thead>
<tr>
<th>ID</th>
<th>Product</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Amount</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php foreach ($orders as $order): ?>
<tr>
<td><?php echo esc_html($order->order_id); ?></td>
<td><?php echo esc_html($order->product_name); ?></td>
<td><?php echo esc_html($order->quantity); ?></td>
<td>₱<?php echo number_format($order->unit_price, 2); ?></td>
<td>₱<?php echo number_format($order->quantity * $order->unit_price, 2); ?></td>
<td>
<form method="post" action="">
<input type="hidden" name="order_id" value="<?php echo esc_attr($order->order_id); ?>">
<input type="hidden" name="product_id" value="<?php echo esc_attr($order->product_id); ?>">
<button type="submit" name="cancel_order_item"
onclick="return confirm('Are you sure you want to cancel this order item? Quantity will be restored to stock.');">
Cancel
</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<!-- Rest of your HTML -->
<?php
// Database connection and start session
session_start();
global $wpdb;
// Define table names
$table_name_products = 'products';
$table_name_orders = 'orders';
$table_name_order_items = 'order_items';
$message = '';
// Handle order cancellation
if (isset($_POST['cancel_order_item']) && isset($_POST['order_id']) && isset($_POST['product_id'])) {
$order_id = intval($_POST['order_id']);
$product_id = intval($_POST['product_id']);
// Get the order item to be cancelled
$order_item = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $table_name_order_items
WHERE order_id = %d AND product_id = %d",
$order_id, $product_id
));
if ($order_item) {
// Restore the product quantity
$wpdb->query($wpdb->prepare(
"UPDATE $table_name_products
SET in_stock = in_stock + %d
WHERE id = %d",
$order_item->quantity,
$product_id
));
// Delete the order item
$wpdb->delete($table_name_order_items, [
'order_id' => $order_id,
'product_id' => $product_id
], ['%d', '%d']);
// Check if this order has any remaining items
$remaining_items = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM $table_name_order_items
WHERE order_id = %d",
$order_id
));
if ($remaining_items == 0) {
// Delete the entire order if no items left
$wpdb->delete($table_name_orders, ['id' => $order_id], ['%d']);
}
$message = "Order item cancelled successfully. Stock has been restored.";
wp_redirect($_SERVER['REQUEST_URI']);
exit;
} else {
$message = "Failed to cancel order item.";
}
}
// Fetch pending orders
$orders = $wpdb->get_results("
SELECT o.id as order_id, oi.*, p.name as product_name
FROM $table_name_orders o
JOIN $table_name_order_items oi ON o.id = oi.order_id
JOIN $table_name_products p ON oi.product_id = p.id
WHERE o.status = 'Pending'
");
// Calculate total amount
$total_amount = 0;
foreach ($orders as $order) {
$total_amount += ($order->quantity * $order->unit_price);
}
?>
<!-- HTML remains the same until the order table -->
<table>
<thead>
<tr>
<th>ID</th>
<th>Product</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Amount</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php foreach ($orders as $order): ?>
<tr>
<td><?php echo esc_html($order->order_id); ?></td>
<td><?php echo esc_html($order->product_name); ?></td>
<td><?php echo esc_html($order->quantity); ?></td>
<td>₱<?php echo number_format($order->unit_price, 2); ?></td>
<td>₱<?php echo number_format($order->quantity * $order->unit_price, 2); ?></td>
<td>
<form method="post" action="">
<input type="hidden" name="order_id" value="<?php echo esc_attr($order->order_id); ?>">
<input type="hidden" name="product_id" value="<?php echo esc_attr($order->product_id); ?>">
<button type="submit" name="cancel_order_item"
onclick="return confirm('Are you sure you want to cancel this order item? Quantity will be restored to stock.');">
Cancel
</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<!-- Rest of your HTML -->
Key changes made:
cancel_order to cancel_order_item for clarityintval() for order_id and product_idTo test this:
Make sure your database permissions allow these operations and that your tables have the correct structure (particularly the in_stock field in the products table).*
I'll fix the cancel button to make it clickable again while maintaining all the functionality. Here's the corrected version:
<td>
<form method="post" action="" style="display: inline;">
<input type="hidden" name="order_id" value="<?php echo esc_attr($order['id']); ?>">
<input type="hidden" name="product_id" value="<?php echo esc_attr($order['product_id']); ?>">
<?php wp_nonce_field('cancel_order_action', '_wpnonce_cancel_order'); ?>
<button type="submit" name="cancel_order"
style="background-color: #D1B48C; color: #000; border: none; padding: 8px 12px; cursor: pointer;"
onclick="return confirm('Are you sure you want to cancel this order? The product quantity will be restored to stock.');">
Cancel
</button>
</form>
</td>
<td>
<form method="post" action="" style="display: inline;">
<input type="hidden" name="order_id" value="<?php echo esc_attr($order['id']); ?>">
<input type="hidden" name="product_id" value="<?php echo esc_attr($order['product_id']); ?>">
<?php wp_nonce_field('cancel_order_action', '_wpnonce_cancel_order'); ?>
<button type="submit" name="cancel_order"
style="background-color: #D1B48C; color: #000; border: none; padding: 8px 12px; cursor: pointer;"
onclick="return confirm('Are you sure you want to cancel this order? The product quantity will be restored to stock.');">
Cancel
</button>
</form>
</td>
Key changes made:
Fixed button styling by adding proper CSS styles directly to the button:
Ensured form submission works:
Maintained all functionality:
The button should now:
If you're still having issues, please check:
I understand the issue - the cancellation isn't working properly. Let me provide the complete working solution with all the necessary fixes:
order.php file):// Handle Order Cancellation
if (isset($_POST['cancel_order']) && isset($_POST['order_id']) && isset($_POST['product_id'])) {
$order_id = intval($_POST['order_id']);
$product_id = intval($_POST['product_id']);
// Get order item details
$order_item = $wpdb->get_row($wpdb->prepare(
"SELECT oi.quantity, p.name
FROM $table_name_order_items oi
JOIN $table_name_products p ON oi.product_id = p.id
WHERE oi.order_id = %d AND oi.product_id = %d",
$order_id,
$product_id
));
if ($order_item) {
// Restore stock quantity
$wpdb->query($wpdb->prepare(
"UPDATE $table_name_products
SET in_stock = in_stock + %d
WHERE id = %d",
$order_item->quantity,
$product_id
));
// Delete the order item
$wpdb->delete(
$table_name_order_items,
['order_id' => $order_id, 'product_id' => $product_id],
['%d', '%d']
);
// Redirect to prevent resubmission
wp_redirect($_SERVER['REQUEST_URI']);
exit;
}
}
// Handle Order Cancellation
if (isset($_POST['cancel_order']) && isset($_POST['order_id']) && isset($_POST['product_id'])) {
$order_id = intval($_POST['order_id']);
$product_id = intval($_POST['product_id']);
// Get order item details
$order_item = $wpdb->get_row($wpdb->prepare(
"SELECT oi.quantity, p.name
FROM $table_name_order_items oi
JOIN $table_name_products p ON oi.product_id = p.id
WHERE oi.order_id = %d AND oi.product_id = %d",
$order_id,
$product_id
));
if ($order_item) {
// Restore stock quantity
$wpdb->query($wpdb->prepare(
"UPDATE $table_name_products
SET in_stock = in_stock + %d
WHERE id = %d",
$order_item->quantity,
$product_id
));
// Delete the order item
$wpdb->delete(
$table_name_order_items,
['order_id' => $order_id, 'product_id' => $product_id],
['%d', '%d']
);
// Redirect to prevent resubmission
wp_redirect($_SERVER['REQUEST_URI']);
exit;
}
}
<td>
<form method="post" action="">
<?php wp_nonce_field('cancel_order_action', '_wpnonce_cancel_order'); ?>
<input type="hidden" name="order_id" value="<?php echo esc_attr($order['id']); ?>">
<input type="hidden" name="product_id" value="<?php echo esc_attr($order['product_id']); ?>">
<button type="submit" name="cancel_order" class="btn btn-danger"
onclick="return confirm('Are you sure? Product quantity will be restored to stock.');">
Cancel
</button>
</form>
</td>
<td>
<form method="post" action="">
<?php wp_nonce_field('cancel_order_action', '_wpnonce_cancel_order'); ?>
<input type="hidden" name="order_id" value="<?php echo esc_attr($order['id']); ?>">
<input type="hidden" name="product_id" value="<?php echo esc_attr($order['product_id']); ?>">
<button type="submit" name="cancel_order" class="btn btn-danger"
onclick="return confirm('Are you sure? Product quantity will be restored to stock.');">
Cancel
</button>
</form>
</td>
.btn {
padding: 8px 12px;
border: none;
cursor: pointer;
font-size: 14px;
border-radius: 4px;
}
.btn-danger {
background-color: #ff6b6b;
color: white;
}
.btn-danger:hover {
background-color: #ff5252;
}
.btn {
padding: 8px 12px;
border: none;
cursor: pointer;
font-size: 14px;
border-radius: 4px;
}
.btn-danger {
background-color: #ff6b6b;
color: white;
}
.btn-danger:hover {
background-color: #ff5252;
}
Fixed Form Submission:
Complete Stock Restoration:
Better Button Appearance:
Reliable Order Item Removal:
After clicking Cancel, check:
If still not working:
Let me know if you need any clarification or if you'd like me to see any specific error messages you're encountering. The above solution should handle the cancellation and stock restoration properly.
If you want the cancel functionality to work client-side (without page reload), we'll need to use JavaScript/jQuery with AJAX. Here's how to implement it:
// Add this at the top of your PHP file (after session_start())
if (isset($_POST['ajax_cancel_order'])) {
$order_id = intval($_POST['order_id']);
$product_id = intval($_POST['product_id']);
// Get order item details
$order_item = $wpdb->get_row($wpdb->prepare(
"SELECT oi.quantity, p.name
FROM $table_name_order_items oi
JOIN $table_name_products p ON oi.product_id = p.id
WHERE oi.order_id = %d AND oi.product_id = %d",
$order_id,
$product_id
));
if ($order_item) {
// Restore stock quantity
$wpdb->query($wpdb->prepare(
"UPDATE $table_name_products
SET in_stock = in_stock + %d
WHERE id = %d",
$order_item->quantity,
$product_id
));
// Delete the order item
$wpdb->delete(
$table_name_order_items,
['order_id' => $order_id, 'product_id' => $product_id],
['%d', '%d']
);
wp_send_json_success(['message' => 'Order item cancelled successfully']);
} else {
wp_send_json_error(['message' => 'Failed to cancel order item']);
}
exit;
}
// Add this at the top of your PHP file (after session_start())
if (isset($_POST['ajax_cancel_order'])) {
$order_id = intval($_POST['order_id']);
$product_id = intval($_POST['product_id']);
// Get order item details
$order_item = $wpdb->get_row($wpdb->prepare(
"SELECT oi.quantity, p.name
FROM $table_name_order_items oi
JOIN $table_name_products p ON oi.product_id = p.id
WHERE oi.order_id = %d AND oi.product_id = %d",
$order_id,
$product_id
));
if ($order_item) {
// Restore stock quantity
$wpdb->query($wpdb->prepare(
"UPDATE $table_name_products
SET in_stock = in_stock + %d
WHERE id = %d",
$order_item->quantity,
$product_id
));
// Delete the order item
$wpdb->delete(
$table_name_order_items,
['order_id' => $order_id, 'product_id' => $product_id],
['%d', '%d']
);
wp_send_json_success(['message' => 'Order item cancelled successfully']);
} else {
wp_send_json_error(['message' => 'Failed to cancel order item']);
}
exit;
}
<td>
<button class="cancel-order-btn"
data-order-id="<?php echo esc_attr($order['id']); ?>"
data-product-id="<?php echo esc_attr($order['product_id']); ?>"
style="background-color: #ff6b6b; color: white; padding: 8px 12px; border: none; border-radius: 4px; cursor: pointer;">
Cancel
</button>
</td>
<td>
<button class="cancel-order-btn"
data-order-id="<?php echo esc_attr($order['id']); ?>"
data-product-id="<?php echo esc_attr($order['product_id']); ?>"
style="background-color: #ff6b6b; color: white; padding: 8px 12px; border: none; border-radius: 4px; cursor: pointer;">
Cancel
</button>
</td>
<script>
jQuery(document).ready(function($) {
$('.cancel-order-btn').on('click', function(e) {
e.preventDefault();
if (!confirm('Are you sure? Product quantity will be restored to stock.')) {
return;
}
var button = $(this);
var orderId = button.data('order-id');
var productId = button.data('product-id');
button.prop('disabled', true).text('Processing...');
$.ajax({
url: window.location.href,
type: 'POST',
data: {
ajax_cancel_order: true,
order_id: orderId,
product_id: productId,
_wpnonce: '<?php echo wp_create_nonce("cancel_order_action"); ?>'
},
success: function(response) {
if (response.success) {
// Remove the entire table row
button.closest('tr').fadeOut(300, function() {
$(this).remove();
// Recalculate total amount if needed
calculateTotal();
});
} else {
alert(response.data.message);
button.prop('disabled', false).text('Cancel');
}
},
error: function() {
alert('Error cancelling order. Please try again.');
button.prop('disabled', false).text('Cancel');
}
});
});
function calculateTotal() {
// Implement your total calculation logic here if needed
}
});
</script>
<script>
jQuery(document).ready(function($) {
$('.cancel-order-btn').on('click', function(e) {
e.preventDefault();
if (!confirm('Are you sure? Product quantity will be restored to stock.')) {
return;
}
var button = $(this);
var orderId = button.data('order-id');
var productId = button.data('product-id');
button.prop('disabled', true).text('Processing...');
$.ajax({
url: window.location.href,
type: 'POST',
data: {
ajax_cancel_order: true,
order_id: orderId,
product_id: productId,
_wpnonce: '<?php echo wp_create_nonce("cancel_order_action"); ?>'
},
success: function(response) {
if (response.success) {
// Remove the entire table row
button.closest('tr').fadeOut(300, function() {
$(this).remove();
// Recalculate total amount if needed
calculateTotal();
});
} else {
alert(response.data.message);
button.prop('disabled', false).text('Cancel');
}
},
error: function() {
alert('Error cancelling order. Please try again.');
button.prop('disabled', false).text('Cancel');
}
});
});
function calculateTotal() {
// Implement your total calculation logic here if needed
}
});
</script>
Client-side Experience:
Security:
User Experience:
Database Operations:
If it's still not working:
This solution provides a much smoother user experience while maintaining all the important functionality and security of your order system.