mirror of
https://github.com/myronblair/tomsjavajive-app
synced 2026-06-30 17:50:56 -05:00
268 lines
12 KiB
PHP
268 lines
12 KiB
PHP
<?php
|
|
ob_start();
|
|
/**
|
|
* Tom's Java Jive - Admin Users Management
|
|
*/
|
|
|
|
$pageTitle = 'Admin Users';
|
|
require_once __DIR__ . '/includes/header.php';
|
|
|
|
// Handle actions
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$action = $_POST['action'] ?? '';
|
|
|
|
if ($action === 'create' || $action === 'update') {
|
|
$userId = $_POST['user_id'] ?? '';
|
|
$email = trim($_POST['email'] ?? '');
|
|
$name = trim($_POST['name'] ?? '');
|
|
$password = $_POST['password'] ?? '';
|
|
$isMaster = isset($_POST['is_master']) ? 1 : 0;
|
|
|
|
$permissions = [
|
|
'dashboard' => isset($_POST['perm_dashboard']),
|
|
'pos' => isset($_POST['perm_pos']),
|
|
'products' => isset($_POST['perm_products']),
|
|
'orders' => isset($_POST['perm_orders']),
|
|
'customers' => isset($_POST['perm_customers']),
|
|
'settings_payment' => isset($_POST['perm_settings']),
|
|
'settings_shipping' => isset($_POST['perm_settings']),
|
|
'settings_email' => isset($_POST['perm_settings']),
|
|
'admin_management' => isset($_POST['perm_admin'])
|
|
];
|
|
|
|
if (empty($email) || empty($name)) {
|
|
setFlash('error', 'Email and name are required');
|
|
} else {
|
|
$data = [
|
|
'email' => strtolower($email),
|
|
'name' => $name,
|
|
'is_master' => $isMaster,
|
|
'permissions' => json_encode($permissions)
|
|
];
|
|
|
|
if ($action === 'update' && $userId) {
|
|
if (!empty($password)) {
|
|
$data['password_hash'] = hashPassword($password);
|
|
}
|
|
db()->update('admin_users', $data, 'user_id = :id', ['id' => $userId]);
|
|
setFlash('success', 'Admin user updated');
|
|
} else {
|
|
if (empty($password)) {
|
|
setFlash('error', 'Password is required for new users');
|
|
} else {
|
|
$existing = db()->fetch("SELECT id FROM admin_users WHERE email = :email", ['email' => strtolower($email)]);
|
|
if ($existing) {
|
|
setFlash('error', 'Email already exists');
|
|
} else {
|
|
$data['user_id'] = generateId('admin_');
|
|
$data['password_hash'] = hashPassword($password);
|
|
$data['is_admin'] = 1;
|
|
db()->insert('admin_users', $data);
|
|
setFlash('success', 'Admin user created');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
header('Location: /admin/users.php');
|
|
exit;
|
|
}
|
|
|
|
if ($action === 'delete' && !empty($_POST['user_id'])) {
|
|
// Don't allow deleting self or last master
|
|
$user = db()->fetch("SELECT is_master FROM admin_users WHERE user_id = :id", ['id' => $_POST['user_id']]);
|
|
if ($user && $user['is_master']) {
|
|
$masterCount = db()->count('admin_users', 'is_master = 1');
|
|
if ($masterCount <= 1) {
|
|
setFlash('error', 'Cannot delete the last master admin');
|
|
header('Location: /admin/users.php');
|
|
exit;
|
|
}
|
|
}
|
|
|
|
db()->delete('admin_users', 'user_id = :id', ['id' => $_POST['user_id']]);
|
|
setFlash('success', 'Admin user deleted');
|
|
header('Location: /admin/users.php');
|
|
exit;
|
|
}
|
|
}
|
|
|
|
$users = db()->fetchAll("SELECT * FROM admin_users ORDER BY is_master DESC, name ASC");
|
|
?>
|
|
|
|
<div class="page-header">
|
|
<h1 class="page-title">Admin Users</h1>
|
|
<button class="btn btn-primary" onclick="openUserModal()">
|
|
<i class="fas fa-plus"></i> Add Admin User
|
|
</button>
|
|
</div>
|
|
|
|
<?php if (hasFlash('success')): ?>
|
|
<div class="alert alert-success"><i class="fas fa-check-circle"></i> <?= getFlash('success') ?></div>
|
|
<?php endif; ?>
|
|
<?php if (hasFlash('error')): ?>
|
|
<div class="alert alert-error"><i class="fas fa-exclamation-circle"></i> <?= getFlash('error') ?></div>
|
|
<?php endif; ?>
|
|
|
|
<div class="admin-card">
|
|
<div class="admin-card-body" style="padding: 0;">
|
|
<table class="admin-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Email</th>
|
|
<th>Role</th>
|
|
<th>Created</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($users as $user): ?>
|
|
<tr>
|
|
<td>
|
|
<strong><?= htmlspecialchars($user['name']) ?></strong>
|
|
<?php if ($user['user_id'] === $adminUser['user_id']): ?>
|
|
<span class="badge badge-primary">You</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td><?= htmlspecialchars($user['email']) ?></td>
|
|
<td>
|
|
<?php if ($user['is_master']): ?>
|
|
<span class="badge badge-warning">Master Admin</span>
|
|
<?php else: ?>
|
|
<span class="badge badge-primary">Admin</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="text-muted"><?= formatDate($user['created_at']) ?></td>
|
|
<td>
|
|
<button class="btn btn-sm btn-secondary" onclick='openUserModal(<?= json_encode($user) ?>)'>
|
|
<i class="fas fa-edit"></i>
|
|
</button>
|
|
<?php if ($user['user_id'] !== $adminUser['user_id']): ?>
|
|
<form method="POST" style="display: inline;">
|
|
<input type="hidden" name="action" value="delete">
|
|
<input type="hidden" name="user_id" value="<?= $user['user_id'] ?>">
|
|
<button type="submit" class="btn btn-sm btn-danger" data-confirm="Delete this admin user?">
|
|
<i class="fas fa-trash"></i>
|
|
</button>
|
|
</form>
|
|
<?php endif; ?>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- User Modal -->
|
|
<div class="modal-overlay" id="userModal">
|
|
<div class="modal">
|
|
<div class="modal-header">
|
|
<h3 class="modal-title" id="userModalTitle">Add Admin User</h3>
|
|
<button type="button" class="modal-close" onclick="Modal.close('userModal')">×</button>
|
|
</div>
|
|
<form method="POST" id="userForm">
|
|
<div class="modal-body">
|
|
<input type="hidden" name="action" id="userAction" value="create">
|
|
<input type="hidden" name="user_id" id="userId">
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">Name *</label>
|
|
<input type="text" name="name" id="userName" class="form-input" required>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">Email *</label>
|
|
<input type="email" name="email" id="userEmail" class="form-input" required>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">Password <span id="passwordRequired">*</span></label>
|
|
<input type="password" name="password" id="userPassword" class="form-input">
|
|
<small class="text-muted" id="passwordHint">Leave blank to keep current password</small>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
|
|
<input type="checkbox" name="is_master" id="userMaster">
|
|
Master Admin (full access)
|
|
</label>
|
|
</div>
|
|
|
|
<div id="permissionsSection">
|
|
<h4 style="margin-bottom: 0.75rem; font-size: 0.9rem;">Permissions</h4>
|
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem;">
|
|
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
|
|
<input type="checkbox" name="perm_dashboard" id="permDashboard" checked> Dashboard
|
|
</label>
|
|
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
|
|
<input type="checkbox" name="perm_pos" id="permPos" checked> POS
|
|
</label>
|
|
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
|
|
<input type="checkbox" name="perm_products" id="permProducts" checked> Products
|
|
</label>
|
|
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
|
|
<input type="checkbox" name="perm_orders" id="permOrders" checked> Orders
|
|
</label>
|
|
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
|
|
<input type="checkbox" name="perm_customers" id="permCustomers" checked> Customers
|
|
</label>
|
|
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
|
|
<input type="checkbox" name="perm_settings" id="permSettings"> Settings
|
|
</label>
|
|
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
|
|
<input type="checkbox" name="perm_admin" id="permAdmin"> Admin Users
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" onclick="Modal.close('userModal')">Cancel</button>
|
|
<button type="submit" class="btn btn-primary" id="userSubmitBtn">Add User</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.getElementById('userMaster').addEventListener('change', function() {
|
|
document.getElementById('permissionsSection').style.display = this.checked ? 'none' : 'block';
|
|
});
|
|
|
|
function openUserModal(user = null) {
|
|
const isEdit = !!user;
|
|
|
|
document.getElementById('userModalTitle').textContent = isEdit ? 'Edit Admin User' : 'Add Admin User';
|
|
document.getElementById('userSubmitBtn').textContent = isEdit ? 'Update User' : 'Add User';
|
|
document.getElementById('userAction').value = isEdit ? 'update' : 'create';
|
|
document.getElementById('userId').value = isEdit ? user.user_id : '';
|
|
document.getElementById('userName').value = isEdit ? user.name : '';
|
|
document.getElementById('userEmail').value = isEdit ? user.email : '';
|
|
document.getElementById('userPassword').value = '';
|
|
document.getElementById('userMaster').checked = isEdit ? user.is_master : false;
|
|
|
|
document.getElementById('passwordRequired').style.display = isEdit ? 'none' : 'inline';
|
|
document.getElementById('passwordHint').style.display = isEdit ? 'block' : 'none';
|
|
document.getElementById('userPassword').required = !isEdit;
|
|
|
|
if (isEdit) {
|
|
const perms = JSON.parse(user.permissions || '{}');
|
|
document.getElementById('permDashboard').checked = perms.dashboard ?? true;
|
|
document.getElementById('permPos').checked = perms.pos ?? true;
|
|
document.getElementById('permProducts').checked = perms.products ?? true;
|
|
document.getElementById('permOrders').checked = perms.orders ?? true;
|
|
document.getElementById('permCustomers').checked = perms.customers ?? true;
|
|
document.getElementById('permSettings').checked = perms.settings_payment ?? false;
|
|
document.getElementById('permAdmin').checked = perms.admin_management ?? false;
|
|
}
|
|
|
|
document.getElementById('permissionsSection').style.display =
|
|
document.getElementById('userMaster').checked ? 'none' : 'block';
|
|
|
|
Modal.open('userModal');
|
|
}
|
|
</script>
|
|
|
|
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|