Managed Users

This commit is contained in:
Flatlogic Bot 2025-12-05 06:55:18 +00:00
parent 7c1bf16409
commit 9fa23089ba
11 changed files with 410 additions and 8 deletions

View File

@ -14,7 +14,7 @@ $pageTitle = 'All Change Requests';
// Fetch all requests from the database
try {
$pdoconn = db();
$stmt = $pdoconn->prepare('SELECT cr.*, u.username as requester_name FROM change_requests cr JOIN users u ON cr.requester_id = u.id ORDER BY cr.created_at DESC');
$stmt = $pdoconn->prepare('SELECT cr.*, u.username as requester_name, cr.related_cr_no FROM change_requests cr JOIN users u ON cr.requester_id = u.id ORDER BY cr.created_at DESC');
$stmt->execute();
$requests = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
@ -45,6 +45,7 @@ try {
<thead class="thead-dark">
<tr>
<th>ID</th>
<th>Related CR No.</th>
<th>Change Title</th>
<th>Requester</th>
<th>Status</th>
@ -56,6 +57,7 @@ try {
<?php foreach ($requests as $request): ?>
<tr>
<td><?= htmlspecialchars($request['id']) ?></td>
<td><?= htmlspecialchars($request['related_cr_no']) ?></td>
<td><?= htmlspecialchars($request['change_title']) ?></td>
<td><?= htmlspecialchars($request['requester_name']) ?></td>
<td><?= displayStatusBadge($request['status']) ?></td>

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

75
create_user.php Normal file
View File

@ -0,0 +1,75 @@
<?php
session_start();
require_once 'auth_check.php';
require_once 'db/config.php';
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'admin') {
header('Location: login.php');
exit;
}
$error = '';
$success = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username']);
$password = $_POST['password'];
$role = $_POST['role'];
if (empty($username) || empty($password) || empty($role)) {
$error = 'All fields are required.';
} else {
$pdo = db();
$stmt = $pdo->prepare('SELECT id FROM users WHERE username = :username');
$stmt->execute(['username' => $username]);
if ($stmt->fetch()) {
$error = 'Username or email already exists.';
} else {
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare('INSERT INTO users (username, password, role) VALUES (:username, :password, :role)');
if ($stmt->execute(['username' => $username, 'password' => $hashed_password, 'role' => $role])) {
$success = 'User created successfully.';
} else {
$error = 'Failed to create user.';
}
}
}
}
?>
<?php include 'header.php'; ?>
<div class="container mt-4">
<h2>Create User</h2>
<?php if ($error): ?>
<div class="alert alert-danger"><?php echo $error; ?></div>
<?php endif; ?>
<?php if ($success): ?>
<div class="alert alert-success"><?php echo $success; ?></div>
<?php endif; ?>
<form action="create_user.php" method="post">
<div class="form-group">
<label for="username">Username</label>
<input type="text" name="username" class="form-control" id="username" required>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" name="password" class="form-control" id="password" required>
</div>
<div class="form-group">
<label for="role">Role</label>
<select name="role" class="form-control" id="role">
<option value="user">User</option>
<option value="admin">Admin</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Create User</button>
<a href="manage_users.php" class="btn btn-secondary">Back to Manage Users</a>
</form>
</div>
<?php include 'footer.php'; ?>

36
delete_user.php Normal file
View File

@ -0,0 +1,36 @@
<?php
session_start();
require_once 'auth_check.php';
require_once 'db/config.php';
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'admin') {
header('Location: login.php');
exit;
}
$user_id = $_GET['id'] ?? null;
if (!$user_id) {
header('Location: manage_users.php');
exit;
}
// Prevent admin from deleting their own account
if ($user_id == $_SESSION['user_id']) {
$_SESSION['error_message'] = 'You cannot delete your own account.';
header('Location: manage_users.php');
exit;
}
$pdoconfig = db();
$pdo = new PDO($pdoconfig['dsn'], $pdoconfig['user'], $pdoconfig['pass'], $pdoconfig['options']);
$stmt = $pdo->prepare('DELETE FROM users WHERE id = :id');
if ($stmt->execute(['id' => $user_id])) {
$_SESSION['success_message'] = 'User deleted successfully.';
} else {
$_SESSION['error_message'] = 'Failed to delete user.';
}
header('Location: manage_users.php');
exit;
?>

93
edit_user.php Normal file
View File

@ -0,0 +1,93 @@
<?php
session_start();
require_once 'auth_check.php';
require_once 'db/config.php';
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'admin') {
header('Location: login.php');
exit;
}
$user_id = $_GET['id'] ?? null;
if (!$user_id) {
header('Location: manage_users.php');
exit;
}
$pdo = db();
$error = '';
$success = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username']);
$role = $_POST['role'];
$password = $_POST['password'];
if (empty($username) || empty($role)) {
$error = 'Username and role are required.';
} else {
$sql = 'UPDATE users SET username = :username, role = :role';
$params = ['username' => $username, 'role' => $role, 'id' => $user_id];
if (!empty($password)) {
$sql .= ', password = :password';
$params['password'] = password_hash($password, PASSWORD_DEFAULT);
}
$sql .= ' WHERE id = :id';
$stmt = $pdo->prepare($sql);
if ($stmt->execute($params)) {
$success = 'User updated successfully.';
} else {
$error = 'Failed to update user.';
}
}
}
$stmt = $pdo->prepare('SELECT username, role FROM users WHERE id = :id');
$stmt->execute(['id' => $user_id]);
$user = $stmt->fetch();
if (!$user) {
header('Location: manage_users.php');
exit;
}
?>
<?php include 'header.php'; ?>
<div class="container mt-4">
<h2>Edit User</h2>
<?php if ($error): ?>
<div class="alert alert-danger"><?php echo $error; ?></div>
<?php endif; ?>
<?php if ($success): ?>
<div class="alert alert-success"><?php echo $success; ?></div>
<?php endif; ?>
<form action="edit_user.php?id=<?php echo $user_id; ?>" method="post">
<div class="form-group">
<label for="username">Username</label>
<input type="text" name="username" class="form-control" id="username" value="<?php echo htmlspecialchars($user['username']); ?>" required>
</div>
<div class="form-group">
<label for="password">Password (leave blank to keep current password)</label>
<input type="password" name="password" class="form-control" id="password">
</div>
<div class="form-group">
<label for="role">Role</label>
<select name="role" class="form-control" id="role">
<option value="user" <?php echo ($user['role'] === 'user') ? 'selected' : ''; ?>>User</option>
<option value="admin" <?php echo ($user['role'] === 'admin') ? 'selected' : ''; ?>>Admin</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Update User</button>
<a href="manage_users.php" class="btn btn-secondary">Back to Manage Users</a>
</form>
</div>
<?php include 'footer.php'; ?>

6
footer.php Normal file
View File

@ -0,0 +1,6 @@
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>

View File

@ -5,8 +5,22 @@ if (session_status() === PHP_SESSION_NONE) {
$is_logged_in = isset($_SESSION["user_id"]);
$username = $is_logged_in ? $_SESSION["username"] : "";
$is_admin = $is_logged_in && $_SESSION['role'] === 'admin';
$page_title = basename($_SERVER['PHP_SELF'], '.php');
$page_title = str_replace('_', ' ', $page_title);
$page_title = ucwords($page_title);
?>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title><?php echo $page_title; ?> - Change Request System</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="index.php">Change Request System</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
@ -30,6 +44,9 @@ $is_admin = $is_logged_in && $_SESSION['role'] === 'admin';
<li class="nav-item">
<a class="nav-link" href="all_requests.php">All Requests</a>
</li>
<li class="nav-item">
<a class="nav-link" href="manage_users.php">Manage Users</a>
</li>
<?php endif; ?>
<?php endif; ?>
</ul>
@ -49,3 +66,4 @@ $is_admin = $is_logged_in && $_SESSION['role'] === 'admin';
</ul>
</div>
</nav>

84
manage_users.php Normal file
View File

@ -0,0 +1,84 @@
<?php
session_start();
require_once 'auth_check.php';
require_once 'db/config.php';
require_once 'includes/helpers.php';
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'admin') {
header('Location: login.php');
exit;
}
$pdo = db();
$users = $pdo->query('SELECT id, username, role FROM users')->fetchAll();
?>
<?php include 'header.php'; ?>
<h2>Manage Users</h2>
<?php
if (isset($_SESSION['upload_success']) && $_SESSION['upload_success']) {
echo '<div class="alert alert-success">' . $_SESSION['upload_success'] . '</div>';
unset($_SESSION['upload_success']);
}
if (isset($_SESSION['upload_error']) && $_SESSION['upload_error']) {
echo '<div class="alert alert-danger">' . $_SESSION['upload_error'] . '</div>';
unset($_SESSION['upload_error']);
}
if (isset($_SESSION['success_message']) && $_SESSION['success_message']) {
echo '<div class="alert alert-success">' . $_SESSION['success_message'] . '</div>';
unset($_SESSION['success_message']);
}
if (isset($_SESSION['error_message']) && $_SESSION['error_message']) {
echo '<div class="alert alert-danger">' . $_SESSION['error_message'] . '</div>';
unset($_SESSION['error_message']);
}
?>
<div class="card mb-4">
<div class="card-header">Create Users</div>
<div class="card-body">
<a href="create_user.php" class="btn btn-success">Create Single User</a>
<hr>
<h5>Upload CSV to Create Users</h5>
<form action="upload_users_csv.php" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="csv_file">Select CSV file</label>
<input type="file" name="csv_file" class="form-control-file" id="csv_file" accept=".csv" required>
</div>
<button type="submit" class="btn btn-primary">Upload and Create</button>
</form>
</div>
</div>
<div class="card">
<div class="card-header">Existing Users</div>
<div class="card-body">
<table class="table table-striped">
<thead>
<tr>
<th>Username</th>
<th>Role</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($users as $user): ?>
<tr>
<td><?php echo htmlspecialchars($user['username']); ?></td>
<td><?php echo htmlspecialchars($user['role']); ?></td>
<td>
<a href="edit_user.php?id=<?php echo $user['id']; ?>" class="btn btn-sm btn-warning">Edit</a>
<a href="delete_user.php?id=<?php echo $user['id']; ?>" class="btn btn-sm btn-danger" onclick="return confirm('Are you sure you want to delete this user?');">Delete</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<?php include 'footer.php'; // Assuming you have a footer file ?>

View File

@ -9,7 +9,7 @@ $userId = $_SESSION['user_id'];
// Fetch requests for the logged-in user
try {
$pdoconn = db();
$stmt = $pdoconn->prepare('SELECT * FROM change_requests WHERE requester_id = :requester_id ORDER BY created_at DESC');
$stmt = $pdoconn->prepare('SELECT id, change_title, related_cr_no, status, created_at FROM change_requests WHERE requester_id = :requester_id ORDER BY created_at DESC');
$stmt->bindParam(':requester_id', $userId, PDO::PARAM_INT);
$stmt->execute();
$requests = $stmt->fetchAll(PDO::FETCH_ASSOC);
@ -43,6 +43,7 @@ try {
<tr>
<th>ID</th>
<th>Change Title</th>
<th>Related CR No.</th>
<th>Status</th>
<th>Submitted On</th>
</tr>
@ -52,6 +53,7 @@ try {
<tr>
<td><?= htmlspecialchars($request['id']) ?></td>
<td><?= htmlspecialchars($request['change_title']) ?></td>
<td><?= htmlspecialchars($request['related_cr_no'] ?? 'N/A') ?></td>
<td><?= displayStatusBadge($request['status']) ?></td>
<td><?= htmlspecialchars(date('Y-m-d H:i', strtotime($request['created_at']))) ?></td>
</tr>

87
upload_users_csv.php Normal file
View File

@ -0,0 +1,87 @@
<?php
session_start();
require_once 'auth_check.php';
require_once 'db/config.php';
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'admin') {
header('Location: login.php');
exit;
}
$error = '';
$success = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['csv_file'])) {
$file = $_FILES['csv_file']['tmp_name'];
$handle = fopen($file, "r");
if ($handle !== FALSE) {
$pdoconfig = db();
$pdo = new PDO($pdoconfig['dsn'], $pdoconfig['user'], $pdoconfig['pass'], $pdoconfig['options']);
$pdo->beginTransaction();
// Skip header row
fgetcsv($handle, 1000, ",");
$created_count = 0;
$error_count = 0;
$errors = [];
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$username = trim($data[0]);
$email = trim($data[1]);
$password = $data[2];
$role = trim($data[3]);
if (empty($username) || empty($email) || empty($password) || empty($role)) {
$errors[] = "Skipping row: required field is empty.";
$error_count++;
continue;
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = "Skipping row for email {$email}: invalid email format.";
$error_count++;
continue;
}
$stmt = $pdo->prepare('SELECT id FROM users WHERE username = :username OR email = :email');
$stmt->execute(['username' => $username, 'email' => $email]);
if ($stmt->fetch()) {
$errors[] = "Skipping row for user {$username}: username or email already exists.";
$error_count++;
continue;
}
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare('INSERT INTO users (username, email, password, role) VALUES (:username, :email, :password, :role)');
if ($stmt->execute(['username' => $username, 'email' => $email, 'password' => $hashed_password, 'role' => $role])) {
$created_count++;
} else {
$errors[] = "Failed to create user {$username}.";
$error_count++;
}
}
fclose($handle);
if ($error_count === 0) {
$pdo->commit();
$success = "{$created_count} users created successfully.";
} else {
$pdo->rollBack();
$error = "There were {$error_count} errors creating users. No users were created. Errors: <br>" . implode("<br>", $errors);
}
$_SESSION['upload_success'] = $success;
$_SESSION['upload_error'] = $error;
} else {
$_SESSION['upload_error'] = 'Failed to open CSV file.';
}
header("Location: manage_users.php");
exit;
} else {
header('Location: manage_users.php');
exit;
}

View File

@ -13,11 +13,10 @@ if (!$requestId) {
// Fetch the request and requester info
try {
$pdoconn = db();
$stmt = $pdoconn->prepare('SELECT cr.*, u.full_name as requester_full_name, u.username as requester_username, cr.related_request_id FROM change_requests cr JOIN users u ON cr.requester_id = u.id WHERE cr.id = :id');
$stmt = $pdoconn->prepare('SELECT cr.*, u.full_name as requester_full_name, u.username as requester_username FROM change_requests cr JOIN users u ON cr.requester_id = u.id WHERE cr.id = :id');
$stmt->bindParam(':id', $requestId, PDO::PARAM_INT);
$stmt->execute();
$request = $stmt->fetch(PDO::FETCH_ASSOC);
var_dump($request);
} catch (PDOException $e) {
$request = null;
error_log("DB Error: " . $e->getMessage());
@ -63,8 +62,8 @@ if (!$request) {
<p><strong>Submission Date:</strong> <?= date('Y-m-d H:i', strtotime($request['created_at'])) ?></p>
<p><strong>Category:</strong> <?= htmlspecialchars($request['change_category']) ?></p>
<p><strong>Program Name:</strong> <?= htmlspecialchars($request['program_name']) ?></p>
<?php if (!empty($request['related_request_id'])): ?>
<p><strong>Related Change Request No:</strong> <a href="view_request.php?id=<?= htmlspecialchars($request['related_request_id']) ?>"><?= htmlspecialchars($request['related_request_id']) ?></a></p>
<?php if (!empty($request['related_request_no'])): ?>
<p><strong>Related Change Request No:</strong> <a href="view_request.php?id=<?= htmlspecialchars($request['related_request_no']) ?>"><?= htmlspecialchars($request['related_request_no']) ?></a></p>
<?php endif; ?>
</div>
</div>
@ -112,4 +111,4 @@ if (!$request) {
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.2/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>
</html>