321 lines
12 KiB
PHP
321 lines
12 KiB
PHP
<?php
|
|
$headerStyle = 'light';
|
|
$rootPath = dirname(dirname(__DIR__));
|
|
include_once($rootPath . '/header.php');
|
|
checkAdmin();
|
|
|
|
// Fetch all trips with booking status
|
|
$trips_query = "
|
|
SELECT
|
|
trip_id, trip_name, location, start_date, end_date,
|
|
vehicle_capacity, places_booked, cost_members, published
|
|
FROM trips
|
|
ORDER BY start_date DESC
|
|
";
|
|
|
|
$result = $conn->query($trips_query);
|
|
$trips = [];
|
|
if ($result && $result->num_rows > 0) {
|
|
while ($row = $result->fetch_assoc()) {
|
|
$trips[] = $row;
|
|
}
|
|
}
|
|
?>
|
|
|
|
<style>
|
|
table {
|
|
width: 100%;
|
|
border-collapse: separate;
|
|
border-spacing: 0;
|
|
margin: 10px 0;
|
|
}
|
|
|
|
thead th {
|
|
cursor: pointer;
|
|
text-align: left;
|
|
padding: 10px;
|
|
font-weight: bold;
|
|
position: relative;
|
|
}
|
|
|
|
thead th::after {
|
|
content: '\25B2';
|
|
/* Up arrow */
|
|
font-size: 0.8em;
|
|
position: absolute;
|
|
right: 10px;
|
|
opacity: 0;
|
|
transition: opacity 0.2s;
|
|
}
|
|
|
|
thead th.asc::after {
|
|
content: '\25B2';
|
|
/* Up arrow */
|
|
opacity: 1;
|
|
}
|
|
|
|
thead th.desc::after {
|
|
content: '\25BC';
|
|
/* Down arrow */
|
|
opacity: 1;
|
|
}
|
|
|
|
tbody tr:nth-child(odd) {
|
|
background-color: transparent;
|
|
}
|
|
|
|
tbody tr:nth-child(even) {
|
|
background-color: rgb(255, 255, 255);
|
|
border-radius: 10px;
|
|
}
|
|
|
|
tbody td {
|
|
padding: 5px;
|
|
}
|
|
|
|
tbody tr:nth-child(even) td:first-child {
|
|
border-top-left-radius: 10px;
|
|
border-bottom-left-radius: 10px;
|
|
}
|
|
|
|
tbody tr:nth-child(even) td:last-child {
|
|
border-top-right-radius: 10px;
|
|
border-bottom-right-radius: 10px;
|
|
}
|
|
|
|
.filter-input {
|
|
width: 100%;
|
|
padding: 5px;
|
|
font-size: 16px;
|
|
background-color: rgb(255, 255, 255);
|
|
border-radius: 25px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.trips-section {
|
|
color: #484848;
|
|
background: #f9f9f7;
|
|
border: 1px solid #d8d8d8;
|
|
border-radius: 10px;
|
|
margin-top: 15px;
|
|
margin-bottom: 15px;
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
document.addEventListener("DOMContentLoaded", function() {
|
|
const tables = document.querySelectorAll("table");
|
|
tables.forEach((table) => {
|
|
const headers = table.querySelectorAll("thead th");
|
|
const rows = Array.from(table.querySelectorAll("tbody tr"));
|
|
const filterInput = table.previousElementSibling;
|
|
|
|
headers.forEach((header, index) => {
|
|
header.addEventListener("click", () => {
|
|
const sortedRows = rows.sort((a, b) => {
|
|
const aText = a.cells[index].textContent.trim().toLowerCase();
|
|
const bText = b.cells[index].textContent.trim().toLowerCase();
|
|
|
|
if (aText < bText) return -1;
|
|
if (aText > bText) return 1;
|
|
return 0;
|
|
});
|
|
|
|
if (header.classList.contains("asc")) {
|
|
header.classList.remove("asc");
|
|
header.classList.add("desc");
|
|
sortedRows.reverse();
|
|
} else {
|
|
headers.forEach(h => h.classList.remove("asc", "desc"));
|
|
header.classList.add("asc");
|
|
}
|
|
|
|
const tbody = table.querySelector("tbody");
|
|
tbody.innerHTML = "";
|
|
sortedRows.forEach(row => tbody.appendChild(row));
|
|
});
|
|
});
|
|
|
|
if (rows.length === 0) {
|
|
filterInput.style.display = "none";
|
|
} else {
|
|
filterInput.addEventListener("input", function() {
|
|
const filterValue = filterInput.value.trim().toLowerCase();
|
|
rows.forEach(row => {
|
|
const rowText = row.textContent.trim().toLowerCase();
|
|
row.style.display = rowText.includes(filterValue) ? "" : "none";
|
|
});
|
|
});
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<?php
|
|
$bannerFolder = 'assets/images/banners/';
|
|
$bannerImages = glob($bannerFolder . '*.{jpg,jpeg,png,webp}', GLOB_BRACE);
|
|
|
|
$randomBanner = 'assets/images/base4/camping.jpg'; // default fallback
|
|
if (!empty($bannerImages)) {
|
|
$randomBanner = $bannerImages[array_rand($bannerImages)];
|
|
}
|
|
?>
|
|
<section class="page-banner-area pt-50 pb-35 rel z-1 bgs-cover" style="background-image: url('<?php echo $randomBanner; ?>');">
|
|
<div class="banner-overlay"></div>
|
|
<div class="container">
|
|
<div class="banner-inner text-white mb-50">
|
|
<h2 class="page-title mb-10" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">Manage Trips</h2>
|
|
<nav aria-label="breadcrumb">
|
|
<ol class="breadcrumb justify-content-center mb-20" data-aos="fade-right" data-aos-delay="200" data-aos-duration="1500" data-aos-offset="50">
|
|
<li class="breadcrumb-item"><a href="index">Home</a></li>
|
|
<li class="breadcrumb-item active">Manage Trips</li>
|
|
</ol>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Trips Management Area start -->
|
|
<section class="tour-list-page py-100 rel z-1">
|
|
<div class="container">
|
|
<div style="margin-bottom: 20px;">
|
|
<a href="manage_trips" class="theme-btn">
|
|
<i class="far fa-plus"></i> Create New Trip
|
|
</a>
|
|
</div>
|
|
|
|
<?php
|
|
if (count($trips) > 0) {
|
|
echo '<input type="text" class="filter-input" placeholder="Filter trips...">';
|
|
echo '<div class="trips-section" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">';
|
|
echo '<div style="padding:10px;">';
|
|
echo '<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Trip Name</th>
|
|
<th>Location</th>
|
|
<th>Start Date</th>
|
|
<th>End Date</th>
|
|
<th>Capacity</th>
|
|
<th>Booked</th>
|
|
<th>Cost (Member)</th>
|
|
<th>Status</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>';
|
|
foreach ($trips as $trip) {
|
|
$publishButtonText = $trip['published'] == 1 ? 'Unpublish' : 'Publish';
|
|
$publishButtonClass = $trip['published'] == 1 ? 'btn-warning' : 'btn-success';
|
|
echo '<tr>
|
|
<td><strong>' . htmlspecialchars($trip['trip_name']) . '</strong></td>
|
|
<td>' . htmlspecialchars($trip['location']) . '</td>
|
|
<td>' . date('M d, Y', strtotime($trip['start_date'])) . '</td>
|
|
<td>' . date('M d, Y', strtotime($trip['end_date'])) . '</td>
|
|
<td>' . $trip['vehicle_capacity'] . '</td>
|
|
<td><span class="badge bg-info">' . $trip['places_booked'] . ' / ' . $trip['vehicle_capacity'] . '</span></td>
|
|
<td>R ' . number_format($trip['cost_members'], 2) . '</td>
|
|
<td>' . ($trip['published'] == 1 ? '<span class="badge bg-success">Published</span>' : '<span class="badge bg-warning">Draft</span>') . '</td>
|
|
<td>
|
|
<a href="manage_trips?trip_id=' . $trip['trip_id'] . '" class="btn btn-sm btn-primary" title="Edit">
|
|
<i class="far fa-edit"></i>
|
|
</a>
|
|
<button class="btn btn-sm ' . $publishButtonClass . ' toggle-publish" data-trip-id="' . $trip['trip_id'] . '" title="' . $publishButtonText . '">
|
|
<i class="far fa-' . ($trip['published'] == 1 ? 'eye-slash' : 'eye') . '"></i>
|
|
</button>
|
|
<button class="btn btn-sm btn-danger delete-trip" data-trip-id="' . $trip['trip_id'] . '" title="Delete">
|
|
<i class="far fa-trash"></i>
|
|
</button>
|
|
</td>
|
|
</tr>';
|
|
}
|
|
echo '</tbody></table>';
|
|
echo '</div>';
|
|
echo '</div>';
|
|
} else {
|
|
echo '<p>No trips found. <a href="manage_trips">Create one</a></p>';
|
|
}
|
|
?>
|
|
</div>
|
|
</section>
|
|
<!-- Trips Management Area end -->
|
|
|
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
|
<script>
|
|
$(document).ready(function() {
|
|
$('.toggle-publish').on('click', function() {
|
|
var tripId = $(this).data('trip-id');
|
|
var button = $(this);
|
|
var row = button.closest('tr');
|
|
|
|
$.ajax({
|
|
url: 'toggle_trip_published',
|
|
type: 'POST',
|
|
data: {
|
|
trip_id: tripId
|
|
},
|
|
dataType: 'json',
|
|
success: function(response) {
|
|
if (response.status === 'success') {
|
|
// Update button appearance
|
|
if (response.published == 1) {
|
|
button.removeClass('btn-success').addClass('btn-warning');
|
|
button.find('i').removeClass('fa-eye').addClass('fa-eye-slash');
|
|
button.attr('title', 'Unpublish');
|
|
// Update status badge
|
|
row.find('td:nth-child(8)').html('<span class="badge bg-success">Published</span>');
|
|
} else {
|
|
button.removeClass('btn-warning').addClass('btn-success');
|
|
button.find('i').removeClass('fa-eye-slash').addClass('fa-eye');
|
|
button.attr('title', 'Publish');
|
|
// Update status badge
|
|
row.find('td:nth-child(8)').html('<span class="badge bg-warning">Draft</span>');
|
|
}
|
|
} else {
|
|
alert('Error: ' + response.message);
|
|
}
|
|
},
|
|
error: function() {
|
|
alert('Error updating trip status');
|
|
}
|
|
});
|
|
});
|
|
|
|
$('.delete-trip').on('click', function() {
|
|
if (!confirm('Are you sure you want to delete this trip? This action cannot be undone.')) {
|
|
return false;
|
|
}
|
|
|
|
var tripId = $(this).data('trip-id');
|
|
var button = $(this);
|
|
var row = button.closest('tr');
|
|
|
|
$.ajax({
|
|
url: 'delete_trip',
|
|
type: 'POST',
|
|
data: {
|
|
trip_id: tripId
|
|
},
|
|
dataType: 'json',
|
|
success: function(response) {
|
|
if (response.status === 'success') {
|
|
row.fadeOut(function() {
|
|
$(this).remove();
|
|
if ($('table tbody tr').length === 0) {
|
|
location.reload();
|
|
}
|
|
});
|
|
} else {
|
|
alert('Error: ' + response.message);
|
|
}
|
|
},
|
|
error: function() {
|
|
alert('Error deleting trip');
|
|
}
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<?php include_once($rootPath . '/components/insta_footer.php'); ?>
|