440 lines
15 KiB
PHP
440 lines
15 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Row Details</title>
|
|
<style>
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
margin: 0;
|
|
padding: 0;
|
|
background-color: #f4f4f4;
|
|
}
|
|
|
|
.container {
|
|
width: 80%;
|
|
margin: 20px auto;
|
|
background-color: #fff;
|
|
padding: 20px;
|
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
h2 {
|
|
color: #333;
|
|
text-align: center;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.details {
|
|
padding: 15px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 5px;
|
|
background-color: #f9f9f9;
|
|
}
|
|
|
|
.details th {
|
|
text-align: right; /* Justify table headings to the right */
|
|
}
|
|
|
|
.details p {
|
|
margin: 10px 0;
|
|
font-size: 16px;
|
|
}
|
|
|
|
.details p strong {
|
|
color: #333;
|
|
}
|
|
|
|
.back-link {
|
|
display: inline-block;
|
|
margin-top: 20px;
|
|
text-decoration: none;
|
|
color: #fff;
|
|
background-color: #007BFF;
|
|
padding: 10px 15px;
|
|
border-radius: 5px;
|
|
}
|
|
|
|
.back-link:hover {
|
|
background-color: #0056b3;
|
|
}
|
|
|
|
button {
|
|
padding: 10px 20px;
|
|
font-size: 1rem;
|
|
background-color: #007bff;
|
|
color: white;
|
|
border: none;
|
|
border-radius: 5px;
|
|
cursor: pointer;
|
|
transition: 0.3s;
|
|
}
|
|
|
|
button:hover {
|
|
background-color: #0056b3;
|
|
}
|
|
|
|
.editable {
|
|
padding: 5px;
|
|
font-size: 16px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 5px;
|
|
width: 90%;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
input:focus {
|
|
border-color: #007bff;
|
|
outline: none;
|
|
}
|
|
|
|
.edit-button {
|
|
margin-left: 10px;
|
|
padding: 5px 10px;
|
|
font-size: 0.9rem;
|
|
background-color: transparent;
|
|
border: none;
|
|
cursor: pointer;
|
|
transition: 0.3s;
|
|
}
|
|
|
|
.edit-button img {
|
|
width: 20px;
|
|
height: 20px;
|
|
}
|
|
|
|
.edit-button:hover img {
|
|
filter: brightness(0.8);
|
|
}
|
|
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<script>
|
|
|
|
document.addEventListener("DOMContentLoaded", function () {
|
|
let id = "<?php echo $_GET['id'];?>";
|
|
|
|
// Disable all dropdowns by default
|
|
document.querySelectorAll("select.editable").forEach((element) => {
|
|
element.disabled = true;
|
|
});
|
|
|
|
// Select all editable elements
|
|
document.querySelectorAll(".editable").forEach((element) => {
|
|
let oldValue = element.value || element.textContent.trim(); // Store initial value
|
|
|
|
element.addEventListener("focus", function () {
|
|
oldValue = this.value || this.textContent.trim(); // Store old value when focused
|
|
});
|
|
|
|
element.addEventListener("blur", function () {
|
|
let newValue = this.value || this.textContent.trim();
|
|
let column = this.getAttribute("data-column");
|
|
|
|
if (newValue !== oldValue) {
|
|
sendUpdate(id, column, oldValue, newValue, element);
|
|
}
|
|
});
|
|
|
|
element.addEventListener("keydown", function (event) {
|
|
if (event.key === "Enter") {
|
|
event.preventDefault(); // Prevent new line
|
|
this.blur(); // Trigger blur event to save changes
|
|
}
|
|
});
|
|
});
|
|
|
|
// Select all edit buttons
|
|
document.querySelectorAll(".edit-button").forEach((button) => {
|
|
button.addEventListener("click", function () {
|
|
editField(button);
|
|
});
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Enables editing for the field
|
|
*/
|
|
function editField(button) {
|
|
let element = button.parentElement.nextElementSibling.firstElementChild;
|
|
if (element.tagName === "INPUT") {
|
|
element.readOnly = false;
|
|
element.focus();
|
|
} else if (element.tagName === "SELECT") {
|
|
element.disabled = false; // Enable dropdown
|
|
element.focus();
|
|
} else {
|
|
element.contentEditable = true;
|
|
element.focus();
|
|
}
|
|
|
|
element.addEventListener("blur", function () {
|
|
if (element.tagName === "INPUT") {
|
|
element.readOnly = true;
|
|
} else if (element.tagName === "SELECT") {
|
|
element.disabled = true; // Disable dropdown
|
|
} else {
|
|
element.contentEditable = false;
|
|
}
|
|
}, { once: true });
|
|
}
|
|
|
|
/**
|
|
* Sends the updated data to the server
|
|
*/
|
|
function sendUpdate(flightId, column, oldValue, newValue, element) {
|
|
fetch("update_data.php", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
body: `id=${flightId}&column=${encodeURIComponent(column)}&old_value=${encodeURIComponent(oldValue)}&new_value=${encodeURIComponent(newValue)}`
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
console.log(`Updated: ${data.column} changed from '${data.old_value}' to '${data.new_value}'`);
|
|
oldValue = newValue; // ✅ Update oldValue to prevent reverting
|
|
} else {
|
|
alert("Error updating data");
|
|
if (element.tagName === "INPUT") {
|
|
element.value = oldValue; // ❌ Revert ONLY if update fails
|
|
} else {
|
|
element.textContent = oldValue; // ❌ Revert ONLY if update fails
|
|
}
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error("Fetch error:", error);
|
|
if (element.tagName === "INPUT") {
|
|
element.value = oldValue; // ❌ Revert only on network failure
|
|
} else {
|
|
element.textContent = oldValue; // ❌ Revert only on network failure
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
<?php
|
|
include("functions.php");
|
|
require_db_auth();
|
|
|
|
function opCancel() {
|
|
$conn = connectDb();
|
|
$sql = "UPDATE submitted SET status = 'CANCELED' where id = " . $_GET['id'];
|
|
$result = $conn->query($sql);
|
|
logJournal($conn, $_GET['id'], "Marked Canceled");
|
|
$conn->close();
|
|
}
|
|
|
|
function opLanded() {
|
|
|
|
$date = date('Y-m-d');
|
|
$time = urldecode($_GET['time']);
|
|
$landed_dt = $date . ' ' . $time;
|
|
|
|
$conn = connectDb();
|
|
$sql = "UPDATE submitted SET status = 'LANDED', landed_dt = ? WHERE id = ?";
|
|
|
|
$stmt = $conn->prepare($sql);
|
|
$stmt->bind_param("si", $landed_dt, $_GET['id']);
|
|
|
|
$stmt->execute();
|
|
$stmt->close();
|
|
|
|
logJournal($conn, $_GET['id'], "Marked Landed at time " . $time);
|
|
|
|
$conn->close();
|
|
|
|
}
|
|
|
|
function opDeparted() {
|
|
|
|
$date = date('Y-m-d');
|
|
$time = urldecode($_GET['time']);
|
|
$departed_dt = $date . ' ' . $time;
|
|
|
|
$conn = connectDb();
|
|
$sql = "UPDATE submitted SET status = 'DEPARTED', departed_dt = ? WHERE id = ?";
|
|
|
|
$stmt = $conn->prepare($sql);
|
|
$stmt->bind_param("si", $departed_dt, $_GET['id']);
|
|
|
|
$stmt->execute();
|
|
$stmt->close();
|
|
|
|
logJournal($conn, $_GET['id'], "Marked Departed at time " . $time);
|
|
|
|
$conn->close();
|
|
|
|
}
|
|
|
|
function opDelete() {
|
|
$conn = connectDb();
|
|
$sql = "UPDATE submitted SET status = 'DELETED' where id = " . $_GET['id'];
|
|
$result = $conn->query($sql);
|
|
logJournal($conn, $_GET['id'], "Marked Deleted");
|
|
$conn->close();
|
|
}
|
|
|
|
function opDetail() {
|
|
$conn = connectDb();
|
|
$sql = "SELECT * FROM submitted WHERE id = " . $_GET['id'];
|
|
$result = $conn->query($sql);
|
|
|
|
if ($result->num_rows > 0) {
|
|
// Output data of the row
|
|
$row = $result->fetch_assoc();
|
|
echo '<div class="container">';
|
|
echo '<table class="details">';
|
|
echo '<tr><th>Aircraft Reg</th><td><button class="edit-button" onclick="editField(this)"><img src="assets/edit.png" alt="Edit"></button></td><td><input type="text" class="editable" data-column="ac_reg" value="' . $row['ac_reg'] . '" readonly></td></tr>';
|
|
echo '<tr><th>Aircraft Type</th><td><button class="edit-button" onclick="editField(this)"><img src="assets/edit.png" alt="Edit"></button></td><td><input type="text" class="editable" data-column="ac_type" value="' . $row['ac_type'] . '" readonly></td></tr>';
|
|
echo '<tr><th>Callsign</th><td><button class="edit-button" onclick="editField(this)"><img src="assets/edit.png" alt="Edit"></button></td><td><input type="text" class="editable" data-column="ac_call" value="' . $row['ac_call'] . '" readonly></td></tr>';
|
|
echo '<tr><th>Captain</th><td><button class="edit-button" onclick="editField(this)"><img src="assets/edit.png" alt="Edit"></button></td><td><input type="text" class="editable" data-column="captain" value="' . $row['captain'] . '" readonly></td></tr>';
|
|
echo '<tr><th>Arriving From:</th><td><button class="edit-button" onclick="editField(this)"><img src="assets/edit.png" alt="Edit"></button></td><td><span class="editable" data-column="in_from">' . $row['in_from'] . '</span></td></tr>';
|
|
echo '<tr><th>POB IN</th><td><button class="edit-button" onclick="editField(this)"><img src="assets/edit.png" alt="Edit"></button></td><td><input type="number" class="editable" data-column="pob_in" value="' . $row['pob_in'] . '" readonly></td></tr>';
|
|
echo '<tr><th>ETA Z</th><td><button class="edit-button" onclick="editField(this)"><img src="assets/edit.png" alt="Edit"></button></td><td><input type="datetime-local" class="editable" data-column="eta" value="' . ($row['eta'] ? date('Y-m-d\TH:i', strtotime($row['eta'])) : '') . '" readonly></td></tr>';
|
|
echo '<tr><th>Fuel</th><td><button class="edit-button" onclick="editField(this)"><img src="assets/edit.png" alt="Edit"></button></td><td><select class="editable" data-column="fuel" onchange="this.blur()" disabled>';
|
|
echo '<option value="None"' . ($row['fuel'] === 'None' ? ' selected' : '') . '>None</option>';
|
|
echo '<option value="100LL"' . ($row['fuel'] === '100LL' ? ' selected' : '') . '>100LL</option>';
|
|
echo '<option value="JET A1"' . ($row['fuel'] === 'JET A1' ? ' selected' : '') . '>JET A1</option>';
|
|
echo '</select></td></tr>';
|
|
echo '<tr><th>POB OUT</th><td><button class="edit-button" onclick="editField(this)"><img src="assets/edit.png" alt="Edit"></button></td><td><input type="number" class="editable" data-column="pob_out" value="' . $row['pob_out'] . '" readonly></td></tr>';
|
|
echo '<tr><th>Outbound To</th><td><button class="edit-button" onclick="editField(this)"><img src="assets/edit.png" alt="Edit"></button></td><td><span class="editable" data-column="out_to">' . $row['out_to'] . '</span></td></tr>';
|
|
echo '<tr><th>ETD Z</th><td><button class="edit-button" onclick="editField(this)"><img src="assets/edit.png" alt="Edit"></button></td><td><input type="datetime-local" class="editable" data-column="etd" value="' . ($row['etd'] ? date('Y-m-d\TH:i', strtotime($row['etd'])) : '') . '" readonly></td></tr>';
|
|
echo '<tr><th>Email Address</th><td><button class="edit-button" onclick="editField(this)"><img src="assets/edit.png" alt="Edit"></button></td><td><input type="email" class="editable" data-column="email" value="' . $row['email'] . '" readonly></td></tr>';
|
|
echo '<tr><th>Phone</th><td><button class="edit-button" onclick="editField(this)"><img src="assets/edit.png" alt="Edit"></button></td><td><input type="tel" class="editable" data-column="phone" value="' . $row['phone'] . '" readonly></td></tr>';
|
|
echo '<tr><th>Notes</th><td></td><td>' . $row['notes'] . '</td></tr>';
|
|
echo '<tr><th>PPR created</th><td></td><td>' . $row['submitted_dt'] . ' by ' . $row['created_by'] . '</td></tr>';
|
|
echo '</table>';
|
|
|
|
// Fetch journal entries
|
|
$journalSql = "SELECT * FROM journal WHERE ppr_id = " . $_GET['id'] . " ORDER BY id DESC";
|
|
$journalResult = $conn->query($journalSql);
|
|
$journalCount = $journalResult->num_rows;
|
|
|
|
// Add button to toggle journal entries
|
|
echo '<br><button onclick="window.close()">Close Window</button>';
|
|
echo ' <button onclick="toggleJournal()">Show Journal Entries (' . $journalCount . ')</button>';
|
|
echo '<div id="journal-entries" style="display:none;">';
|
|
echo '<h3>Journal Entries</h3>';
|
|
echo '<table class="journal-table">';
|
|
echo '<tr><th>Timestamp</th><th>User</th><th>Entry</th></tr>';
|
|
|
|
if ($journalCount > 0) {
|
|
while ($journalRow = $journalResult->fetch_assoc()) {
|
|
echo '<tr>';
|
|
echo '<td>' . $journalRow['entry_dt'] . '</td>';
|
|
echo '<td>' . $journalRow['user'] . '</td>';
|
|
echo '<td>' . $journalRow['entry'] . '</td>';
|
|
echo '</tr>';
|
|
}
|
|
} else {
|
|
echo '<tr><td colspan="3">No journal entries found.</td></tr>';
|
|
}
|
|
|
|
echo '</table>';
|
|
echo '</div>';
|
|
echo '</div>';
|
|
} else {
|
|
echo "No details found for the given ID.";
|
|
}
|
|
$conn->close();
|
|
}
|
|
|
|
switch($_GET['op']) {
|
|
case "cancel":
|
|
opCancel();
|
|
break;
|
|
case "landed":
|
|
opLanded();
|
|
break;
|
|
case "departed":
|
|
opDeparted();
|
|
break;
|
|
case "delete":
|
|
opDelete();
|
|
break;
|
|
case "detail":
|
|
opDetail();
|
|
break;
|
|
|
|
default:
|
|
|
|
}
|
|
?>
|
|
|
|
<script>
|
|
function toggleJournal() {
|
|
var journalEntries = document.getElementById("journal-entries");
|
|
var toggleButton = document.querySelector("button[onclick='toggleJournal()']");
|
|
if (journalEntries.style.display === "none") {
|
|
journalEntries.style.display = "block";
|
|
toggleButton.textContent = "Hide Journal Entries";
|
|
} else {
|
|
journalEntries.style.display = "none";
|
|
toggleButton.textContent = "Show Journal Entries";
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.journal-table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.journal-table th, .journal-table td {
|
|
border: 1px solid #ddd;
|
|
padding: 8px;
|
|
text-align: left;
|
|
}
|
|
|
|
.journal-table th {
|
|
background-color: #f2f2f2;
|
|
color: #333;
|
|
}
|
|
|
|
.journal-table tr:nth-child(even) {
|
|
background-color: #f9f9f9;
|
|
}
|
|
|
|
.journal-table tr:hover {
|
|
background-color: #f1f1f1;
|
|
}
|
|
|
|
.edit-button {
|
|
margin-left: 10px;
|
|
padding: 5px 10px;
|
|
font-size: 0.9rem;
|
|
background-color: transparent;
|
|
border: none;
|
|
cursor: pointer;
|
|
transition: 0.3s;
|
|
}
|
|
|
|
.edit-button img {
|
|
width: 20px;
|
|
height: 20px;
|
|
}
|
|
|
|
.edit-button:hover img {
|
|
filter: brightness(0.8);
|
|
}
|
|
|
|
.editable {
|
|
background-color: transparent;
|
|
transition: background-color 0.3s ease;
|
|
}
|
|
|
|
.editable:focus {
|
|
background-color: white;
|
|
}
|
|
</style>
|
|
|