- Create components/banner.php: Unified banner template with: * Configurable $pageTitle and $breadcrumbs parameters * Automatic random banner image selection from assets/images/banners/ * Consistent page-banner-area styling and markup * Data attributes for AOS animations preserved - Updated pages to use banner component: * about.php, blog.php, blog_details.php * bookings.php, campsites.php, contact.php * course_details.php, driver_training.php, events.php * membership.php, membership_application.php, membership_payment.php * trips.php, bush_mechanics.php, rescue_recovery.php * indemnity.php, basic_indemnity.php * best_of_the_eastern_cape_2024.php, 2025_agm_minutes.php - Results: * Eliminated ~90% duplicate code across 23 pages * Single source of truth for banner functionality * Easier future updates to banner styling/behavior * Breadcrumb navigation now consistent and parameterized
324 lines
15 KiB
PHP
324 lines
15 KiB
PHP
<?php
|
|
$headerStyle = 'light';
|
|
include_once('header.php');
|
|
checkUserSession();
|
|
$user_id = $_SESSION['user_id'];
|
|
|
|
?>
|
|
<style>
|
|
.image {
|
|
width: 400px;
|
|
/* Set your desired width */
|
|
height: 350px;
|
|
/* Set your desired height */
|
|
overflow: hidden;
|
|
/* Hide any overflow */
|
|
display: block;
|
|
/* Ensure proper block behavior */
|
|
}
|
|
|
|
.image img {
|
|
width: 100%;
|
|
/* Image scales to fill the container */
|
|
height: 100%;
|
|
/* Image scales to fill the container */
|
|
object-fit: cover;
|
|
/* Fills the container while maintaining aspect ratio */
|
|
object-position: top;
|
|
/* Aligns the top of the image with the top of the container */
|
|
display: block;
|
|
/* Prevents inline whitespace issues */
|
|
}
|
|
|
|
.message-box {
|
|
text-align: center;
|
|
position: relative;
|
|
padding: 10px;
|
|
padding-right: 35px;
|
|
/* Ensures text doesn't overlap with the close button */
|
|
}
|
|
|
|
.close-btn {
|
|
position: absolute;
|
|
right: 10px;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
/* Centers vertically */
|
|
cursor: pointer;
|
|
font-size: 20px;
|
|
font-weight: bold;
|
|
color: #333;
|
|
background: none;
|
|
border: none;
|
|
}
|
|
|
|
.close-btn:hover {
|
|
color: red;
|
|
}
|
|
|
|
</style>
|
|
</style>
|
|
<?php
|
|
$pageTitle = 'My Bookings';
|
|
$breadcrumbs = [['Home' => 'index.php']];
|
|
require_once('components/banner.php');
|
|
?>
|
|
|
|
<!-- Tour List Area start -->
|
|
<section class="tour-list-page py-100 rel z-1">
|
|
<div class="container">
|
|
<div class="row">
|
|
|
|
<div class="col-lg-12">
|
|
<?php if (isset($_SESSION['message'])): ?>
|
|
<div class="alert alert-warning message-box">
|
|
<?php echo $_SESSION['message']; ?>
|
|
<span class="close-btn" onclick="this.parentElement.style.display='none'">×</span>
|
|
</div>
|
|
<?php unset($_SESSION['message']); ?>
|
|
<?php endif; ?>
|
|
|
|
<div class="shop-shorter rel z-3 mb-20">
|
|
<!-- <ul class="grid-list mb-15 me-2">
|
|
<li><a href="#"><i class="fal fa-border-all"></i></a></li>
|
|
<li><a href="#"><i class="far fa-list"></i></a></li>
|
|
</ul> -->
|
|
<div class="sort-text mb-15 me-4 me-xl-auto">
|
|
<?php echo countUpcomingBookings($user_id); ?> Upcoming Bookings
|
|
</div>
|
|
<label>
|
|
<input type="checkbox" id="togglePastBookings" onchange="togglePastBookings()"> Show Past Bookings
|
|
</label>
|
|
<!-- <div class="sort-text mb-15 me-4">
|
|
Sort By
|
|
</div> -->
|
|
<!-- <select>
|
|
<option value="default" selected="">Sort By</option>
|
|
<option value="new">Newness</option>
|
|
<option value="old">Oldest</option>
|
|
<option value="hight-to-low">High To Low</option>
|
|
<option value="low-to-high">Low To High</option>
|
|
</select> -->
|
|
</div>
|
|
<?php
|
|
// Query to retrieve data from the bookings table
|
|
$sql = "SELECT * FROM bookings WHERE user_id = ? ORDER BY to_date DESC";
|
|
|
|
$stmt = $conn->prepare($sql);
|
|
$stmt->bind_param("i", $user_id);
|
|
$stmt->execute();
|
|
$result = $stmt->get_result();
|
|
|
|
if ($result->num_rows > 0) {
|
|
// Loop through each row
|
|
while ($row = $result->fetch_assoc()) {
|
|
$booking_id = $row['booking_id'];
|
|
$booking_type = $row['booking_type'];
|
|
$from_date = $row['from_date'];
|
|
$to_date = $row['to_date'];
|
|
$num_vehicles = $row['num_vehicles'];
|
|
$num_adults = $row['num_adults'];
|
|
$num_children = $row['num_children'];
|
|
$add_firewood = $row['add_firewood'];
|
|
$total_amount = $row['total_amount'];
|
|
$discount_amount = $row['discount_amount'];
|
|
$status = $row['status'];
|
|
$trip_id = $row['trip_id'];
|
|
$course_id = $row['course_id'];
|
|
$course_nonmembers = $row['course_non_members'];
|
|
$radio = $row['radio'];
|
|
$amount = $total_amount - $discount_amount;
|
|
$total_adults = $num_adults + $course_nonmembers;
|
|
|
|
if (!is_null($trip_id)) {
|
|
// Prepare a SQL statement to retrieve trip details
|
|
$sql_trip = "SELECT trip_name, location, short_description, start_date, end_date FROM trips WHERE trip_id = ?";
|
|
$stmt_trip = $conn->prepare($sql_trip);
|
|
$stmt_trip->bind_param("i", $trip_id);
|
|
|
|
if ($stmt_trip->execute()) {
|
|
$result_trip = $stmt_trip->get_result();
|
|
|
|
if ($result_trip->num_rows > 0) {
|
|
// Fetch trip details
|
|
$trip_data = $result_trip->fetch_assoc();
|
|
$trip_name = $trip_data['trip_name'] ?? "Trip Name Placeholder";
|
|
$location = $trip_data['location'] ?? "Location Placeholder";
|
|
$short_description = $trip_data['short_description'] ?? "Short description of the trip.";
|
|
$start_date = $trip_data['start_date'] ?? $from_date; // Default to booking start date if not set
|
|
$end_date = $trip_data['end_date'] ?? $to_date; // Default to booking end date if not set
|
|
|
|
} else {
|
|
// Set default values if no trip data found
|
|
$trip_name = "Trip Name Placeholder";
|
|
$location = "Location Placeholder";
|
|
$short_description = "Short description of the trip.";
|
|
$start_date = $from_date; // Default to booking start date
|
|
$end_date = $to_date; // Default to booking end date
|
|
}
|
|
} else {
|
|
// Handle SQL execution error
|
|
echo "Error retrieving trip information: " . $stmt_trip->error;
|
|
}
|
|
|
|
// Close the statement
|
|
$stmt_trip->close();
|
|
} elseif (!is_null($course_id)) {
|
|
// Prepare a SQL statement to retrieve trip details
|
|
$sql_course = "SELECT course_type, date FROM courses WHERE course_id = ?";
|
|
$stmt_course = $conn->prepare($sql_course);
|
|
$stmt_course->bind_param("i", $course_id);
|
|
|
|
if ($stmt_course->execute()) {
|
|
$result_course = $stmt_course->get_result();
|
|
|
|
if ($result_course->num_rows > 0) {
|
|
// Fetch trip details
|
|
$trip_data = $result_course->fetch_assoc();
|
|
$date = $trip_data['date'] ?? "Location Placeholder";
|
|
$type = $trip_data['course_type'] ?? "Trip Name Placeholder";
|
|
if ($type === "driver_training") {
|
|
$trip_name = "Basic 4X4 Driver Training Course";
|
|
} elseif ($type === "bush_mechanics") {
|
|
$trip_name = "Bush Mechanics Course";
|
|
} elseif ($type === "rescue_recovery") {
|
|
$trip_name = "Rescue & Recovery Training Course";
|
|
} else {
|
|
$trip_name = "General Course"; // Default fallback description
|
|
}
|
|
$start_date = $date;
|
|
$end_date = $date;
|
|
$location = "BASE4, Hennops";
|
|
$short_description = getDetail($type);
|
|
} else {
|
|
// Set default values if no trip data found
|
|
$trip_name = "Trip Name Placeholder";
|
|
$location = "BASE4, Hennops";
|
|
$short_description = getDetail($type);
|
|
$start_date = $from_date; // Default to booking start date
|
|
$end_date = $to_date; // Default to booking end date
|
|
}
|
|
} else {
|
|
// Handle SQL execution error
|
|
echo "Error retrieving trip information: " . $stmt_course->error;
|
|
}
|
|
|
|
// Close the statement
|
|
$stmt_course->close();
|
|
} else {
|
|
// Set default values if trip_id is null
|
|
$trip_name = "BASE4 Camping";
|
|
$location = "BASE4, Hennops";
|
|
$short_description = "Please remember to bring 2 bags of firewood and drinking water for personal use.";
|
|
$start_date = $from_date; // Default to booking start date
|
|
$end_date = $to_date; // Default to booking end date
|
|
}
|
|
|
|
// Get today's date
|
|
$today = date("Y-m-d");
|
|
|
|
// Determine if the date is past or future
|
|
if ($end_date < $today) {
|
|
$tense = 'past';
|
|
} else {
|
|
$tense = 'future';
|
|
}
|
|
|
|
// Output the HTML structure with dynamic data
|
|
echo '
|
|
<div class="destination-item style-three bgc-lighter booking ' . $tense . '" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
|
<div class="image">';
|
|
if ($booking_type === 'trip') {
|
|
echo '<img src="assets/images/trips/' . $trip_id . '_01.jpg" alt="' . htmlspecialchars($trip_name) . '">';
|
|
} elseif ($booking_type === 'course') {
|
|
echo '<img src="assets/images/courses/' . $type . '.png" alt="' . htmlspecialchars($trip_name) . '">';
|
|
} else {
|
|
echo '<img style="width:450px;" src="assets/images/base4/base4.jpg" alt="Base4">';
|
|
}
|
|
echo '
|
|
</div>
|
|
<div class="content">
|
|
<div class="destination-header">
|
|
<span class="location"><i class="fal fa-map-marker-alt"></i> ' . htmlspecialchars($location) . '</span>
|
|
|
|
</div>
|
|
<h5>' . htmlspecialchars($trip_name) . '</a></h5>
|
|
<p>' . htmlspecialchars($short_description) . '</p>
|
|
<ul class="blog-meta">';
|
|
if ($booking_type === 'course') {
|
|
echo '<li><i class="far fa-calendar"></i> ' . convertDate($start_date) . '</li>';
|
|
} else {
|
|
echo '<li><i class="far fa-calendar"></i> ' . convertDate($start_date) . ' - ' . convertDate($end_date) . '</li>
|
|
<li><i class="far fa-clock"></i> ' . calculateDaysAndNights($start_date, $end_date) . '</li>';
|
|
} ?>
|
|
<li><i class="far fa-user"></i>
|
|
<?php
|
|
echo $num_vehicles . ' ' . ($num_vehicles > 1 ? 'vehicles' : 'vehicle') . ' ' .
|
|
$total_adults . ' ' . ($total_adults > 1 ? 'adults' : 'adult');
|
|
if ($num_children > 0) {
|
|
echo ' ' . $num_children . ' ' . ($num_children > 1 ? 'children' : 'child');
|
|
}
|
|
?>
|
|
</li>
|
|
|
|
<?php echo '
|
|
</ul>
|
|
<div class="destination-footer">
|
|
<span class="price"><span>Booking Total: R ' . number_format($amount, 2) . '</span></span>';
|
|
if ($status == "AWAITING PAYMENT") {
|
|
echo '<a href="payment_confirmation.php?token=' . encryptData($booking_id, $salt) . '" class="theme-btn style-two style-three">
|
|
<span data-hover="PAYMENT INFO">' . $status . '</span>
|
|
</a>';
|
|
} else {
|
|
echo '<a href="" class="theme-btn style-two style-three">
|
|
<span data-hover="' . $status . '">' . $status . '</span>
|
|
</a>';
|
|
}
|
|
echo '
|
|
|
|
</div>
|
|
</div>
|
|
</div>';
|
|
}
|
|
} else {
|
|
echo '<p>You have no upcoming bookings.</p>';
|
|
}
|
|
|
|
|
|
// Close connection
|
|
$conn->close();
|
|
?>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<!-- Tour List Area end -->
|
|
<script>
|
|
function togglePastBookings() {
|
|
// Get the checkbox element
|
|
const checkbox = document.getElementById('togglePastBookings');
|
|
|
|
// Select all elements with the class 'past'
|
|
const pastBookings = document.querySelectorAll('.booking.past');
|
|
|
|
// Show or hide past bookings based on the checkbox state
|
|
pastBookings.forEach(booking => {
|
|
booking.style.display = checkbox.checked ? '' : 'none';
|
|
});
|
|
}
|
|
// Run the function on page load
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
// Set the initial state of the checkbox if needed
|
|
const checkbox = document.getElementById('togglePastBookings');
|
|
checkbox.checked = false; // Optional: Start with checkbox unchecked
|
|
|
|
// Call the function to set the initial state of past bookings
|
|
togglePastBookings();
|
|
});
|
|
</script>
|
|
|
|
|
|
|
|
<?php include_once("insta_footer.php"); ?>
|