38682-vm/admin/user_edit.php
2026-02-23 17:32:54 +00:00

311 lines
16 KiB
PHP

<?php
require_once __DIR__ . '/../db/config.php';
require_once __DIR__ . '/../includes/functions.php';
$pdo = db();
require_permission('all');
$id = $_GET['id'] ?? null;
$user = null;
if ($id) {
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$user) {
header('Location: users.php');
exit;
}
} else {
// Default values for new user
$user = [
'id' => null,
'username' => '',
'full_name' => '',
'email' => '',
'group_id' => '',
'employee_id' => '',
'is_active' => 1,
'is_ratable' => 0,
'profile_pic' => '',
'created_at' => date('Y-m-d H:i:s')
];
}
$message = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$full_name = $_POST['full_name'];
$username = $_POST['username'];
$email = $_POST['email'];
$group_id = $_POST['group_id'];
$employee_id = $_POST['employee_id'] ?? null;
$is_active = isset($_POST['is_active']) ? 1 : 0;
$is_ratable = isset($_POST['is_ratable']) ? 1 : 0;
$assigned_outlets = $_POST['outlets'] ?? [];
$password = $_POST['password'] ?? '';
// Validation
if (!$id && empty($password)) {
$message = '<div class="alert alert-danger">Password is required for new users.</div>';
} else {
// Check if username already exists
$stmt = $pdo->prepare("SELECT id FROM users WHERE username = ? AND id != ?");
$stmt->execute([$username, (int)$id]);
if ($stmt->fetch()) {
$message = '<div class="alert alert-danger">Username already taken.</div>';
}
}
if (!$message) {
$pdo->beginTransaction();
try {
if ($id) {
// Update
$sql = "UPDATE users SET full_name = ?, username = ?, email = ?, group_id = ?, is_active = ?, is_ratable = ?, employee_id = ? WHERE id = ?";
$params = [$full_name, $username, $email, $group_id, $is_active, $is_ratable, $employee_id, $id];
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
if (!empty($password)) {
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$pdo->prepare("UPDATE users SET password = ? WHERE id = ?")->execute([$hashed_password, $id]);
}
$user_id = $id;
} else {
// Insert
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$sql = "INSERT INTO users (full_name, username, email, group_id, is_active, is_ratable, employee_id, password) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
$params = [$full_name, $username, $email, $group_id, $is_active, $is_ratable, $employee_id, $hashed_password];
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$user_id = $pdo->lastInsertId();
}
// Update assigned outlets
$pdo->prepare("DELETE FROM user_outlets WHERE user_id = ?")->execute([$user_id]);
if (!empty($assigned_outlets)) {
$stmt_outlet = $pdo->prepare("INSERT INTO user_outlets (user_id, outlet_id) VALUES (?, ?)");
foreach ($assigned_outlets as $outlet_id) {
$stmt_outlet->execute([$user_id, $outlet_id]);
}
}
// Handle Profile Picture Upload
if (isset($_FILES['profile_pic']) && $_FILES['profile_pic']['error'] === UPLOAD_ERR_OK) {
$upload_dir = __DIR__ . '/../assets/images/users/';
if (!is_dir($upload_dir)) {
mkdir($upload_dir, 0775, true);
}
$file_tmp = $_FILES['profile_pic']['tmp_name'];
$file_name = $_FILES['profile_pic']['name'];
$file_ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
$allowed_exts = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
if (in_array($file_ext, $allowed_exts)) {
$new_file_name = 'user_' . $user_id . '_' . uniqid() . '.' . $file_ext;
$upload_path = $upload_dir . $new_file_name;
if (move_uploaded_file($file_tmp, $upload_path)) {
// Delete old profile pic if exists
if ($user['profile_pic'] && file_exists(__DIR__ . '/../' . $user['profile_pic'])) {
unlink(__DIR__ . '/../' . $user['profile_pic']);
}
$profile_pic_path = 'assets/images/users/' . $new_file_name;
$pdo->prepare("UPDATE users SET profile_pic = ? WHERE id = ?")->execute([$profile_pic_path, $user_id]);
}
}
}
$pdo->commit();
if ($id) {
$message = '<div class="alert alert-success">User updated successfully!</div>';
} else {
header("Location: user_edit.php?id=$user_id&success=1");
exit;
}
// Refresh user data
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$user_id]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
} catch (Exception $e) {
$pdo->rollBack();
$message = '<div class="alert alert-danger">Error saving user: ' . $e->getMessage() . '</div>';
}
}
}
if (isset($_GET['success'])) {
$message = '<div class="alert alert-success">User created successfully!</div>';
}
$groups = $pdo->query("SELECT * FROM user_groups ORDER BY name")->fetchAll();
$all_outlets = $pdo->query("SELECT * FROM outlets ORDER BY name")->fetchAll();
$assigned_outlet_ids = [];
if ($id) {
$user_outlets = $pdo->prepare("SELECT outlet_id FROM user_outlets WHERE user_id = ?");
$user_outlets->execute([$id]);
$assigned_outlet_ids = $user_outlets->fetchAll(PDO::FETCH_COLUMN);
}
include 'includes/header.php';
?>
<div class="mb-4">
<a href="users.php" class="text-decoration-none text-muted small"><i class="bi bi-arrow-left"></i> Back to Users</a>
<div class="d-flex align-items-center mt-2">
<h2 class="fw-bold mb-0"><?= $id ? 'Edit' : 'Add' ?> User<?= $user['username'] ? ': ' . htmlspecialchars($user['username']) : '' ?></h2>
</div>
</div>
<?= $message ?>
<div class="row">
<div class="col-md-8">
<div class="card border-0 shadow-sm rounded-4 mb-4">
<div class="card-body p-4">
<form method="POST" enctype="multipart/form-data">
<div class="row mb-4">
<div class="col-md-6">
<label class="form-label small fw-bold text-muted">FULL NAME</label>
<input type="text" name="full_name" class="form-control" value="<?= htmlspecialchars($user['full_name']) ?>" required>
</div>
<div class="col-md-6">
<label class="form-label small fw-bold text-muted">USERNAME</label>
<input type="text" name="username" class="form-control" value="<?= htmlspecialchars($user['username']) ?>" required>
</div>
</div>
<div class="row mb-4">
<div class="col-md-6">
<label class="form-label small fw-bold text-muted">EMAIL</label>
<input type="email" name="email" class="form-control" value="<?= htmlspecialchars($user['email']) ?>" required>
</div>
<div class="col-md-6">
<label class="form-label small fw-bold text-muted">EMPLOYEE / BIOMETRIC ID</label>
<input type="text" name="employee_id" class="form-control mb-3" value="<?= htmlspecialchars($user['employee_id'] ?? '') ?>" placeholder="e.g. 101">
<label class="form-label small fw-bold text-muted">USER GROUP / ROLE</label>
<select name="group_id" class="form-select" required>
<option value="">Select Group</option>
<?php foreach ($groups as $group): ?>
<option value="<?= $group['id'] ?>" <?= $user['group_id'] == $group['id'] ? 'selected' : '' ?>><?= htmlspecialchars($group['name']) ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="row mb-4">
<div class="col-md-12">
<label class="form-label small fw-bold text-muted">PROFILE PICTURE</label>
<div class="d-flex align-items-center gap-3">
<?php if ($user['profile_pic']): ?>
<img src="../<?= htmlspecialchars($user['profile_pic']) ?>?v=<?= time() ?>" alt="Profile Picture" class="rounded-circle shadow-sm" style="width: 80px; height: 80px; object-fit: cover;">
<?php else: ?>
<div class="bg-primary bg-gradient text-white rounded-circle d-flex align-items-center justify-content-center shadow-sm" style="width: 80px; height: 80px; font-weight: 700; font-size: 1.5rem;">
<?= strtoupper(substr($user['full_name'] ?: $user['username'] ?: 'U', 0, 1)) ?>
</div>
<?php endif; ?>
<div class="flex-grow-1">
<input type="file" name="profile_pic" class="form-control" accept="image/*">
<div class="form-text mt-1">Allowed: JPG, PNG, GIF, WebP. Recommended: Square image.</div>
</div>
</div>
</div>
</div>
<div class="mb-4">
<label class="form-label small fw-bold text-muted"><?= $id ? 'NEW PASSWORD (LEAVE BLANK TO KEEP CURRENT)' : 'PASSWORD' ?></label>
<input type="password" name="password" class="form-control" placeholder="<?= $id ? '******' : 'Enter password' ?>" <?= $id ? '' : 'required' ?>>
</div>
<div class="mb-4">
<label class="form-label small fw-bold text-muted d-block mb-2">ASSIGNED OUTLETS</label>
<div class="row">
<?php foreach ($all_outlets as $outlet): ?>
<div class="col-md-4 mb-2">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="outlets[]" value="<?= $outlet['id'] ?>" id="outlet_<?= $outlet['id'] ?>" <?= in_array($outlet['id'], $assigned_outlet_ids) ? 'checked' : '' ?>>
<label class="form-check-label small" for="outlet_<?= $outlet['id'] ?>">
<?= htmlspecialchars($outlet['name']) ?>
</label>
</div>
</div>
<?php endforeach; ?>
</div>
<div class="form-text mt-1">Assign one or more outlets to this user.</div>
</div>
<div class="row mb-4">
<div class="col-md-6">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" name="is_active" id="isActiveSwitch" <?= $user['is_active'] ? 'checked' : '' ?>>
<label class="form-check-label fw-bold text-muted small" for="isActiveSwitch">ACTIVE ACCOUNT</label>
</div>
</div>
<div class="col-md-6">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" name="is_ratable" id="isRatableSwitch" <?= $user['is_ratable'] ? 'checked' : '' ?>>
<label class="form-check-label fw-bold text-muted small" for="isRatableSwitch">DISPLAY IN STAFF RATINGS</label>
</div>
<div class="form-text small mt-1">Enable this to allow customers to rate this staff member in the public rating page.</div>
</div>
</div>
<hr class="my-4">
<div class="d-flex justify-content-end gap-2">
<a href="users.php" class="btn btn-light rounded-pill px-4">Cancel</a>
<button type="submit" class="btn btn-primary rounded-pill px-4 fw-bold"><?= $id ? 'Update' : 'Create' ?> User</button>
</div>
</form>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card border-0 shadow-sm rounded-4 bg-primary bg-gradient text-white shadow">
<div class="card-body p-4">
<h5 class="fw-bold mb-3">User Info</h5>
<div class="d-flex align-items-center mb-3">
<?php if ($user['profile_pic']): ?>
<img src="../<?= htmlspecialchars($user['profile_pic']) ?>?v=<?= time() ?>" alt="Profile Picture" class="rounded-circle shadow-sm border border-2 border-white me-3" style="width: 60px; height: 60px; object-fit: cover;">
<?php else: ?>
<div class="bg-white text-primary rounded-circle d-flex align-items-center justify-content-center me-3" style="width:60px;height:60px; font-weight:700; font-size:1.5rem;">
<?= strtoupper(substr($user['full_name'] ?: $user['username'] ?: 'U', 0, 1)) ?>
</div>
<?php endif; ?>
<div>
<div class="fw-bold"><?= htmlspecialchars($user['full_name'] ?: 'New User') ?></div>
<div class="small opacity-75">Member since <?= date('M Y', strtotime($user['created_at'])) ?></div>
</div>
</div>
<div class="small">
<div class="mb-1"><i class="bi bi-envelope me-2"></i> <?= htmlspecialchars($user['email'] ?: 'Email not set') ?></div>
<div><i class="bi bi-person-badge me-2"></i> User ID: <?= $id ? '#' . $id : '<i>New</i>' ?></div>
</div>
<hr class="opacity-25 my-3">
<div class="small">
<div class="fw-bold mb-2">Assigned Outlets:</div>
<?php if (empty($assigned_outlet_ids)): ?>
<div class="opacity-75">No outlets assigned.</div>
<?php else: ?>
<ul class="list-unstyled mb-0 opacity-75">
<?php foreach ($all_outlets as $outlet): ?>
<?php if (in_array($outlet['id'], $assigned_outlet_ids)): ?>
<li><i class="bi bi-geo-alt me-1"></i> <?= htmlspecialchars($outlet['name']) ?></li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div>
<?php include 'includes/footer.php'; ?>