v3
This commit is contained in:
parent
0e7e15ad6d
commit
d9ae8f552d
196
bunks.php
196
bunks.php
@ -4,28 +4,67 @@ require_once 'db/config.php';
|
|||||||
|
|
||||||
$notification = null;
|
$notification = null;
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_bunk'])) {
|
// Handle Add, Edit, Delete actions
|
||||||
$name = trim($_POST['name']);
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
$owner = trim($_POST['owner']);
|
$db = db();
|
||||||
$contact = trim($_POST['contact']);
|
// Add Bunk
|
||||||
$location = trim($_POST['location']);
|
if (isset($_POST['add_bunk'])) {
|
||||||
|
$name = trim($_POST['name']);
|
||||||
|
$owner = trim($_POST['owner']);
|
||||||
|
$contact = trim($_POST['contact']);
|
||||||
|
$location = trim($_POST['location']);
|
||||||
|
|
||||||
if (!empty($name)) {
|
if (!empty($name)) {
|
||||||
try {
|
try {
|
||||||
$db = db();
|
$stmt = $db->prepare("INSERT INTO bunks (name, owner, contact, location) VALUES (?, ?, ?, ?)");
|
||||||
$stmt = $db->prepare("INSERT INTO bunks (name, owner, contact, location) VALUES (?, ?, ?, ?)");
|
$stmt->execute([$name, $owner, $contact, $location]);
|
||||||
$stmt->execute([$name, $owner, $contact, $location]);
|
$_SESSION['notification'] = ['text' => 'Bunk added successfully!', 'type' => 'success'];
|
||||||
$_SESSION['notification'] = ['text' => 'Bunk added successfully!', 'type' => 'success'];
|
} catch (PDOException $e) {
|
||||||
} catch (PDOException $e) {
|
$_SESSION['notification'] = ['text' => 'Error adding bunk: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
$_SESSION['notification'] = ['text' => 'Error adding bunk: ' . $e->getMessage(), 'type' => 'danger'];
|
}
|
||||||
|
} else {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Bunk name is required.', 'type' => 'warning'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Edit Bunk
|
||||||
|
elseif (isset($_POST['edit_bunk'])) {
|
||||||
|
$id = $_POST['bunk_id'];
|
||||||
|
$name = trim($_POST['name']);
|
||||||
|
$owner = trim($_POST['owner']);
|
||||||
|
$contact = trim($_POST['contact']);
|
||||||
|
$location = trim($_POST['location']);
|
||||||
|
|
||||||
|
if (!empty($name) && !empty($id)) {
|
||||||
|
try {
|
||||||
|
$stmt = $db->prepare("UPDATE bunks SET name = ?, owner = ?, contact = ?, location = ? WHERE id = ?");
|
||||||
|
$stmt->execute([$name, $owner, $contact, $location, $id]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Bunk updated successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error updating bunk: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Bunk name and ID are required.', 'type' => 'warning'];
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
$_SESSION['notification'] = ['text' => 'Bunk name is required.', 'type' => 'warning'];
|
|
||||||
}
|
}
|
||||||
header("Location: bunks.php");
|
header("Location: bunks.php");
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete Bunk
|
||||||
|
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
|
||||||
|
try {
|
||||||
|
$db = db();
|
||||||
|
$stmt = $db->prepare("DELETE FROM bunks WHERE id = ?");
|
||||||
|
$stmt->execute([$_GET['id']]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Bunk deleted successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error deleting bunk: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
header("Location: bunks.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (isset($_SESSION['notification'])) {
|
if (isset($_SESSION['notification'])) {
|
||||||
$notification = $_SESSION['notification'];
|
$notification = $_SESSION['notification'];
|
||||||
unset($_SESSION['notification']);
|
unset($_SESSION['notification']);
|
||||||
@ -70,24 +109,7 @@ try {
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<nav class="navbar navbar-expand-lg navbar-dark shadow-sm">
|
<?php include 'includes/header.php'; ?>
|
||||||
<div class="container">
|
|
||||||
<a class="navbar-brand" href="index.php">Bunk Admin</a>
|
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
|
||||||
</button>
|
|
||||||
<div class="collapse navbar-collapse" id="navbarNav">
|
|
||||||
<ul class="navbar-nav">
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="index.php">Dashboard</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link active" href="bunks.php">Bunks</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="container mt-4">
|
<div class="container mt-4">
|
||||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||||
@ -125,8 +147,20 @@ try {
|
|||||||
<td><?= htmlspecialchars($bunk['location']) ?></td>
|
<td><?= htmlspecialchars($bunk['location']) ?></td>
|
||||||
<td><?= date('d M, Y', strtotime($bunk['created_at'])) ?></td>
|
<td><?= date('d M, Y', strtotime($bunk['created_at'])) ?></td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn btn-sm btn-outline-secondary"><i class="bi bi-pencil"></i></button>
|
<button type="button" class="btn btn-sm btn-outline-secondary edit-btn"
|
||||||
<button class="btn btn-sm btn-outline-danger"><i class="bi bi-trash"></i></button>
|
data-bs-toggle="modal" data-bs-target="#editBunkModal"
|
||||||
|
data-id="<?= $bunk['id'] ?>"
|
||||||
|
data-name="<?= htmlspecialchars($bunk['name']) ?>"
|
||||||
|
data-owner="<?= htmlspecialchars($bunk['owner']) ?>"
|
||||||
|
data-contact="<?= htmlspecialchars($bunk['contact']) ?>"
|
||||||
|
data-location="<?= htmlspecialchars($bunk['location']) ?>">
|
||||||
|
<i class="bi bi-pencil"></i>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-danger delete-btn"
|
||||||
|
data-bs-toggle="modal" data-bs-target="#deleteConfirmModal"
|
||||||
|
data-id="<?= $bunk['id'] ?>">
|
||||||
|
<i class="bi bi-trash"></i>
|
||||||
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
@ -174,6 +208,63 @@ try {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Edit Bunk Modal -->
|
||||||
|
<div class="modal fade" id="editBunkModal" tabindex="-1" aria-labelledby="editBunkModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<form action="bunks.php" method="POST">
|
||||||
|
<input type="hidden" name="bunk_id" id="edit_bunk_id">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="editBunkModalLabel">Edit Bunk</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="edit_name" class="form-label">Bunk Name*</label>
|
||||||
|
<input type="text" class="form-control" id="edit_name" name="name" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="edit_owner" class="form-label">Owner</label>
|
||||||
|
<input type="text" class="form-control" id="edit_owner" name="owner">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="edit_contact" class="form-label">Contact</label>
|
||||||
|
<input type="text" class="form-control" id="edit_contact" name="contact">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="edit_location" class="form-label">Location</label>
|
||||||
|
<textarea class="form-control" id="edit_location" name="location" rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" name="edit_bunk" class="btn btn-primary">Save Changes</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Delete Confirmation Modal -->
|
||||||
|
<div class="modal fade" id="deleteConfirmModal" tabindex="-1" aria-labelledby="deleteConfirmModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="deleteConfirmModalLabel">Confirm Deletion</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
Are you sure you want to delete this bunk? This action cannot be undone.
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||||
|
<a href="#" id="delete-confirm-btn" class="btn btn-danger">Delete</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- Toast Notification -->
|
<!-- Toast Notification -->
|
||||||
<div class="position-fixed bottom-0 end-0 p-3 toast-container">
|
<div class="position-fixed bottom-0 end-0 p-3 toast-container">
|
||||||
<div id="notificationToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
|
<div id="notificationToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
@ -189,6 +280,7 @@ try {
|
|||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
// Toast notification
|
||||||
<?php if ($notification): ?>
|
<?php if ($notification): ?>
|
||||||
const toastEl = document.getElementById('notificationToast');
|
const toastEl = document.getElementById('notificationToast');
|
||||||
const toastBody = toastEl.querySelector('.toast-body');
|
const toastBody = toastEl.querySelector('.toast-body');
|
||||||
@ -200,6 +292,40 @@ try {
|
|||||||
const toast = new bootstrap.Toast(toastEl);
|
const toast = new bootstrap.Toast(toastEl);
|
||||||
toast.show();
|
toast.show();
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
// Edit modal handler
|
||||||
|
const editBunkModal = document.getElementById('editBunkModal');
|
||||||
|
editBunkModal.addEventListener('show.bs.modal', function (event) {
|
||||||
|
const button = event.relatedTarget;
|
||||||
|
const id = button.getAttribute('data-id');
|
||||||
|
const name = button.getAttribute('data-name');
|
||||||
|
const owner = button.getAttribute('data-owner');
|
||||||
|
const contact = button.getAttribute('data-contact');
|
||||||
|
const location = button.getAttribute('data-location');
|
||||||
|
|
||||||
|
const modalTitle = editBunkModal.querySelector('.modal-title');
|
||||||
|
const modalBodyInputId = editBunkModal.querySelector('#edit_bunk_id');
|
||||||
|
const modalBodyInputName = editBunkModal.querySelector('#edit_name');
|
||||||
|
const modalBodyInputOwner = editBunkModal.querySelector('#edit_owner');
|
||||||
|
const modalBodyInputContact = editBunkModal.querySelector('#edit_contact');
|
||||||
|
const modalBodyInputLocation = editBunkModal.querySelector('#edit_location');
|
||||||
|
|
||||||
|
modalTitle.textContent = 'Edit Bunk: ' + name;
|
||||||
|
modalBodyInputId.value = id;
|
||||||
|
modalBodyInputName.value = name;
|
||||||
|
modalBodyInputOwner.value = owner;
|
||||||
|
modalBodyInputContact.value = contact;
|
||||||
|
modalBodyInputLocation.value = location;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete confirmation handler
|
||||||
|
const deleteConfirmModal = document.getElementById('deleteConfirmModal');
|
||||||
|
deleteConfirmModal.addEventListener('show.bs.modal', function (event) {
|
||||||
|
const button = event.relatedTarget;
|
||||||
|
const id = button.getAttribute('data-id');
|
||||||
|
const deleteBtn = deleteConfirmModal.querySelector('#delete-confirm-btn');
|
||||||
|
deleteBtn.href = 'bunks.php?action=delete&id=' + id;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
238
fuel_types.php
Normal file
238
fuel_types.php
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
require_once 'db/config.php';
|
||||||
|
|
||||||
|
$notification = null;
|
||||||
|
|
||||||
|
// Handle Add, Edit, Delete actions
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$db = db();
|
||||||
|
// Add Fuel Type
|
||||||
|
if (isset($_POST['add_fuel_type'])) {
|
||||||
|
$name = trim($_POST['name']);
|
||||||
|
if (!empty($name)) {
|
||||||
|
try {
|
||||||
|
$stmt = $db->prepare("INSERT INTO fuel_types (name) VALUES (?)");
|
||||||
|
$stmt->execute([$name]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Fuel type added successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error adding fuel type: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Fuel type name is required.', 'type' => 'warning'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Edit Fuel Type
|
||||||
|
elseif (isset($_POST['edit_fuel_type'])) {
|
||||||
|
$id = $_POST['fuel_type_id'];
|
||||||
|
$name = trim($_POST['name']);
|
||||||
|
if (!empty($name) && !empty($id)) {
|
||||||
|
try {
|
||||||
|
$stmt = $db->prepare("UPDATE fuel_types SET name = ? WHERE id = ?");
|
||||||
|
$stmt->execute([$name, $id]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Fuel type updated successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error updating fuel type: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Fuel type name and ID are required.', 'type' => 'warning'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header("Location: fuel_types.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete Fuel Type
|
||||||
|
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
|
||||||
|
try {
|
||||||
|
$db = db();
|
||||||
|
$stmt = $db->prepare("SELECT COUNT(*) FROM tanks WHERE fuel_type_id = ?");
|
||||||
|
$stmt->execute([$_GET['id']]);
|
||||||
|
if ($stmt->fetchColumn() > 0) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Cannot delete. This fuel type is in use by one or more tanks.', 'type' => 'warning'];
|
||||||
|
} else {
|
||||||
|
$stmt = $db->prepare("DELETE FROM fuel_types WHERE id = ?");
|
||||||
|
$stmt->execute([$_GET['id']]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Fuel type deleted successfully!', 'type' => 'success'];
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error deleting fuel type: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
header("Location: fuel_types.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_SESSION['notification'])) {
|
||||||
|
$notification = $_SESSION['notification'];
|
||||||
|
unset($_SESSION['notification']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$fuel_types = db()->query("SELECT * FROM fuel_types ORDER BY name ASC")->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
$page_title = "Fuel Type Management";
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title><?= htmlspecialchars($page_title) ?> - Petrol Pump Management</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<?php include 'includes/header.php'; ?>
|
||||||
|
|
||||||
|
<div class="container mt-4">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||||
|
<h1><i class="bi bi-fuel-pump"></i> <?= htmlspecialchars($page_title) ?></h1>
|
||||||
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addFuelTypeModal">
|
||||||
|
<i class="bi bi-plus-circle"></i> Add New Fuel Type
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($fuel_types as $type): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?= htmlspecialchars($type['id']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($type['name']) ?></td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-secondary edit-btn"
|
||||||
|
data-bs-toggle="modal" data-bs-target="#editFuelTypeModal"
|
||||||
|
data-id="<?= $type['id'] ?>"
|
||||||
|
data-name="<?= htmlspecialchars($type['name']) ?>">
|
||||||
|
<i class="bi bi-pencil"></i>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-danger delete-btn"
|
||||||
|
data-bs-toggle="modal" data-bs-target="#deleteConfirmModal"
|
||||||
|
data-id="<?= $type['id'] ?>">
|
||||||
|
<i class="bi bi-trash"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Add Fuel Type Modal -->
|
||||||
|
<div class="modal fade" id="addFuelTypeModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<form method="POST">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Add Fuel Type</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="name" class="form-label">Fuel Type Name*</label>
|
||||||
|
<input type="text" class="form-control" name="name" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" name="add_fuel_type" class="btn btn-primary">Save</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Edit Fuel Type Modal -->
|
||||||
|
<div class="modal fade" id="editFuelTypeModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<form method="POST">
|
||||||
|
<input type="hidden" name="fuel_type_id" id="edit_fuel_type_id">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Edit Fuel Type</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="edit_name" class="form-label">Fuel Type Name*</label>
|
||||||
|
<input type="text" class="form-control" id="edit_name" name="name" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" name="edit_fuel_type" class="btn btn-primary">Save Changes</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Delete Confirmation Modal -->
|
||||||
|
<div class="modal fade" id="deleteConfirmModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Confirm Deletion</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Are you sure you want to delete this fuel type?</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||||
|
<a href="#" id="delete-confirm-btn" class="btn btn-danger">Delete</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Toast Notification -->
|
||||||
|
<div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11">
|
||||||
|
<div id="notificationToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
|
<div class="toast-header"></div>
|
||||||
|
<div class="toast-body"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const notification = <?php echo json_encode($notification); ?>;
|
||||||
|
if (notification) {
|
||||||
|
const toastEl = document.getElementById('notificationToast');
|
||||||
|
const toastHeader = toastEl.querySelector('.toast-header');
|
||||||
|
const toastBody = toastEl.querySelector('.toast-body');
|
||||||
|
|
||||||
|
toastHeader.innerHTML = `<strong class="me-auto">Notification</strong><button type="button" class="btn-close" data-bs-dismiss="toast"></button>`;
|
||||||
|
toastBody.textContent = notification.text;
|
||||||
|
toastEl.classList.remove('bg-success', 'bg-danger', 'bg-warning');
|
||||||
|
toastEl.classList.add('bg-' + notification.type, 'text-white');
|
||||||
|
|
||||||
|
new bootstrap.Toast(toastEl).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
const editModal = document.getElementById('editFuelTypeModal');
|
||||||
|
editModal.addEventListener('show.bs.modal', function (event) {
|
||||||
|
const button = event.relatedTarget;
|
||||||
|
const id = button.getAttribute('data-id');
|
||||||
|
const name = button.getAttribute('data-name');
|
||||||
|
editModal.querySelector('#edit_fuel_type_id').value = id;
|
||||||
|
editModal.querySelector('#edit_name').value = name;
|
||||||
|
});
|
||||||
|
|
||||||
|
const deleteModal = document.getElementById('deleteConfirmModal');
|
||||||
|
deleteModal.addEventListener('show.bs.modal', function (event) {
|
||||||
|
const button = event.relatedTarget;
|
||||||
|
const id = button.getAttribute('data-id');
|
||||||
|
deleteModal.querySelector('#delete-confirm-btn').href = 'fuel_types.php?action=delete&id=' + id;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
50
includes/header.php
Normal file
50
includes/header.php
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Petrol Pump Management</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<a class="navbar-brand" href="index.php">Petrol Pump</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navbarNav">
|
||||||
|
<ul class="navbar-nav">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="index.php">Dashboard</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="bunks.php">Bunks</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="users.php">Users</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="roles.php">Roles</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="tanks.php">Tanks</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="fuel_types.php">Fuel Types</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="pumps.php">Pumps</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="nozzles.php">Nozzles</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="prices.php">Prices</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<div class="container mt-4">
|
||||||
67
index.php
67
index.php
@ -32,28 +32,11 @@ require_once 'db/config.php';
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<nav class="navbar navbar-expand-lg navbar-dark shadow-sm">
|
<?php include 'includes/header.php'; ?>
|
||||||
<div class="container">
|
|
||||||
<a class="navbar-brand" href="index.php">Bunk Admin</a>
|
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
|
||||||
</button>
|
|
||||||
<div class="collapse navbar-collapse" id="navbarNav">
|
|
||||||
<ul class="navbar-nav">
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link active" href="index.php">Dashboard</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="bunks.php">Bunks</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="container mt-4">
|
<div class="container mt-4">
|
||||||
<h1 class="h2 mb-3">Dashboard</h1>
|
<h1 class="h2 mb-3">Dashboard</h1>
|
||||||
<div class="row">
|
<div class="row g-4">
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<div class="card text-center shadow-sm h-100">
|
<div class="card text-center shadow-sm h-100">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@ -65,12 +48,52 @@ require_once 'db/config.php';
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<div class="card text-center text-secondary bg-light shadow-sm h-100">
|
<div class="card text-center shadow-sm h-100">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<i class="bi bi-people card-icon"></i>
|
<i class="bi bi-people card-icon"></i>
|
||||||
<h5 class="card-title mt-3">User Management</h5>
|
<h5 class="card-title mt-3">User Management</h5>
|
||||||
<p class="card-text">Manage users and roles (coming soon).</p>
|
<p class="card-text">Manage users and roles.</p>
|
||||||
<a href="#" class="btn btn-secondary disabled">Go to Users</a>
|
<a href="users.php" class="btn btn-primary">Go to Users</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="card text-center shadow-sm h-100">
|
||||||
|
<div class="card-body">
|
||||||
|
<i class="bi bi-shield-lock card-icon"></i>
|
||||||
|
<h5 class="card-title mt-3">Role Management</h5>
|
||||||
|
<p class="card-text">Define user roles and permissions.</p>
|
||||||
|
<a href="roles.php" class="btn btn-primary">Go to Roles</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="card text-center shadow-sm h-100">
|
||||||
|
<div class="card-body">
|
||||||
|
<i class="bi bi-inboxes card-icon"></i>
|
||||||
|
<h5 class="card-title mt-3">Tank Management</h5>
|
||||||
|
<p class="card-text">Manage fuel tanks and inventory.</p>
|
||||||
|
<a href="tanks.php" class="btn btn-primary">Go to Tanks</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="card text-center shadow-sm h-100">
|
||||||
|
<div class="card-body">
|
||||||
|
<i class="bi bi-ev-station card-icon"></i>
|
||||||
|
<h5 class="card-title mt-3">Pump Management</h5>
|
||||||
|
<p class="card-text">Manage fuel pumps.</p>
|
||||||
|
<a href="pumps.php" class="btn btn-primary">Go to Pumps</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="card text-center shadow-sm h-100">
|
||||||
|
<div class="card-body">
|
||||||
|
<i class="bi bi-cone-striped card-icon"></i>
|
||||||
|
<h5 class="card-title mt-3">Nozzle Management</h5>
|
||||||
|
<p class="card-text">Manage fuel nozzles.</p>
|
||||||
|
<a href="nozzles.php" class="btn btn-primary">Go to Nozzles</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
280
nozzles.php
Normal file
280
nozzles.php
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
require_once 'db/config.php';
|
||||||
|
|
||||||
|
$notification = null;
|
||||||
|
|
||||||
|
// Handle Add, Edit, Delete actions
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$db = db();
|
||||||
|
// Add Nozzle
|
||||||
|
if (isset($_POST['add_nozzle'])) {
|
||||||
|
$name = trim($_POST['name']);
|
||||||
|
$pump_id = $_POST['pump_id'];
|
||||||
|
$tank_id = $_POST['tank_id'];
|
||||||
|
if (!empty($name) && !empty($pump_id) && !empty($tank_id)) {
|
||||||
|
try {
|
||||||
|
$stmt = $db->prepare("INSERT INTO nozzles (name, pump_id, tank_id) VALUES (?, ?, ?)");
|
||||||
|
$stmt->execute([$name, $pump_id, $tank_id]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Nozzle added successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error adding nozzle: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_SESSION['notification'] = ['text' => 'All fields are required.', 'type' => 'warning'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Edit Nozzle
|
||||||
|
elseif (isset($_POST['edit_nozzle'])) {
|
||||||
|
$id = $_POST['nozzle_id'];
|
||||||
|
$name = trim($_POST['name']);
|
||||||
|
$pump_id = $_POST['pump_id'];
|
||||||
|
$tank_id = $_POST['tank_id'];
|
||||||
|
if (!empty($name) && !empty($pump_id) && !empty($tank_id) && !empty($id)) {
|
||||||
|
try {
|
||||||
|
$stmt = $db->prepare("UPDATE nozzles SET name = ?, pump_id = ?, tank_id = ? WHERE id = ?");
|
||||||
|
$stmt->execute([$name, $pump_id, $tank_id, $id]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Nozzle updated successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error updating nozzle: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_SESSION['notification'] = ['text' => 'All fields and ID are required.', 'type' => 'warning'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header("Location: nozzles.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Soft Delete Nozzle
|
||||||
|
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
|
||||||
|
try {
|
||||||
|
$db = db();
|
||||||
|
$stmt = $db->prepare("UPDATE nozzles SET deleted_at = NOW() WHERE id = ?");
|
||||||
|
$stmt->execute([$_GET['id']]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Nozzle deleted successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error deleting nozzle: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
header("Location: nozzles.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_SESSION['notification'])) {
|
||||||
|
$notification = $_SESSION['notification'];
|
||||||
|
unset($_SESSION['notification']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = db();
|
||||||
|
$nozzles = $db->query("SELECT n.*, p.name as pump_name, t.name as tank_name FROM nozzles n JOIN pumps p ON n.pump_id = p.id JOIN tanks t ON n.tank_id = t.id WHERE n.deleted_at IS NULL ORDER BY n.created_at DESC")->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
$pumps = $db->query("SELECT * FROM pumps WHERE deleted_at IS NULL")->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
$tanks = $db->query("SELECT * FROM tanks")->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
$page_title = "Nozzle Management";
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title><?= htmlspecialchars($page_title) ?> - Petrol Pump Management</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<?php include 'includes/header.php'; ?>
|
||||||
|
|
||||||
|
<div class="container mt-4">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||||
|
<h1><i class="bi bi-cone-striped"></i> <?= htmlspecialchars($page_title) ?></h1>
|
||||||
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addNozzleModal">
|
||||||
|
<i class="bi bi-plus-circle"></i> Add New Nozzle
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Pump</th>
|
||||||
|
<th>Tank</th>
|
||||||
|
<th>Created At</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($nozzles as $nozzle): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?= htmlspecialchars($nozzle['name']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($nozzle['pump_name']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($nozzle['tank_name']) ?></td>
|
||||||
|
<td><?= date('d M, Y', strtotime($nozzle['created_at'])) ?></td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-primary edit-btn"
|
||||||
|
data-bs-toggle="modal" data-bs-target="#editNozzleModal"
|
||||||
|
data-id="<?= $nozzle['id'] ?>"
|
||||||
|
data-name="<?= htmlspecialchars($nozzle['name']) ?>"
|
||||||
|
data-pump-id="<?= $nozzle['pump_id'] ?>"
|
||||||
|
data-tank-id="<?= $nozzle['tank_id'] ?>">
|
||||||
|
<i class="bi bi-pencil-square"></i>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-danger delete-btn"
|
||||||
|
data-bs-toggle="modal" data-bs-target="#deleteConfirmModal"
|
||||||
|
data-id="<?= $nozzle['id'] ?>">
|
||||||
|
<i class="bi bi-trash"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Add Nozzle Modal -->
|
||||||
|
<div class="modal fade" id="addNozzleModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<form method="POST">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Add New Nozzle</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Nozzle Name*</label>
|
||||||
|
<input type="text" class="form-control" name="name" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Pump*</label>
|
||||||
|
<select class="form-select" name="pump_id" required>
|
||||||
|
<option value="">Select Pump</option>
|
||||||
|
<?php foreach ($pumps as $pump): ?>
|
||||||
|
<option value="<?= $pump['id'] ?>"><?= htmlspecialchars($pump['name']) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Tank*</label>
|
||||||
|
<select class="form-select" name="tank_id" required>
|
||||||
|
<option value="">Select Tank</option>
|
||||||
|
<?php foreach ($tanks as $tank): ?>
|
||||||
|
<option value="<?= $tank['id'] ?>"><?= htmlspecialchars($tank['name']) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" name="add_nozzle" class="btn btn-primary">Save Nozzle</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Edit Nozzle Modal -->
|
||||||
|
<div class="modal fade" id="editNozzleModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<form method="POST">
|
||||||
|
<input type="hidden" name="nozzle_id" id="edit_nozzle_id">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Edit Nozzle</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Nozzle Name*</label>
|
||||||
|
<input type="text" class="form-control" id="edit_name" name="name" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Pump*</label>
|
||||||
|
<select class="form-select" id="edit_pump_id" name="pump_id" required>
|
||||||
|
<?php foreach ($pumps as $pump): ?>
|
||||||
|
<option value="<?= $pump['id'] ?>"><?= htmlspecialchars($pump['name']) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Tank*</label>
|
||||||
|
<select class="form-select" id="edit_tank_id" name="tank_id" required>
|
||||||
|
<?php foreach ($tanks as $tank): ?>
|
||||||
|
<option value="<?= $tank['id'] ?>"><?= htmlspecialchars($tank['name']) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" name="edit_nozzle" class="btn btn-primary">Save Changes</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Delete Confirmation Modal -->
|
||||||
|
<div class="modal fade" id="deleteConfirmModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Confirm Deletion</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Are you sure you want to delete this nozzle?</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||||
|
<a href="#" id="delete-confirm-btn" class="btn btn-danger">Delete</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Toast Notification -->
|
||||||
|
<div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11">
|
||||||
|
<div id="notificationToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
|
<div class="toast-header"></div>
|
||||||
|
<div class="toast-body"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const notification = <?php echo json_encode($notification); ?>;
|
||||||
|
if (notification) {
|
||||||
|
const toastEl = document.getElementById('notificationToast');
|
||||||
|
const toastHeader = toastEl.querySelector('.toast-header');
|
||||||
|
const toastBody = toastEl.querySelector('.toast-body');
|
||||||
|
|
||||||
|
toastHeader.innerHTML = `<strong class="me-auto">Notification</strong><button type="button" class="btn-close" data-bs-dismiss="toast"></button>`;
|
||||||
|
toastBody.textContent = notification.text;
|
||||||
|
toastEl.classList.remove('bg-success', 'bg-danger', 'bg-warning');
|
||||||
|
toastEl.classList.add('bg-' + notification.type, 'text-white');
|
||||||
|
|
||||||
|
new bootstrap.Toast(toastEl).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
const editModal = document.getElementById('editNozzleModal');
|
||||||
|
editModal.addEventListener('show.bs.modal', function (event) {
|
||||||
|
const button = event.relatedTarget;
|
||||||
|
const id = button.getAttribute('data-id');
|
||||||
|
editModal.querySelector('#edit_nozzle_id').value = id;
|
||||||
|
editModal.querySelector('#edit_name').value = button.getAttribute('data-name');
|
||||||
|
editModal.querySelector('#edit_pump_id').value = button.getAttribute('data-pump-id');
|
||||||
|
editModal.querySelector('#edit_tank_id').value = button.getAttribute('data-tank-id');
|
||||||
|
});
|
||||||
|
|
||||||
|
const deleteModal = document.getElementById('deleteConfirmModal');
|
||||||
|
deleteModal.addEventListener('show.bs.modal', function (event) {
|
||||||
|
const button = event.relatedTarget;
|
||||||
|
const id = button.getAttribute('data-id');
|
||||||
|
deleteModal.querySelector('#delete-confirm-btn').href = 'nozzles.php?action=delete&id=' + id;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
268
prices.php
Normal file
268
prices.php
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
require_once 'db/config.php';
|
||||||
|
|
||||||
|
$notification = null;
|
||||||
|
|
||||||
|
// Handle Add, Edit, Delete actions
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$db = db();
|
||||||
|
// Add Price
|
||||||
|
if (isset($_POST['add_price'])) {
|
||||||
|
$tank_id = $_POST['tank_id'];
|
||||||
|
$price = $_POST['price'];
|
||||||
|
$effective_date = $_POST['effective_date'];
|
||||||
|
if (!empty($tank_id) && !empty($price) && !empty($effective_date)) {
|
||||||
|
try {
|
||||||
|
$stmt = $db->prepare("INSERT INTO prices (tank_id, price, effective_date) VALUES (?, ?, ?)");
|
||||||
|
$stmt->execute([$tank_id, $price, $effective_date]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Price added successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error adding price: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_SESSION['notification'] = ['text' => 'All fields are required.', 'type' => 'warning'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Edit Price
|
||||||
|
elseif (isset($_POST['edit_price'])) {
|
||||||
|
$id = $_POST['price_id'];
|
||||||
|
$tank_id = $_POST['tank_id'];
|
||||||
|
$price = $_POST['price'];
|
||||||
|
$effective_date = $_POST['effective_date'];
|
||||||
|
if (!empty($tank_id) && !empty($price) && !empty($effective_date) && !empty($id)) {
|
||||||
|
try {
|
||||||
|
$stmt = $db->prepare("UPDATE prices SET tank_id = ?, price = ?, effective_date = ? WHERE id = ?");
|
||||||
|
$stmt->execute([$tank_id, $price, $effective_date, $id]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Price updated successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error updating price: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_SESSION['notification'] = ['text' => 'All fields and ID are required.', 'type' => 'warning'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header("Location: prices.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Soft Delete Price
|
||||||
|
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
|
||||||
|
try {
|
||||||
|
$db = db();
|
||||||
|
$stmt = $db->prepare("UPDATE prices SET deleted_at = NOW() WHERE id = ?");
|
||||||
|
$stmt->execute([$_GET['id']]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Price deleted successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error deleting price: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
header("Location: prices.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_SESSION['notification'])) {
|
||||||
|
$notification = $_SESSION['notification'];
|
||||||
|
unset($_SESSION['notification']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = db();
|
||||||
|
$prices = $db->query("SELECT pr.*, t.name as tank_name, ft.name as fuel_type_name FROM prices pr JOIN tanks t ON pr.tank_id = t.id JOIN fuel_types ft ON t.fuel_type_id = ft.id WHERE pr.deleted_at IS NULL ORDER BY pr.effective_date DESC")->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
$tanks = $db->query("SELECT t.id, t.name, ft.name as fuel_type_name FROM tanks t JOIN fuel_types ft ON t.fuel_type_id = ft.id WHERE t.deleted_at IS NULL")->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
$page_title = "Price Management";
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title><?= htmlspecialchars($page_title) ?> - Petrol Pump Management</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<?php include 'includes/header.php'; ?>
|
||||||
|
|
||||||
|
<div class="container mt-4">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||||
|
<h1><i class="bi bi-tags-fill"></i> <?= htmlspecialchars($page_title) ?></h1>
|
||||||
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addPriceModal">
|
||||||
|
<i class="bi bi-plus-circle"></i> Add New Price
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Tank</th>
|
||||||
|
<th>Price</th>
|
||||||
|
<th>Effective Date</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($prices as $price): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?= htmlspecialchars($price['tank_name'] . ' (' . $price['fuel_type_name'] . ')') ?></td>
|
||||||
|
<td>₹ <?= htmlspecialchars(number_format($price['price'], 2)) ?></td>
|
||||||
|
<td><?= date('d M, Y', strtotime($price['effective_date'])) ?></td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-primary edit-btn"
|
||||||
|
data-bs-toggle="modal" data-bs-target="#editPriceModal"
|
||||||
|
data-id="<?= $price['id'] ?>"
|
||||||
|
data-tank-id="<?= $price['tank_id'] ?>"
|
||||||
|
data-price="<?= htmlspecialchars($price['price']) ?>"
|
||||||
|
data-effective-date="<?= htmlspecialchars($price['effective_date']) ?>">
|
||||||
|
<i class="bi bi-pencil-square"></i>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-danger delete-btn"
|
||||||
|
data-bs-toggle="modal" data-bs-target="#deleteConfirmModal"
|
||||||
|
data-id="<?= $price['id'] ?>">
|
||||||
|
<i class="bi bi-trash"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Add Price Modal -->
|
||||||
|
<div class="modal fade" id="addPriceModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<form method="POST">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Add New Price</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Tank*</label>
|
||||||
|
<select class="form-select" name="tank_id" required>
|
||||||
|
<option value="">Select Tank</option>
|
||||||
|
<?php foreach ($tanks as $tank): ?>
|
||||||
|
<option value="<?= $tank['id'] ?>"><?= htmlspecialchars($tank['name'] . ' (' . $tank['fuel_type_name'] . ')') ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Price*</label>
|
||||||
|
<input type="number" step="0.01" class="form-control" name="price" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Effective Date*</label>
|
||||||
|
<input type="date" class="form-control" name="effective_date" value="<?= date('Y-m-d') ?>" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" name="add_price" class="btn btn-primary">Save Price</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Edit Price Modal -->
|
||||||
|
<div class="modal fade" id="editPriceModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<form method="POST">
|
||||||
|
<input type="hidden" name="price_id" id="edit_price_id">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Edit Price</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Tank*</label>
|
||||||
|
<select class="form-select" id="edit_tank_id" name="tank_id" required>
|
||||||
|
<?php foreach ($tanks as $tank): ?>
|
||||||
|
<option value="<?= $tank['id'] ?>"><?= htmlspecialchars($tank['name'] . ' (' . $tank['fuel_type_name'] . ')') ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Price*</label>
|
||||||
|
<input type="number" step="0.01" class="form-control" id="edit_price" name="price" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Effective Date*</label>
|
||||||
|
<input type="date" class="form-control" id="edit_effective_date" name="effective_date" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" name="edit_price" class="btn btn-primary">Save Changes</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Delete Confirmation Modal -->
|
||||||
|
<div class="modal fade" id="deleteConfirmModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Confirm Deletion</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Are you sure you want to delete this price record? This is a soft delete.</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||||
|
<a href="#" id="delete-confirm-btn" class="btn btn-danger">Delete</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Toast Notification -->
|
||||||
|
<div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11">
|
||||||
|
<div id="notificationToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
|
<div class="toast-header"></div>
|
||||||
|
<div class="toast-body"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const notification = <?php echo json_encode($notification); ?>;
|
||||||
|
if (notification) {
|
||||||
|
const toastEl = document.getElementById('notificationToast');
|
||||||
|
const toastHeader = toastEl.querySelector('.toast-header');
|
||||||
|
const toastBody = toastEl.querySelector('.toast-body');
|
||||||
|
|
||||||
|
toastHeader.innerHTML = `<strong class="me-auto">Notification</strong><button type="button" class="btn-close" data-bs-dismiss="toast"></button>`;
|
||||||
|
toastBody.textContent = notification.text;
|
||||||
|
toastEl.classList.remove('bg-success', 'bg-danger', 'bg-warning');
|
||||||
|
toastEl.classList.add('bg-' + notification.type, 'text-white');
|
||||||
|
|
||||||
|
new bootstrap.Toast(toastEl).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
const editModal = document.getElementById('editPriceModal');
|
||||||
|
editModal.addEventListener('show.bs.modal', function (event) {
|
||||||
|
const button = event.relatedTarget;
|
||||||
|
const id = button.getAttribute('data-id');
|
||||||
|
editModal.querySelector('#edit_price_id').value = id;
|
||||||
|
editModal.querySelector('#edit_tank_id').value = button.getAttribute('data-tank-id');
|
||||||
|
editModal.querySelector('#edit_price').value = button.getAttribute('data-price');
|
||||||
|
editModal.querySelector('#edit_effective_date').value = button.getAttribute('data-effective-date');
|
||||||
|
});
|
||||||
|
|
||||||
|
const deleteModal = document.getElementById('deleteConfirmModal');
|
||||||
|
deleteModal.addEventListener('show.bs.modal', function (event) {
|
||||||
|
const button = event.relatedTarget;
|
||||||
|
const id = button.getAttribute('data-id');
|
||||||
|
deleteModal.querySelector('#delete-confirm-btn').href = 'prices.php?action=delete&id=' + id;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
256
pumps.php
Normal file
256
pumps.php
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
require_once 'db/config.php';
|
||||||
|
|
||||||
|
$notification = null;
|
||||||
|
|
||||||
|
// Handle Add, Edit, Delete actions
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$db = db();
|
||||||
|
// Add Pump
|
||||||
|
if (isset($_POST['add_pump'])) {
|
||||||
|
$name = trim($_POST['name']);
|
||||||
|
$bunk_id = $_POST['bunk_id'];
|
||||||
|
if (!empty($name) && !empty($bunk_id)) {
|
||||||
|
try {
|
||||||
|
$stmt = $db->prepare("INSERT INTO pumps (name, bunk_id) VALUES (?, ?)");
|
||||||
|
$stmt->execute([$name, $bunk_id]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Pump added successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error adding pump: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Pump name and bunk are required.', 'type' => 'warning'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Edit Pump
|
||||||
|
elseif (isset($_POST['edit_pump'])) {
|
||||||
|
$id = $_POST['pump_id'];
|
||||||
|
$name = trim($_POST['name']);
|
||||||
|
$bunk_id = $_POST['bunk_id'];
|
||||||
|
if (!empty($name) && !empty($bunk_id) && !empty($id)) {
|
||||||
|
try {
|
||||||
|
$stmt = $db->prepare("UPDATE pumps SET name = ?, bunk_id = ? WHERE id = ?");
|
||||||
|
$stmt->execute([$name, $bunk_id, $id]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Pump updated successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error updating pump: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Pump name, bunk and ID are required.', 'type' => 'warning'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header("Location: pumps.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Soft Delete Pump
|
||||||
|
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
|
||||||
|
try {
|
||||||
|
$db = db();
|
||||||
|
$stmt = $db->prepare("UPDATE pumps SET deleted_at = NOW() WHERE id = ?");
|
||||||
|
$stmt->execute([$_GET['id']]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Pump deleted successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error deleting pump: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
header("Location: pumps.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_SESSION['notification'])) {
|
||||||
|
$notification = $_SESSION['notification'];
|
||||||
|
unset($_SESSION['notification']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = db();
|
||||||
|
$pumps = $db->query("SELECT p.*, b.name as bunk_name FROM pumps p JOIN bunks b ON p.bunk_id = b.id WHERE p.deleted_at IS NULL ORDER BY p.created_at DESC")->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
$bunks = $db->query("SELECT * FROM bunks WHERE deleted_at IS NULL")->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
$page_title = "Pump Management";
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title><?= htmlspecialchars($page_title) ?> - Petrol Pump Management</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<?php include 'includes/header.php'; ?>
|
||||||
|
|
||||||
|
<div class="container mt-4">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||||
|
<h1><i class="bi bi-ev-station-fill"></i> <?= htmlspecialchars($page_title) ?></h1>
|
||||||
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addPumpModal">
|
||||||
|
<i class="bi bi-plus-circle"></i> Add New Pump
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Bunk</th>
|
||||||
|
<th>Created At</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($pumps as $pump): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?= htmlspecialchars($pump['name']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($pump['bunk_name']) ?></td>
|
||||||
|
<td><?= date('d M, Y', strtotime($pump['created_at'])) ?></td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-primary edit-btn"
|
||||||
|
data-bs-toggle="modal" data-bs-target="#editPumpModal"
|
||||||
|
data-id="<?= $pump['id'] ?>"
|
||||||
|
data-name="<?= htmlspecialchars($pump['name']) ?>"
|
||||||
|
data-bunk-id="<?= $pump['bunk_id'] ?>">
|
||||||
|
<i class="bi bi-pencil-square"></i>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-danger delete-btn"
|
||||||
|
data-bs-toggle="modal" data-bs-target="#deleteConfirmModal"
|
||||||
|
data-id="<?= $pump['id'] ?>">
|
||||||
|
<i class="bi bi-trash"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Add Pump Modal -->
|
||||||
|
<div class="modal fade" id="addPumpModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<form method="POST">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Add New Pump</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Pump Name*</label>
|
||||||
|
<input type="text" class="form-control" name="name" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Bunk*</label>
|
||||||
|
<select class="form-select" name="bunk_id" required>
|
||||||
|
<option value="">Select Bunk</option>
|
||||||
|
<?php foreach ($bunks as $bunk): ?>
|
||||||
|
<option value="<?= $bunk['id'] ?>"><?= htmlspecialchars($bunk['name']) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" name="add_pump" class="btn btn-primary">Save Pump</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Edit Pump Modal -->
|
||||||
|
<div class="modal fade" id="editPumpModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<form method="POST">
|
||||||
|
<input type="hidden" name="pump_id" id="edit_pump_id">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Edit Pump</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Pump Name*</label>
|
||||||
|
<input type="text" class="form-control" id="edit_name" name="name" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Bunk*</label>
|
||||||
|
<select class="form-select" id="edit_bunk_id" name="bunk_id" required>
|
||||||
|
<?php foreach ($bunks as $bunk): ?>
|
||||||
|
<option value="<?= $bunk['id'] ?>"><?= htmlspecialchars($bunk['name']) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" name="edit_pump" class="btn btn-primary">Save Changes</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Delete Confirmation Modal -->
|
||||||
|
<div class="modal fade" id="deleteConfirmModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Confirm Deletion</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Are you sure you want to delete this pump?</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||||
|
<a href="#" id="delete-confirm-btn" class="btn btn-danger">Delete</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Toast Notification -->
|
||||||
|
<div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11">
|
||||||
|
<div id="notificationToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
|
<div class="toast-header"></div>
|
||||||
|
<div class="toast-body"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const notification = <?php echo json_encode($notification); ?>;
|
||||||
|
if (notification) {
|
||||||
|
const toastEl = document.getElementById('notificationToast');
|
||||||
|
const toastHeader = toastEl.querySelector('.toast-header');
|
||||||
|
const toastBody = toastEl.querySelector('.toast-body');
|
||||||
|
|
||||||
|
toastHeader.innerHTML = `<strong class="me-auto">Notification</strong><button type="button" class="btn-close" data-bs-dismiss="toast"></button>`;
|
||||||
|
toastBody.textContent = notification.text;
|
||||||
|
toastEl.classList.remove('bg-success', 'bg-danger', 'bg-warning');
|
||||||
|
toastEl.classList.add('bg-' + notification.type, 'text-white');
|
||||||
|
|
||||||
|
new bootstrap.Toast(toastEl).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
const editModal = document.getElementById('editPumpModal');
|
||||||
|
editModal.addEventListener('show.bs.modal', function (event) {
|
||||||
|
const button = event.relatedTarget;
|
||||||
|
const id = button.getAttribute('data-id');
|
||||||
|
editModal.querySelector('#edit_pump_id').value = id;
|
||||||
|
editModal.querySelector('#edit_name').value = button.getAttribute('data-name');
|
||||||
|
editModal.querySelector('#edit_bunk_id').value = button.getAttribute('data-bunk-id');
|
||||||
|
});
|
||||||
|
|
||||||
|
const deleteModal = document.getElementById('deleteConfirmModal');
|
||||||
|
deleteModal.addEventListener('show.bs.modal', function (event) {
|
||||||
|
const button = event.relatedTarget;
|
||||||
|
const id = button.getAttribute('data-id');
|
||||||
|
deleteModal.querySelector('#delete-confirm-btn').href = 'pumps.php?action=delete&id=' + id;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
286
roles.php
Normal file
286
roles.php
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
require_once 'db/config.php';
|
||||||
|
|
||||||
|
$notification = null;
|
||||||
|
|
||||||
|
// Handle Add, Edit, Delete actions
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$db = db();
|
||||||
|
// Add Role
|
||||||
|
if (isset($_POST['add_role'])) {
|
||||||
|
$name = trim($_POST['name']);
|
||||||
|
$description = trim($_POST['description']);
|
||||||
|
|
||||||
|
if (!empty($name)) {
|
||||||
|
try {
|
||||||
|
$stmt = $db->prepare("INSERT INTO roles (name, description) VALUES (?, ?)");
|
||||||
|
$stmt->execute([$name, $description]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Role added successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error adding role: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Role name is required.', 'type' => 'warning'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Edit Role
|
||||||
|
elseif (isset($_POST['edit_role'])) {
|
||||||
|
$id = $_POST['role_id'];
|
||||||
|
$name = trim($_POST['name']);
|
||||||
|
$description = trim($_POST['description']);
|
||||||
|
|
||||||
|
if (!empty($name) && !empty($id)) {
|
||||||
|
try {
|
||||||
|
$stmt = $db->prepare("UPDATE roles SET name = ?, description = ? WHERE id = ?");
|
||||||
|
$stmt->execute([$name, $description, $id]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Role updated successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error updating role: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Role name and ID are required.', 'type' => 'warning'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header("Location: roles.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete Role
|
||||||
|
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
|
||||||
|
try {
|
||||||
|
$db = db();
|
||||||
|
// Check if any user is assigned this role
|
||||||
|
$stmt = $db->prepare("SELECT COUNT(*) FROM users WHERE role_id = ?");
|
||||||
|
$stmt->execute([$_GET['id']]);
|
||||||
|
if ($stmt->fetchColumn() > 0) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Cannot delete role. It is currently assigned to one or more users.', 'type' => 'warning'];
|
||||||
|
} else {
|
||||||
|
$stmt = $db->prepare("DELETE FROM roles WHERE id = ?");
|
||||||
|
$stmt->execute([$_GET['id']]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Role deleted successfully!', 'type' => 'success'];
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error deleting role: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
header("Location: roles.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (isset($_SESSION['notification'])) {
|
||||||
|
$notification = $_SESSION['notification'];
|
||||||
|
unset($_SESSION['notification']);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db = db();
|
||||||
|
$stmt = $db->query("SELECT id, name, description, created_at FROM roles ORDER BY name ASC");
|
||||||
|
$roles = $stmt->fetchAll();
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$roles = [];
|
||||||
|
$notification = ['text' => 'Error fetching roles: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$page_title = "Role Management";
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title><?= htmlspecialchars($page_title) ?> - Petrol Pump Management</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<?php include 'includes/header.php'; ?>
|
||||||
|
|
||||||
|
<div class="container mt-4">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||||
|
<h1><i class="bi bi-person-badge"></i> <?= htmlspecialchars($page_title) ?></h1>
|
||||||
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addRoleModal">
|
||||||
|
<i class="bi bi-plus-circle"></i> Add New Role
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th>Created At</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php if (empty($roles)): ?>
|
||||||
|
<tr>
|
||||||
|
<td colspan="4" class="text-center">No roles found.</td>
|
||||||
|
</tr>
|
||||||
|
<?php else: ?>
|
||||||
|
<?php foreach ($roles as $role): ?>
|
||||||
|
<tr>
|
||||||
|
<td><span class="badge bg-primary"><?= htmlspecialchars($role['name']) ?></span></td>
|
||||||
|
<td><?= htmlspecialchars($role['description']) ?></td>
|
||||||
|
<td><?= date('d M, Y', strtotime($role['created_at'])) ?></td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-secondary edit-btn"
|
||||||
|
data-bs-toggle="modal" data-bs-target="#editRoleModal"
|
||||||
|
data-id="<?= $role['id'] ?>"
|
||||||
|
data-name="<?= htmlspecialchars($role['name']) ?>"
|
||||||
|
data-description="<?= htmlspecialchars($role['description']) ?>">
|
||||||
|
<i class="bi bi-pencil"></i>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-danger delete-btn"
|
||||||
|
data-bs-toggle="modal" data-bs-target="#deleteConfirmModal"
|
||||||
|
data-id="<?= $role['id'] ?>">
|
||||||
|
<i class="bi bi-trash"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Add Role Modal -->
|
||||||
|
<div class="modal fade" id="addRoleModal" tabindex="-1" aria-labelledby="addRoleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<form action="roles.php" method="POST">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="addRoleModalLabel">Add New Role</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="name" class="form-label">Role Name*</label>
|
||||||
|
<input type="text" class="form-control" id="name" name="name" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="description" class="form-label">Description</label>
|
||||||
|
<textarea class="form-control" id="description" name="description" rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" name="add_role" class="btn btn-primary">Save Role</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Edit Role Modal -->
|
||||||
|
<div class="modal fade" id="editRoleModal" tabindex="-1" aria-labelledby="editRoleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<form action="roles.php" method="POST">
|
||||||
|
<input type="hidden" name="role_id" id="edit_role_id">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="editRoleModalLabel">Edit Role</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="edit_name" class="form-label">Role Name*</label>
|
||||||
|
<input type="text" class="form-control" id="edit_name" name="name" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="edit_description" class="form-label">Description</label>
|
||||||
|
<textarea class="form-control" id="edit_description" name="description" rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" name="edit_role" class="btn btn-primary">Save Changes</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Delete Confirmation Modal -->
|
||||||
|
<div class="modal fade" id="deleteConfirmModal" tabindex="-1" aria-labelledby="deleteConfirmModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="deleteConfirmModalLabel">Confirm Deletion</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
Are you sure you want to delete this role? This action cannot be undone.
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||||
|
<a href="#" id="delete-confirm-btn" class="btn btn-danger">Delete</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Toast Notification -->
|
||||||
|
<div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11">
|
||||||
|
<div id="notificationToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
|
<div class="toast-header">
|
||||||
|
<strong class="me-auto">Notification</strong>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="toast-body">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
// Toast notification
|
||||||
|
<?php if ($notification): ?>
|
||||||
|
const toastEl = document.getElementById('notificationToast');
|
||||||
|
const toastBody = toastEl.querySelector('.toast-body');
|
||||||
|
|
||||||
|
toastEl.classList.remove('bg-success', 'bg-danger', 'bg-warning');
|
||||||
|
toastEl.classList.add('bg-<?= $notification['type'] ?>', 'text-white');
|
||||||
|
toastBody.textContent = '<?= addslashes(htmlspecialchars($notification['text'])) ?>';
|
||||||
|
|
||||||
|
const toast = new bootstrap.Toast(toastEl);
|
||||||
|
toast.show();
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
// Edit modal handler
|
||||||
|
const editRoleModal = document.getElementById('editRoleModal');
|
||||||
|
editRoleModal.addEventListener('show.bs.modal', function (event) {
|
||||||
|
const button = event.relatedTarget;
|
||||||
|
const id = button.getAttribute('data-id');
|
||||||
|
const name = button.getAttribute('data-name');
|
||||||
|
const description = button.getAttribute('data-description');
|
||||||
|
|
||||||
|
const modalTitle = editRoleModal.querySelector('.modal-title');
|
||||||
|
const modalBodyInputId = editRoleModal.querySelector('#edit_role_id');
|
||||||
|
const modalBodyInputName = editRoleModal.querySelector('#edit_name');
|
||||||
|
const modalBodyInputDescription = editRoleModal.querySelector('#edit_description');
|
||||||
|
|
||||||
|
modalTitle.textContent = 'Edit Role: ' + name;
|
||||||
|
modalBodyInputId.value = id;
|
||||||
|
modalBodyInputName.value = name;
|
||||||
|
modalBodyInputDescription.value = description;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete confirmation handler
|
||||||
|
const deleteConfirmModal = document.getElementById('deleteConfirmModal');
|
||||||
|
deleteConfirmModal.addEventListener('show.bs.modal', function (event) {
|
||||||
|
const button = event.relatedTarget;
|
||||||
|
const id = button.getAttribute('data-id');
|
||||||
|
const deleteBtn = deleteConfirmModal.querySelector('#delete-confirm-btn');
|
||||||
|
deleteBtn.href = 'roles.php?action=delete&id=' + id;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
294
tanks.php
Normal file
294
tanks.php
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
require_once 'db/config.php';
|
||||||
|
|
||||||
|
$notification = null;
|
||||||
|
|
||||||
|
// Handle Add, Edit, Delete actions
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$db = db();
|
||||||
|
// Add Tank
|
||||||
|
if (isset($_POST['add_tank'])) {
|
||||||
|
$name = trim($_POST['name']);
|
||||||
|
$bunk_id = $_POST['bunk_id'];
|
||||||
|
$fuel_type_id = $_POST['fuel_type_id'];
|
||||||
|
$capacity = $_POST['capacity'];
|
||||||
|
|
||||||
|
if (!empty($name) && !empty($bunk_id) && !empty($fuel_type_id) && !empty($capacity)) {
|
||||||
|
try {
|
||||||
|
$stmt = $db->prepare("INSERT INTO tanks (name, bunk_id, fuel_type_id, capacity) VALUES (?, ?, ?, ?)");
|
||||||
|
$stmt->execute([$name, $bunk_id, $fuel_type_id, $capacity]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Tank added successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error adding tank: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_SESSION['notification'] = ['text' => 'All fields are required.', 'type' => 'warning'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Edit Tank
|
||||||
|
elseif (isset($_POST['edit_tank'])) {
|
||||||
|
$id = $_POST['tank_id'];
|
||||||
|
$name = trim($_POST['name']);
|
||||||
|
$bunk_id = $_POST['bunk_id'];
|
||||||
|
$fuel_type_id = $_POST['fuel_type_id'];
|
||||||
|
$capacity = $_POST['capacity'];
|
||||||
|
|
||||||
|
if (!empty($name) && !empty($bunk_id) && !empty($fuel_type_id) && !empty($capacity) && !empty($id)) {
|
||||||
|
try {
|
||||||
|
$stmt = $db->prepare("UPDATE tanks SET name = ?, bunk_id = ?, fuel_type_id = ?, capacity = ? WHERE id = ?");
|
||||||
|
$stmt->execute([$name, $bunk_id, $fuel_type_id, $capacity, $id]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Tank updated successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error updating tank: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_SESSION['notification'] = ['text' => 'All fields are required.', 'type' => 'warning'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header("Location: tanks.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete Tank
|
||||||
|
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
|
||||||
|
try {
|
||||||
|
$db = db();
|
||||||
|
$stmt = $db->prepare("DELETE FROM tanks WHERE id = ?");
|
||||||
|
$stmt->execute([$_GET['id']]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'Tank deleted successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error deleting tank: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
header("Location: tanks.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_SESSION['notification'])) {
|
||||||
|
$notification = $_SESSION['notification'];
|
||||||
|
unset($_SESSION['notification']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = db();
|
||||||
|
$tanks = $db->query("SELECT t.*, b.name as bunk_name, ft.name as fuel_type_name FROM tanks t JOIN bunks b ON t.bunk_id = b.id JOIN fuel_types ft ON t.fuel_type_id = ft.id ORDER BY t.created_at DESC")->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
$bunks = $db->query("SELECT * FROM bunks")->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
$fuel_types = $db->query("SELECT * FROM fuel_types")->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
$page_title = "Tank Management";
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title><?= htmlspecialchars($page_title) ?> - Petrol Pump Management</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<?php include 'includes/header.php'; ?>
|
||||||
|
|
||||||
|
<div class="container mt-4">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||||
|
<h1><i class="bi bi-inboxes-fill"></i> <?= htmlspecialchars($page_title) ?></h1>
|
||||||
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addTankModal">
|
||||||
|
<i class="bi bi-plus-circle"></i> Add New Tank
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Bunk</th>
|
||||||
|
<th>Fuel Type</th>
|
||||||
|
<th>Capacity (L)</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($tanks as $tank): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?= htmlspecialchars($tank['name']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($tank['bunk_name']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($tank['fuel_type_name']) ?></td>
|
||||||
|
<td><?= htmlspecialchars(number_format($tank['capacity'])) ?></td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-primary edit-btn"
|
||||||
|
data-bs-toggle="modal" data-bs-target="#editTankModal"
|
||||||
|
data-id="<?= $tank['id'] ?>"
|
||||||
|
data-name="<?= htmlspecialchars($tank['name']) ?>"
|
||||||
|
data-bunk-id="<?= $tank['bunk_id'] ?>"
|
||||||
|
data-fuel-type-id="<?= $tank['fuel_type_id'] ?>"
|
||||||
|
data-capacity="<?= htmlspecialchars($tank['capacity']) ?>">
|
||||||
|
<i class="bi bi-pencil-square"></i>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-danger delete-btn"
|
||||||
|
data-bs-toggle="modal" data-bs-target="#deleteConfirmModal"
|
||||||
|
data-id="<?= $tank['id'] ?>">
|
||||||
|
<i class="bi bi-trash"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Add Tank Modal -->
|
||||||
|
<div class="modal fade" id="addTankModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<form method="POST">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Add New Tank</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Tank Name*</label>
|
||||||
|
<input type="text" class="form-control" name="name" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Bunk*</label>
|
||||||
|
<select class="form-select" name="bunk_id" required>
|
||||||
|
<option value="">Select Bunk</option>
|
||||||
|
<?php foreach ($bunks as $bunk): ?>
|
||||||
|
<option value="<?= $bunk['id'] ?>"><?= htmlspecialchars($bunk['name']) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Fuel Type*</label>
|
||||||
|
<select class="form-select" name="fuel_type_id" required>
|
||||||
|
<option value="">Select Fuel Type</option>
|
||||||
|
<?php foreach ($fuel_types as $type): ?>
|
||||||
|
<option value="<?= $type['id'] ?>"><?= htmlspecialchars($type['name']) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Capacity (Litres)*</label>
|
||||||
|
<input type="number" class="form-control" name="capacity" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" name="add_tank" class="btn btn-primary">Save Tank</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Edit Tank Modal -->
|
||||||
|
<div class="modal fade" id="editTankModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<form method="POST">
|
||||||
|
<input type="hidden" name="tank_id" id="edit_tank_id">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Edit Tank</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Tank Name*</label>
|
||||||
|
<input type="text" class="form-control" id="edit_name" name="name" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Bunk*</label>
|
||||||
|
<select class="form-select" id="edit_bunk_id" name="bunk_id" required>
|
||||||
|
<?php foreach ($bunks as $bunk): ?>
|
||||||
|
<option value="<?= $bunk['id'] ?>"><?= htmlspecialchars($bunk['name']) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Fuel Type*</label>
|
||||||
|
<select class="form-select" id="edit_fuel_type_id" name="fuel_type_id" required>
|
||||||
|
<?php foreach ($fuel_types as $type): ?>
|
||||||
|
<option value="<?= $type['id'] ?>"><?= htmlspecialchars($type['name']) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Capacity (Litres)*</label>
|
||||||
|
<input type="number" class="form-control" id="edit_capacity" name="capacity" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" name="edit_tank" class="btn btn-primary">Save Changes</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Delete Confirmation Modal -->
|
||||||
|
<div class="modal fade" id="deleteConfirmModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Confirm Deletion</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Are you sure you want to delete this tank?</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||||
|
<a href="#" id="delete-confirm-btn" class="btn btn-danger">Delete</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Toast Notification -->
|
||||||
|
<div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11">
|
||||||
|
<div id="notificationToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
|
<div class="toast-header"></div>
|
||||||
|
<div class="toast-body"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const notification = <?php echo json_encode($notification); ?>;
|
||||||
|
if (notification) {
|
||||||
|
const toastEl = document.getElementById('notificationToast');
|
||||||
|
const toastHeader = toastEl.querySelector('.toast-header');
|
||||||
|
const toastBody = toastEl.querySelector('.toast-body');
|
||||||
|
|
||||||
|
toastHeader.innerHTML = `<strong class="me-auto">Notification</strong><button type="button" class="btn-close" data-bs-dismiss="toast"></button>`;
|
||||||
|
toastBody.textContent = notification.text;
|
||||||
|
toastEl.classList.remove('bg-success', 'bg-danger', 'bg-warning');
|
||||||
|
toastEl.classList.add('bg-' + notification.type, 'text-white');
|
||||||
|
|
||||||
|
new bootstrap.Toast(toastEl).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
const editModal = document.getElementById('editTankModal');
|
||||||
|
editModal.addEventListener('show.bs.modal', function (event) {
|
||||||
|
const button = event.relatedTarget;
|
||||||
|
const id = button.getAttribute('data-id');
|
||||||
|
editModal.querySelector('#edit_tank_id').value = id;
|
||||||
|
editModal.querySelector('#edit_name').value = button.getAttribute('data-name');
|
||||||
|
editModal.querySelector('#edit_bunk_id').value = button.getAttribute('data-bunk-id');
|
||||||
|
editModal.querySelector('#edit_fuel_type_id').value = button.getAttribute('data-fuel-type-id');
|
||||||
|
editModal.querySelector('#edit_capacity').value = button.getAttribute('data-capacity');
|
||||||
|
});
|
||||||
|
|
||||||
|
const deleteModal = document.getElementById('deleteConfirmModal');
|
||||||
|
deleteModal.addEventListener('show.bs.modal', function (event) {
|
||||||
|
const button = event.relatedTarget;
|
||||||
|
const id = button.getAttribute('data-id');
|
||||||
|
deleteModal.querySelector('#delete-confirm-btn').href = 'tanks.php?action=delete&id=' + id;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
329
users.php
Normal file
329
users.php
Normal file
@ -0,0 +1,329 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
require_once 'db/config.php';
|
||||||
|
|
||||||
|
$notification = null;
|
||||||
|
|
||||||
|
// Handle Add, Edit, Delete actions
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$db = db();
|
||||||
|
// Add User
|
||||||
|
if (isset($_POST['add_user'])) {
|
||||||
|
$username = trim($_POST['username']);
|
||||||
|
$password = $_POST['password'];
|
||||||
|
$role_id = $_POST['role_id'];
|
||||||
|
$bunk_id = !empty($_POST['bunk_id']) ? $_POST['bunk_id'] : null;
|
||||||
|
|
||||||
|
if (!empty($username) && !empty($password) && !empty($role_id)) {
|
||||||
|
try {
|
||||||
|
$hashed_password = password_hash($password, PASSWORD_BCRYPT);
|
||||||
|
$stmt = $db->prepare("INSERT INTO users (username, password, role_id, bunk_id) VALUES (?, ?, ?, ?)");
|
||||||
|
$stmt->execute([$username, $hashed_password, $role_id, $bunk_id]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'User added successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error adding user: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Username, password, and role are required.', 'type' => 'warning'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Edit User
|
||||||
|
elseif (isset($_POST['edit_user'])) {
|
||||||
|
$id = $_POST['user_id'];
|
||||||
|
$username = trim($_POST['username']);
|
||||||
|
$role_id = $_POST['role_id'];
|
||||||
|
$bunk_id = !empty($_POST['bunk_id']) ? $_POST['bunk_id'] : null;
|
||||||
|
$password = $_POST['password'];
|
||||||
|
|
||||||
|
if (!empty($username) && !empty($role_id) && !empty($id)) {
|
||||||
|
try {
|
||||||
|
if (!empty($password)) {
|
||||||
|
$hashed_password = password_hash($password, PASSWORD_BCRYPT);
|
||||||
|
$stmt = $db->prepare("UPDATE users SET username = ?, role_id = ?, bunk_id = ?, password = ? WHERE id = ?");
|
||||||
|
$stmt->execute([$username, $role_id, $bunk_id, $hashed_password, $id]);
|
||||||
|
} else {
|
||||||
|
$stmt = $db->prepare("UPDATE users SET username = ?, role_id = ?, bunk_id = ? WHERE id = ?");
|
||||||
|
$stmt->execute([$username, $role_id, $bunk_id, $id]);
|
||||||
|
}
|
||||||
|
$_SESSION['notification'] = ['text' => 'User updated successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error updating user: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Username, role, and ID are required.', 'type' => 'warning'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header("Location: users.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete User (Soft Delete)
|
||||||
|
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
|
||||||
|
try {
|
||||||
|
$db = db();
|
||||||
|
$stmt = $db->prepare("UPDATE users SET deleted_at = NOW() WHERE id = ?");
|
||||||
|
$stmt->execute([$_GET['id']]);
|
||||||
|
$_SESSION['notification'] = ['text' => 'User deleted successfully!', 'type' => 'success'];
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$_SESSION['notification'] = ['text' => 'Error deleting user: ' . $e->getMessage(), 'type' => 'danger'];
|
||||||
|
}
|
||||||
|
header("Location: users.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_SESSION['notification'])) {
|
||||||
|
$notification = $_SESSION['notification'];
|
||||||
|
unset($_SESSION['notification']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch roles and bunks for dropdowns
|
||||||
|
$roles = db()->query("SELECT * FROM roles")->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
$bunks = db()->query("SELECT * FROM bunks WHERE deleted_at IS NULL")->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
$users = db()->query("SELECT u.*, r.name as role_name, b.name as bunk_name FROM users u JOIN roles r ON u.role_id = r.id LEFT JOIN bunks b ON u.bunk_id = b.id WHERE u.deleted_at IS NULL ORDER BY u.created_at DESC")->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
$page_title = "User Management";
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title><?= htmlspecialchars($page_title) ?> - Petrol Pump Management</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<?php include 'includes/header.php'; ?>
|
||||||
|
|
||||||
|
<div class="container mt-4">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||||
|
<h1><i class="bi bi-people-fill"></i> <?= htmlspecialchars($page_title) ?></h1>
|
||||||
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addUserModal">
|
||||||
|
<i class="bi bi-plus-circle"></i> Add New User
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Username</th>
|
||||||
|
<th>Role</th>
|
||||||
|
<th>Assigned Bunk</th>
|
||||||
|
<th>Created At</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php if (empty($users)): ?>
|
||||||
|
<tr>
|
||||||
|
<td colspan="6" class="text-center">No users found.</td>
|
||||||
|
</tr>
|
||||||
|
<?php else: ?>
|
||||||
|
<?php foreach ($users as $user): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?= htmlspecialchars($user['id']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($user['username']) ?></td>
|
||||||
|
<td><span class="badge bg-secondary"><?= htmlspecialchars($user['role_name']) ?></span></td>
|
||||||
|
<td><?= htmlspecialchars($user['bunk_name'] ?? 'N/A') ?></td>
|
||||||
|
<td><?= htmlspecialchars(date('Y-m-d H:i', strtotime($user['created_at']))) ?></td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-primary edit-btn"
|
||||||
|
data-bs-toggle="modal" data-bs-target="#editUserModal"
|
||||||
|
data-id="<?= $user['id'] ?>"
|
||||||
|
data-username="<?= htmlspecialchars($user['username']) ?>"
|
||||||
|
data-role-id="<?= $user['role_id'] ?>"
|
||||||
|
data-bunk-id="<?= $user['bunk_id'] ?>">
|
||||||
|
<i class="bi bi-pencil-square"></i>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-danger delete-btn"
|
||||||
|
data-bs-toggle="modal" data-bs-target="#deleteConfirmModal"
|
||||||
|
data-id="<?= $user['id'] ?>">
|
||||||
|
<i class="bi bi-trash"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Add User Modal -->
|
||||||
|
<div class="modal fade" id="addUserModal" tabindex="-1" aria-labelledby="addUserModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="addUserModalLabel">Add New User</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<form method="POST">
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="username" class="form-label">Username</label>
|
||||||
|
<input type="text" class="form-control" id="username" name="username" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="password" class="form-label">Password</label>
|
||||||
|
<input type="password" class="form-control" id="password" name="password" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="role_id" class="form-label">Role</label>
|
||||||
|
<select class="form-select" id="role_id" name="role_id" required>
|
||||||
|
<option value="">Select Role</option>
|
||||||
|
<?php foreach ($roles as $role): ?>
|
||||||
|
<option value="<?= $role['id'] ?>"><?= htmlspecialchars($role['name']) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="bunk_id" class="form-label">Assign to Bunk (Optional)</label>
|
||||||
|
<select class="form-select" id="bunk_id" name="bunk_id">
|
||||||
|
<option value="">Select Bunk</option>
|
||||||
|
<?php foreach ($bunks as $bunk): ?>
|
||||||
|
<option value="<?= $bunk['id'] ?>"><?= htmlspecialchars($bunk['name']) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" name="add_user" class="btn btn-primary">Save User</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Edit User Modal -->
|
||||||
|
<div class="modal fade" id="editUserModal" tabindex="-1" aria-labelledby="editUserModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<form method="POST">
|
||||||
|
<input type="hidden" name="user_id" id="edit_user_id">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="editUserModalLabel">Edit User</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="edit_username" class="form-label">Username</label>
|
||||||
|
<input type="text" class="form-control" id="edit_username" name="username" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="edit_password" class="form-label">New Password (optional)</label>
|
||||||
|
<input type="password" class="form-control" id="edit_password" name="password">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="edit_role_id" class="form-label">Role</label>
|
||||||
|
<select class="form-select" id="edit_role_id" name="role_id" required>
|
||||||
|
<option value="">Select Role</option>
|
||||||
|
<?php foreach ($roles as $role): ?>
|
||||||
|
<option value="<?= $role['id'] ?>"><?= htmlspecialchars($role['name']) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="edit_bunk_id" class="form-label">Assign to Bunk (Optional)</label>
|
||||||
|
<select class="form-select" id="edit_bunk_id" name="bunk_id">
|
||||||
|
<option value="">Select Bunk</option>
|
||||||
|
<?php foreach ($bunks as $bunk): ?>
|
||||||
|
<option value="<?= $bunk['id'] ?>"><?= htmlspecialchars($bunk['name']) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" name="edit_user" class="btn btn-primary">Save Changes</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Delete Confirmation Modal -->
|
||||||
|
<div class="modal fade" id="deleteConfirmModal" tabindex="-1" aria-labelledby="deleteConfirmModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="deleteConfirmModalLabel">Confirm Deletion</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
Are you sure you want to delete this user? This action cannot be undone.
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||||
|
<a href="#" id="delete-confirm-btn" class="btn btn-danger">Delete</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Toast Notification -->
|
||||||
|
<div class="position-fixed bottom-0 end-0 p-3 toast-container">
|
||||||
|
<div id="notificationToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
|
<div class="toast-header">
|
||||||
|
<strong class="me-auto">Notification</strong>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="toast-body">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
// Toast notification
|
||||||
|
<?php if ($notification): ?>
|
||||||
|
const toastEl = document.getElementById('notificationToast');
|
||||||
|
const toastBody = toastEl.querySelector('.toast-body');
|
||||||
|
|
||||||
|
toastEl.classList.remove('bg-success', 'bg-danger', 'bg-warning');
|
||||||
|
toastEl.classList.add('bg-<?= $notification["type"] ?>', 'text-white');
|
||||||
|
toastBody.textContent = '<?= addslashes(htmlspecialchars($notification["text"])) ?>';
|
||||||
|
|
||||||
|
const toast = new bootstrap.Toast(toastEl);
|
||||||
|
toast.show();
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
// Edit modal handler
|
||||||
|
const editUserModal = document.getElementById('editUserModal');
|
||||||
|
editUserModal.addEventListener('show.bs.modal', function (event) {
|
||||||
|
const button = event.relatedTarget;
|
||||||
|
const id = button.getAttribute('data-id');
|
||||||
|
const username = button.getAttribute('data-username');
|
||||||
|
const roleId = button.getAttribute('data-role-id');
|
||||||
|
const bunkId = button.getAttribute('data-bunk-id');
|
||||||
|
|
||||||
|
const modalTitle = editUserModal.querySelector('.modal-title');
|
||||||
|
const modalBodyInputId = editUserModal.querySelector('#edit_user_id');
|
||||||
|
const modalBodyInputUsername = editUserModal.querySelector('#edit_username');
|
||||||
|
const modalBodyInputRoleId = editUserModal.querySelector('#edit_role_id');
|
||||||
|
const modalBodyInputBunkId = editUserModal.querySelector('#edit_bunk_id');
|
||||||
|
|
||||||
|
modalTitle.textContent = 'Edit User: ' + username;
|
||||||
|
modalBodyInputId.value = id;
|
||||||
|
modalBodyInputUsername.value = username;
|
||||||
|
modalBodyInputRoleId.value = roleId;
|
||||||
|
modalBodyInputBunkId.value = bunkId;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete confirmation handler
|
||||||
|
const deleteConfirmModal = document.getElementById('deleteConfirmModal');
|
||||||
|
deleteConfirmModal.addEventListener('show.bs.modal', function (event) {
|
||||||
|
const button = event.relatedTarget;
|
||||||
|
const id = button.getAttribute('data-id');
|
||||||
|
const deleteBtn = deleteConfirmModal.querySelector('#delete-confirm-btn');
|
||||||
|
deleteBtn.href = 'users.php?action=delete&id=' + id;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
x
Reference in New Issue
Block a user