Code restructure push
This commit is contained in:
325
src/pages/bookings/bookings.php
Normal file
325
src/pages/bookings/bookings.php
Normal file
@@ -0,0 +1,325 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/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($rootPath . '/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="' . url('payment_confirmation') . '?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(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
217
src/pages/bookings/campsite_booking.php
Normal file
217
src/pages/bookings/campsite_booking.php
Normal file
@@ -0,0 +1,217 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once(dirname(dirname(dirname(__DIR__))) . '/header.php');
|
||||
checkUserSession();
|
||||
?>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Gallery Area start -->
|
||||
<section class="gallery-slider-area pt-100 rel z-1">
|
||||
|
||||
<div class="gallery-slider-active">
|
||||
<div class="gallery-three-item" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image">
|
||||
<img src="assets/images/gallery/gallery-slider1.jpg" alt="Gallery">
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="category">Tour & Travel</span>
|
||||
<h5><a href="destination-details.html">Brown Concrete Building</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gallery-three-item" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image">
|
||||
<img src="assets/images/gallery/gallery-slider2.jpg" alt="Gallery">
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="category">Tour & Travel</span>
|
||||
<h5><a href="destination-details.html">Brown Concrete Building</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gallery-three-item" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image">
|
||||
<img src="assets/images/gallery/gallery-slider3.jpg" alt="Gallery">
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="category">Tour & Travel</span>
|
||||
<h5><a href="destination-details.html">Brown Concrete Building</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gallery-three-item" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image">
|
||||
<img src="assets/images/gallery/gallery-slider4.jpg" alt="Gallery">
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="category">Tour & Travel</span>
|
||||
<h5><a href="destination-details.html">Brown Concrete Building</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gallery-three-item" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image">
|
||||
<img src="assets/images/gallery/gallery-slider5.jpg" alt="Gallery">
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="category">Tour & Travel</span>
|
||||
<h5><a href="destination-details.html">Brown Concrete Building</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Gallery Area end -->
|
||||
|
||||
|
||||
|
||||
<!-- About Us Area start -->
|
||||
<section class="about-us-area pt-90 pb-100 rel z-1">
|
||||
<div class="container">
|
||||
<div class="row gap-100 align-items-center">
|
||||
<div class="col-lg-6">
|
||||
<div class="destination-details-content rmb-55" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="section-title mb-25">
|
||||
<span class="h2 mb-15">Welcome to </span>
|
||||
<h2>BASE4 Camping</h2>
|
||||
</div>
|
||||
<p>Escape to the ultimate outdoor adventure at BASE4, nestled right next to a tranquil stream. Enjoy the perfect blend of rugged exploration and relaxation with top-notch facilities, including braai areas, hot showers, and clean ablution blocks. Gather with friends under our spacious lapa or take a dip in the refreshing swimming pool after a day of off-road fun. Whether you're conquering trails or kicking back by the fire, our campsite offers the ideal setting for an unforgettable getaway. Book your spot today and experience nature at its finest!</p>
|
||||
|
||||
</div>
|
||||
<div class="widget widget-booking" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<h5 class="widget-title">Book your Campsite</h5>
|
||||
<form action="process_camp_booking" method="POST">
|
||||
<div class="date mb-25">
|
||||
<b>From Date</b>
|
||||
<input type="date" id="from_date" name="from_date">
|
||||
</div>
|
||||
<div class="date mb-25">
|
||||
<b>To Date</b>
|
||||
<input type="date" id="to_date" name="to_date">
|
||||
</div>
|
||||
<hr class="mb-25">
|
||||
<ul class="tickets clearfix">
|
||||
<li>
|
||||
No. of Vehicles
|
||||
<input style="border-color: #d7d7d7;width:auto;padding:10px;" type="number" id="vehicles" name="vehicles" value="1" min="1">
|
||||
</li>
|
||||
<li>
|
||||
No. of Adults
|
||||
<input style="border-color: #d7d7d7;width:auto;padding:10px;" type="number" id="adults" name="adults" value="1" min="1">
|
||||
</li>
|
||||
<li>
|
||||
No. of Children
|
||||
<input style="border-color: #d7d7d7;width:auto;padding:10px;" type="number" id="children" name="children" value="0" min="0">
|
||||
</li>
|
||||
</ul>
|
||||
<hr class="mb-25">
|
||||
<h6>Add Extra:</h6>
|
||||
<ul class="radio-filter pt-5">
|
||||
<li>
|
||||
<input class="form-check-input" type="checkbox" name="AddExtra" id="add-extra1" value="50">
|
||||
<label for="add-extra1">2 x 5kg Firewood <span>R 50,00</span></label>
|
||||
</li>
|
||||
</ul>
|
||||
<hr>
|
||||
|
||||
<?php if ($is_member) : ?>
|
||||
<div id="discount_section">
|
||||
<h6>Discount:</h6>
|
||||
<ul class="radio-filter pt-5">
|
||||
<li>
|
||||
<label for="add-extra1">4WDCSA Member Discount <span id="discount_amount">R 0,00</span></label>
|
||||
</li>
|
||||
</ul>
|
||||
<hr>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<h6>Total: <span id="booking_total" class="price">-</span></h6>
|
||||
<input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
|
||||
<button type="submit" class="theme-btn style-two w-100 mt-15 mb-5">
|
||||
<span data-hover="Book Now">Book Now</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</button>
|
||||
<div class="text-center">
|
||||
<a href="contact.html">Need some help?</a> | Payments will be redirected to Payfast.
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="col-lg-6" data-aos="fade-right" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="destination-map">
|
||||
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d667.578212275918!2d28.000752737032542!3d-25.864032288240537!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x1e95794b858a5427%3A0xcdb0a4b0055a9753!2sFour%20Wheel%20Drive%20Club%20of%20Southern%20Africa%20-FWDCSA%20GAUTENG%20-%20BASE%204!5e1!3m2!1sen!2sza!4v1726669599601!5m2!1sen!2sza" width="100%" style="border:0;" allowfullscreen="" loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- About Us Area end -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Function to calculate booking total
|
||||
function calculateTotal() {
|
||||
var fromDate = new Date($('#from_date').val());
|
||||
var toDate = new Date($('#to_date').val());
|
||||
var vehicles = parseInt($('#vehicles').val()) || 1;
|
||||
var firewoodCost = $('#add-extra1').is(':checked') ? 50 : 0;
|
||||
var isMember = <?php echo $is_member ? 'true' : 'false'; ?>;
|
||||
|
||||
var perNightRate = 200;
|
||||
if (isMember) {
|
||||
perNightRate = 0; // 100% discount
|
||||
}
|
||||
|
||||
// Calculate nights
|
||||
var timeDifference = toDate.getTime() - fromDate.getTime();
|
||||
var nights = Math.ceil(timeDifference / (1000 * 3600 * 24));
|
||||
|
||||
if (nights < 1) {
|
||||
nights = 0; // If "To Date" is before "From Date", no charge
|
||||
}
|
||||
|
||||
// Calculate total
|
||||
var total = (nights * perNightRate * vehicles) + firewoodCost;
|
||||
|
||||
// Update total in the DOM
|
||||
$('#booking_total').text('R ' + total.toFixed(2));
|
||||
|
||||
// Update discount section
|
||||
if (isMember) {
|
||||
var discountAmount = nights * 200 * vehicles; // Original rate * nights * vehicles
|
||||
$('#discount_amount').text('R ' + discountAmount.toFixed(2));
|
||||
}
|
||||
}
|
||||
|
||||
// Function to restrict date selection
|
||||
function restrictDates() {
|
||||
var today = new Date().toISOString().split('T')[0]; // Get today's date in YYYY-MM-DD format
|
||||
$('#from_date').attr('min', today); // Set min for from_date
|
||||
|
||||
var fromDate = $('#from_date').val();
|
||||
if (fromDate) {
|
||||
$('#to_date').attr('min', fromDate); // Set min for to_date based on from_date
|
||||
} else {
|
||||
$('#to_date').attr('min', today); // Default to today's date if no from_date is set
|
||||
}
|
||||
}
|
||||
|
||||
// Event listeners to trigger recalculation and date restriction
|
||||
$('#from_date').on('change', function() {
|
||||
restrictDates();
|
||||
calculateTotal();
|
||||
});
|
||||
|
||||
$('#to_date, #vehicles, #add-extra1').on('change', function() {
|
||||
calculateTotal();
|
||||
});
|
||||
|
||||
// Initial setup for date restrictions and calculation
|
||||
restrictDates();
|
||||
calculateTotal();
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php') ?>
|
||||
195
src/pages/bookings/campsites.php
Normal file
195
src/pages/bookings/campsites.php
Normal file
@@ -0,0 +1,195 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
|
||||
$conn = openDatabaseConnection();
|
||||
$stmt = $conn->prepare("SELECT * FROM campsites");
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$campsites = [];
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$campsites[] = $row;
|
||||
}
|
||||
?>
|
||||
|
||||
<style>
|
||||
#map {
|
||||
height: 600px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.gm-style .info-box {
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
.info-box img {
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
||||
|
||||
</style>
|
||||
|
||||
<?php
|
||||
$pageTitle = 'Campsites';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once($rootPath . '/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">
|
||||
|
||||
<div id="map" style="width: 100%; height: 500px;"></div>
|
||||
<!-- Add Campsite Modal -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<div class="modal fade" id="addCampsiteModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<form id="addCampsiteForm" method="POST" action="add_campsite" enctype="multipart/form-data">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Add Campsite</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<input type="hidden" name="latitude" id="latitude">
|
||||
<input type="hidden" name="longitude" id="longitude">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Campsite Name</label>
|
||||
<input type="text" class="form-control" name="name" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Description</label>
|
||||
<textarea class="form-control" name="description" rows="3"></textarea>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Booking URL</label>
|
||||
<input type="url" class="form-control" name="website">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Phone Number</label>
|
||||
<input type="text" class="form-control" name="telephone">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Thumbnail Image</label>
|
||||
<input type="file" class="form-control" name="thumbnail" accept="image/*">
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-primary" type="submit">Save Campsite</button>
|
||||
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
let map;
|
||||
const campsites = <?php echo json_encode($campsites); ?>;
|
||||
|
||||
function initMap() {
|
||||
map = new google.maps.Map(document.getElementById("map"), {
|
||||
center: {
|
||||
lat: -28.0,
|
||||
lng: 24.0
|
||||
}, // SA center
|
||||
zoom: 6,
|
||||
});
|
||||
|
||||
map.addListener("click", function(e) {
|
||||
const lat = e.latLng.lat();
|
||||
const lng = e.latLng.lng();
|
||||
|
||||
document.getElementById("latitude").value = lat;
|
||||
document.getElementById("longitude").value = lng;
|
||||
|
||||
const addModal = new bootstrap.Modal(document.getElementById("addCampsiteModal"));
|
||||
addModal.show();
|
||||
});
|
||||
|
||||
// Load existing campsites from PHP
|
||||
fetch("get_campsites.php")
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
data.forEach(site => {
|
||||
const marker = new google.maps.Marker({
|
||||
position: {
|
||||
lat: parseFloat(site.latitude),
|
||||
lng: parseFloat(site.longitude)
|
||||
},
|
||||
map,
|
||||
title: site.name,
|
||||
});
|
||||
|
||||
const content = `
|
||||
<div class="info-box">
|
||||
<strong>${site.name}</strong><br>
|
||||
${site.description ? site.description + "<br>" : ""}
|
||||
${site.website ? `<a href="${site.website}" target="_blank">Visit Website</a><br>` : ""}
|
||||
${site.telephone ? `Phone: ${site.telephone}<br>` : ""}
|
||||
${site.thumbnail ? `<img src="${site.thumbnail}" style="width: 100%; max-width: 200px; border-radius: 8px; margin-top: 5px;">` : ""}
|
||||
${site.user && site.user.first_name ? `
|
||||
<div class="user-info mt-2 d-flex align-items-center">
|
||||
<img src="${site.user.profile_pic}" style="width: 40px; height: 40px; border-radius: 50%; object-fit: cover; margin-right: 10px;">
|
||||
<div>
|
||||
<small>Added by:</small><br>
|
||||
<strong>${site.user.first_name} ${site.user.last_name}</strong>
|
||||
</div>
|
||||
</div>` : ""}
|
||||
<br>
|
||||
<button class="btn btn-sm btn-warning mt-2" onclick='editCampsite(${JSON.stringify(site)})'>Edit</button>
|
||||
<a href="https://www.google.com/maps/dir/?api=1&destination=${site.latitude},${site.longitude}" target="_blank" class="btn btn-sm btn-outline-primary mt-2 ms-2">Get Directions</a>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const infowindow = new google.maps.InfoWindow({
|
||||
content: content
|
||||
});
|
||||
|
||||
marker.addListener("click", () => {
|
||||
infowindow.open(map, marker);
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(err => console.error("Failed to load campsites:", err));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function editCampsite(site) {
|
||||
// Pre-fill form
|
||||
document.querySelector("#addCampsiteForm input[name='name']").value = site.name;
|
||||
document.querySelector("#addCampsiteForm textarea[name='description']").value = site.description || "";
|
||||
document.querySelector("#addCampsiteForm input[name='website']").value = site.website || "";
|
||||
document.querySelector("#addCampsiteForm input[name='telephone']").value = site.telephone || "";
|
||||
document.querySelector("#addCampsiteForm input[name='latitude']").value = site.latitude;
|
||||
document.querySelector("#addCampsiteForm input[name='longitude']").value = site.longitude;
|
||||
|
||||
// Add hidden ID input
|
||||
let idInput = document.querySelector("#addCampsiteForm input[name='id']");
|
||||
if (!idInput) {
|
||||
idInput = document.createElement("input");
|
||||
idInput.type = "hidden";
|
||||
idInput.name = "id";
|
||||
document.querySelector("#addCampsiteForm").appendChild(idInput);
|
||||
}
|
||||
idInput.value = site.id;
|
||||
|
||||
// Show the modal
|
||||
const addModal = new bootstrap.Modal(document.getElementById("addCampsiteModal"));
|
||||
addModal.show();
|
||||
}
|
||||
</script>
|
||||
|
||||
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyC-JuvnbUYc8WGjQBFFVZtKiv5_bFJoWLU&callback=initMap" async defer></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php'); ?>
|
||||
303
src/pages/bookings/course_details.php
Normal file
303
src/pages/bookings/course_details.php
Normal file
@@ -0,0 +1,303 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
|
||||
// SQL query to fetch dates for driver training
|
||||
$stmt = $conn->prepare("SELECT course_id, date FROM courses WHERE course_type = ?");
|
||||
$course_type = 'driver_training';
|
||||
$stmt->bind_param("s", $course_type);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
?>
|
||||
|
||||
|
||||
|
||||
<?php
|
||||
$pageTitle = 'Course Details';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
<!-- Page Banner End -->
|
||||
|
||||
<!-- Product Details Start -->
|
||||
<section class="product-details pt-100">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="product-details-images rmb-55" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="tab-content preview-images">
|
||||
<div class="tab-pane fade preview-item active show" id="preview1">
|
||||
<img src="assets/images/shop/preview1.png" alt="Perview">
|
||||
</div>
|
||||
<div class="tab-pane fade preview-item" id="preview2">
|
||||
<img src="assets/images/shop/preview1.png" alt="Perview">
|
||||
</div>
|
||||
<div class="tab-pane fade preview-item" id="preview3">
|
||||
<img src="assets/images/shop/preview1.png" alt="Perview">
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav thumb-images rmb-20">
|
||||
<a href="#preview1" data-bs-toggle="tab" class="thumb-item active show">
|
||||
<img src="assets/images/shop/thumb1.png" alt="Thumb">
|
||||
</a>
|
||||
<a href="#preview2" data-bs-toggle="tab" class="thumb-item">
|
||||
<img src="assets/images/shop/thumb2.png" alt="Thumb">
|
||||
</a>
|
||||
<a href="#preview3" data-bs-toggle="tab" class="thumb-item">
|
||||
<img src="assets/images/shop/thumb3.png" alt="Thumb">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="product-details-content" data-aos="fade-right" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="section-title">
|
||||
<h2>4X4 Driver Training</h2>
|
||||
</div>
|
||||
<!-- <div class="ratting mb-15">
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star-half-alt"></i>
|
||||
<span>(5.8k+ reviews)</span>
|
||||
</div> -->
|
||||
<span class="price mb-5">R 50,00/member</span>
|
||||
<span class="price mb-25">R 750,00/non-members</span>
|
||||
<p>Our 4x4 Basic Training Course equips you with the essential skills and knowledge to confidently tackle off-road terrains. Learn vehicle mechanics, driving techniques, obstacle navigation, and recovery methods while promoting safe and responsible off-road practices. Perfect for beginners and new 4x4 owners!</p>
|
||||
<hr class="mt-40">
|
||||
<form action="#" class="add-to-cart pt-15 pb-30">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
|
||||
<label for="course_date">Select a Date:</label>
|
||||
<select name="course_date" id="course_date" required>
|
||||
<!-- <option value="" disabled selected>-- Select a Date --</option> -->
|
||||
<?php
|
||||
if ($result->num_rows > 0) {
|
||||
// Output each course as an option
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$course_id = htmlspecialchars($row['course_id']); // Escape output for security
|
||||
$date = htmlspecialchars($row['date']); // Escape output for security
|
||||
echo "<option value='$course_id'>$date</option>";
|
||||
}
|
||||
} else {
|
||||
echo "<option value='' disabled>No dates available</option>";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<button type="submit" class="theme-btn style-two bgc-secondary">
|
||||
<span data-hover="Add to Cart">Book Now</span>
|
||||
<i class="far fa-arrow-right"></i>
|
||||
</button>
|
||||
</form>
|
||||
<hr class="mb-45">
|
||||
<a href="#" class="wishlist"><i class="far fa-heart"></i> Add to Wishlist</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="nav nav product-tab mt-70 mb-30" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<li><a href="#details" data-bs-toggle="tab" class="active show">Course Overview<i class="far fa-arrow-right"></i></a></li>
|
||||
<li><a href="#information" data-bs-toggle="tab">What to Expect<i class="far fa-arrow-right"></i></a></li>
|
||||
<!-- <li><a href="#reviews" data-bs-toggle="tab"> Reviews <i class="far fa-arrow-right"></i></a></li> -->
|
||||
</ul>
|
||||
<div class="tab-content" data-aos="fade-up" data-aos-delay="50" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="tab-pane fade active show" id="details">
|
||||
<p>A 4x4 Basic Training Course is designed to equip participants with the foundational knowledge and practical skills necessary for safe and effective off-road driving. This course covers essential topics such as understanding the mechanics of 4x4 vehicles, selecting the appropriate gear, and engaging various drive modes to tackle different terrains. Participants will learn how to navigate obstacles like mud, sand, and rocky paths while maintaining vehicle control and ensuring safety for themselves and their passengers. The training also includes instruction on tire pressure management, vehicle recovery techniques, and the use of essential recovery equipment like tow straps and shackles.</p>
|
||||
<p>In addition to practical driving exercises, the course emphasizes responsible off-road driving practices, including respecting the environment and adhering to trail etiquette. Whether you're a novice driver looking to explore off-road adventures or a new 4x4 owner seeking confidence behind the wheel, this training provides a comprehensive introduction to the world of off-roading. By the end of the course, participants will feel prepared to tackle basic off-road challenges with skill and assurance, making their next 4x4 outing a safe and enjoyable experience.</p>
|
||||
<div class="row gap-50 pt-25 pb-20 align-items-center">
|
||||
<div class="col-lg-7 pt-15">
|
||||
<h5>What this course includes</h5>
|
||||
<ul class="list-style-two mt-25">
|
||||
<li>Basic Driver Training Manual.</li>
|
||||
<li>Theory session and discussion.</li>
|
||||
<li>Spend the afternoon on the track learning the basic practices of 4X4 driving.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-lg-5">
|
||||
<div class="image rmt-45">
|
||||
<img src="assets/images/shop/product-details.jpg" alt="Product Details">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="information">
|
||||
<!-- <p>Circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses</p> -->
|
||||
<ul class="list-style-two my-35">
|
||||
<li>Coffee and Welcome: Start the day with a warm cup of coffee, meet the instructors, and get an overview of the training schedule.</li>
|
||||
<li>Theory Session: Learn the fundamentals of 4x4 vehicle mechanics, terrain types, recovery equipment, and off-road safety.</li>
|
||||
<li>Practical Demonstrations: Observe demonstrations of essential techniques like gear selection, tire pressure adjustment, and recovery setups.</li>
|
||||
<li>Lunch Break: Bring along a packed lunch or something to braai. Fires will be provided.</li>
|
||||
<li>Track Driving and Practical Training: Put theory into action with hands-on driving exercises on a custom-designed off-road track.</li>
|
||||
<li>Debrief and Certificates: Wrap up the day with a recap of key lessons, feedback from instructors, and certificates of completion.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- <div class="tab-pane fade mb-20" id="reviews">
|
||||
<h5>2 Reviews</h5>
|
||||
<div class="comments my-30">
|
||||
<div class="comment-body" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="author-thumb">
|
||||
<img src="assets/images/blog/comment-author1.jpg" alt="Author">
|
||||
</div>
|
||||
<div class="content">
|
||||
<h6>Lonnie B. Horwitz</h6>
|
||||
<div class="ratting">
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star-half-alt"></i>
|
||||
</div>
|
||||
<span class="time">Venice, Rome and Milan – 9 Days 8 Nights</span>
|
||||
<p>Tours and travels play a crucial role in enriching lives by offering unique experiences, cultural exchanges, and the joy of exploration.</p>
|
||||
<a class="read-more" href="#">Reply <i class="far fa-angle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="comment-body" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="author-thumb">
|
||||
<img src="assets/images/blog/comment-author3.jpg" alt="Author">
|
||||
</div>
|
||||
<div class="content">
|
||||
<h6>Jaime B. Wilson</h6>
|
||||
<div class="ratting">
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star-half-alt"></i>
|
||||
</div>
|
||||
<span class="time">Venice, Rome and Milan – 9 Days 8 Nights</span>
|
||||
<p>Tours and travels play a crucial role in enriching lives by offering unique experiences, cultural exchanges, and the joy of exploration.</p>
|
||||
<a class="read-more" href="#">Reply <i class="far fa-angle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- <h5>Add A Reviews</h5>
|
||||
<form id="comment-form" class="comment-form bgc-lighter z-1 rel mt-30" name="review-form" action="#" method="post" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="row gap-20">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<input type="text" id="full-name" name="full-name" class="form-control" placeholder="Name" value="" required="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<input type="email" id="email-address" name="email" class="form-control" placeholder="Email" value="" required="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="form-group">
|
||||
<textarea name="message" id="message" class="form-control" rows="5" placeholder="Comments" required=""></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="form-group mb-0">
|
||||
<button type="submit" class="theme-btn bgc-secondary style-two">
|
||||
<span data-hover="Submit reviews">Submit review</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form> -->
|
||||
<!-- </div> -->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Product Details End -->
|
||||
|
||||
|
||||
<!-- Shop Details Area start -->
|
||||
<section class="shop-details-page pt-80 pb-100 rel z-1">
|
||||
<div class="container">
|
||||
<div class="section-title text-center mb-40">
|
||||
<h2>Other Courses</h2>
|
||||
</div>
|
||||
<div class="product-slider">
|
||||
<div class="product-item" data-aos="flip-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image">
|
||||
<img src="assets/images/shop/product1.png" alt="Product">
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ratting">
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star-half-alt"></i>
|
||||
</div>
|
||||
<h6><a href="product-details.html">Airport Travel Suitcases</a></h6>
|
||||
<span class="price">$188.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="product-item" data-aos="flip-left" data-aos-duration="1500" data-aos-offset="50" data-aos-delay="50">
|
||||
<div class="image">
|
||||
<img src="assets/images/shop/product2.png" alt="Product">
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ratting">
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star-half-alt"></i>
|
||||
</div>
|
||||
<h6><a href="product-details.html">Travel Great blue hat</a></h6>
|
||||
<span class="price">$188.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="product-item" data-aos="flip-left" data-aos-duration="1500" data-aos-offset="50" data-aos-delay="100">
|
||||
<div class="image">
|
||||
<img src="assets/images/shop/product3.png" alt="Product">
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ratting">
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star-half-alt"></i>
|
||||
</div>
|
||||
<h6><a href="product-details.html">Waistband and Mesh Fashion</a></h6>
|
||||
<span class="price">$188.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="product-item" data-aos="flip-left" data-aos-duration="1500" data-aos-offset="50" data-aos-delay="150">
|
||||
<div class="image">
|
||||
<img src="assets/images/shop/product4.png" alt="Product">
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ratting">
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star-half-alt"></i>
|
||||
</div>
|
||||
<h6><a href="product-details.html">Sandals for Casual Techies</a></h6>
|
||||
<span class="price">$188.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="product-item" data-aos="flip-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image">
|
||||
<img src="assets/images/shop/product5.png" alt="Product">
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ratting">
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star-half-alt"></i>
|
||||
</div>
|
||||
<h6><a href="product-details.html">Children With Jute Soles</a></h6>
|
||||
<span class="price">$188.00</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Shop Details Area end -->
|
||||
|
||||
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php') ?>
|
||||
389
src/pages/bookings/driver_training.php
Normal file
389
src/pages/bookings/driver_training.php
Normal file
@@ -0,0 +1,389 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
checkUserSession();
|
||||
|
||||
// SQL query to fetch dates for driver training
|
||||
$stmt = $conn->prepare("SELECT course_id, date
|
||||
FROM courses
|
||||
WHERE course_type = ?
|
||||
AND date >= CURDATE()");
|
||||
$course_type = 'driver_training';
|
||||
$stmt->bind_param("s", $course_type);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$page_id = 'driver_training';
|
||||
|
||||
?>
|
||||
|
||||
<style>
|
||||
.form-group {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
select {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style><?php
|
||||
$pageTitle = 'Driver Training';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once($rootPath . '/components/banner.php');
|
||||
?>
|
||||
|
||||
<!-- Product Details Start -->
|
||||
<section class="product-details pt-100">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="product-details-images rmb-55" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="tab-content preview-images">
|
||||
<div class="tab-pane fade preview-item active show" id="preview1">
|
||||
<img src="assets/images/drivertraining/01.png" alt="Perview">
|
||||
</div>
|
||||
<div class="tab-pane fade preview-item" id="preview2">
|
||||
<img src="assets/images/drivertraining/07.jpg" alt="Perview">
|
||||
</div>
|
||||
<div class="tab-pane fade preview-item" id="preview3">
|
||||
<img src="assets/images/drivertraining/02.png" alt="Perview">
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav thumb-images rmb-20">
|
||||
<a href="#preview1" data-bs-toggle="tab" class="thumb-item active show">
|
||||
<img src="assets/images/drivertraining/01.png" alt="Thumb">
|
||||
</a>
|
||||
<a href="#preview2" data-bs-toggle="tab" class="thumb-item">
|
||||
<img src="assets/images/drivertraining/07.jpg" alt="Thumb">
|
||||
</a>
|
||||
<a href="#preview3" data-bs-toggle="tab" class="thumb-item">
|
||||
<img src="assets/images/drivertraining/02.png" alt="Thumb">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="product-details-content" data-aos="fade-right" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="section-title">
|
||||
<h2>4X4 Driver Training</h2>
|
||||
</div>
|
||||
<!-- <div class="ratting mb-15">
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star-half-alt"></i>
|
||||
<span>(5.8k+ reviews)</span>
|
||||
</div> -->
|
||||
<span class="price mb-5">R <?= getPrice('driver_training', 'member'); ?>/member</span>
|
||||
<span class="price mb-25">R <?= getPrice('driver_training', 'nonmember'); ?>/non-members</span>
|
||||
<p>Our 4x4 Basic Training Course equips you with the essential skills and knowledge to confidently tackle off-road terrains. Learn vehicle mechanics, driving techniques, obstacle navigation, and recovery methods while promoting safe and responsible off-road practices. Perfect for beginners and new 4x4 owners!</p>
|
||||
<hr class="mt-40">
|
||||
<div class="blog-sidebar tour-sidebar">
|
||||
<div class="widget widget-booking" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<form action="process_course_booking" method="POST">
|
||||
<ul class="tickets clearfix">
|
||||
<li>
|
||||
Select Date
|
||||
<select name="course_id" id="course_id" required>
|
||||
<?php
|
||||
if ($result && $result->num_rows > 0) {
|
||||
// Output each course as an option
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$course_id = htmlspecialchars($row['course_id']); // Escape output for security
|
||||
$date = htmlspecialchars($row['date']); // Escape output for security
|
||||
echo "<option value='$course_id'>$date</option>";
|
||||
}
|
||||
} else {
|
||||
echo "<option value='' disabled>No dates available</option>";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
|
||||
</li>
|
||||
<?php
|
||||
if ($is_member || $pending_member) {
|
||||
echo '
|
||||
<li>
|
||||
Additional Members <span class="price"></span>
|
||||
<select name="members" id="members">
|
||||
<option value="0" selected>00</option>
|
||||
<option value="1">01</option>
|
||||
<option value="2">02</option>
|
||||
<option value="3">03</option>
|
||||
</select>
|
||||
</li>
|
||||
';
|
||||
} ?>
|
||||
|
||||
<li>
|
||||
Additional Non-Members <span class="price"></span>
|
||||
<select name="non-members" id="non-members">
|
||||
<option value="0" selected>00</option>
|
||||
<option value="1">01</option>
|
||||
<option value="2">02</option>
|
||||
<option value="3">03</option>
|
||||
</select>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<hr class="mb-25">
|
||||
|
||||
<h6>Total: <span id="booking_total" class="price">-</span></h6>
|
||||
<div style="margin: 20px 0;">
|
||||
<div id="indemnityBox" style="border: 1px solid #ccc; padding: 10px; height: 150px; overflow-y: scroll; background: #f9f9f9; font-size: 12px;">
|
||||
<p><strong>INDEMNITY AND WAIVER</strong></p>
|
||||
<p>1. I agree to abide by the Code of Conduct as listed below, as well as any reasonable instructions given by any Member of the Committee of the Club, or any person appointed by the Club to organise or control any event (Club Officer).</p>
|
||||
<p>2. I acknowledge that driving the off-road track is inherently dangerous, and that I am fully aware of the dangers thereof. I warrant that I will make all members of my party aware of such dangers prior to driving the track.</p>
|
||||
<p>3. While I, or any member of my party, enjoy the facilities at Base 4 including overnight camping, picnicking, driving the track, using the swimming pool facility or activity or any other activity while at Base 4, I agree that under no circumstances shall the Club be liable for any loss or damage of any kind whatsoever (including consequential loss) which I or any of my party may suffer, regardless of how such loss or damage may have been caused or sustained, and whether or not as a result of the negligence or breach of contract (whether fundamental or otherwise) or other wrongful act of the Club, or any Club Officer, or any of the Club’s agents or contractors, and I hereby indemnify and hold harmless the Club and any Club Officer against all such loss or damage.</p>
|
||||
<p>4. The expression, ‘member of my party’, means all persons who accompany me or attending any event at my specific invitation, request or suggestion, and includes without limitation, members of family, guests and invitees.</p>
|
||||
<p>5. I understand that I am responsible for ensuring my vehicle and equipment and that all members of my party have adequate health and medical insurance to cover any and all likely occurrences.</p>
|
||||
<p>6. This indemnity is irrevocable and shall apply to me and the members of my party for any Club events in which I may participate or attend.</p>
|
||||
<p><strong>BASE 4 CODE OF CONDUCT</strong></p>
|
||||
<p>1. No motorbikes or quadbikes.</p>
|
||||
<p>2. No loud music (unless authorised by the Committee or its representatives).</p>
|
||||
<p>3. Dogs to be controlled by their owners who take full responsibility for the animal’s behaviour.</p>
|
||||
<p>4. No dogs belonging to non-members are allowed at Base 4 unless with the express permission of the Committee.</p>
|
||||
<p>5. No person in the rear of open vehicles when driving on obstacles.</p>
|
||||
<p>6. When driving the obstacles stay on the tracks.</p>
|
||||
<p>7. Engage 4WD when driving the obstacles to minimise wear and damage to the track.</p>
|
||||
<p>8. No alcohol to be consumed while driving the track.</p>
|
||||
<p>9. No littering (please pick up cigarette butts etc.)</p>
|
||||
<p>10. All rubbish is to be taken away with you when leaving. Dustbins and refuse collection is not provided.</p>
|
||||
<p>11. Use water sparingly. Please bring your own water and a little extra for the Club.</p>
|
||||
<p>I am a member of the Four Wheel Drive Club of Southern Africa and I will strive to uphold these Codes.</p>
|
||||
</div>
|
||||
<div style="margin-top: 10px;">
|
||||
<input type="checkbox" id="agreeCheckbox" name="agree" disabled required>
|
||||
<label for="agreeCheckbox" id="agreeLabel" style="color: #888;">I have read and agree to the indemnity terms</label>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
|
||||
<?php
|
||||
$button_text = "Book Now";
|
||||
$button_disabled = "";
|
||||
if (!$result || $result->num_rows == 0) {
|
||||
$button_text = "No booking dates available";
|
||||
$button_disabled = "disabled";
|
||||
}
|
||||
?>
|
||||
<button type="submit" class="theme-btn style-two w-100 mt-15 mb-5" <?php echo $button_disabled; ?>>
|
||||
<span data-hover="<?php echo $button_text; ?>"><?php echo $button_text; ?></span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</button>
|
||||
<div class="text-center">
|
||||
<a href="contact">Need some help?</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- <hr class="mb-45"> -->
|
||||
<!-- <a href="#" class="wishlist"><i class="far fa-heart"></i> Add to Wishlist</a> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="nav nav product-tab mt-70 mb-30" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<li><a href="#details" data-bs-toggle="tab" class="active show">Course Overview<i class="far fa-arrow-right"></i></a></li>
|
||||
<li><a href="#information" data-bs-toggle="tab">What to Expect<i class="far fa-arrow-right"></i></a></li>
|
||||
<li><a href="#reviews" data-bs-toggle="tab"> Reviews <i class="far fa-arrow-right"></i></a></li>
|
||||
</ul>
|
||||
<div class="tab-content" data-aos="fade-up" data-aos-delay="50" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="tab-pane fade active show" id="details">
|
||||
<p>A 4x4 Basic Training Course is designed to equip participants with the foundational knowledge and practical skills necessary for safe and effective off-road driving. This course covers essential topics such as understanding the mechanics of 4x4 vehicles, selecting the appropriate gear, and engaging various drive modes to tackle different terrains. Participants will learn how to navigate obstacles like mud, sand, and rocky paths while maintaining vehicle control and ensuring safety for themselves and their passengers. The training also includes instruction on tire pressure management, vehicle recovery techniques, and the use of essential recovery equipment like tow straps and shackles.</p>
|
||||
<p>In addition to practical driving exercises, the course emphasizes responsible off-road driving practices, including respecting the environment and adhering to trail etiquette. Whether you're a novice driver looking to explore off-road adventures or a new 4x4 owner seeking confidence behind the wheel, this training provides a comprehensive introduction to the world of off-roading. By the end of the course, participants will feel prepared to tackle basic off-road challenges with skill and assurance, making their next 4x4 outing a safe and enjoyable experience.</p>
|
||||
<div class="row gap-50 pt-25 pb-20 align-items-center">
|
||||
<div class="col-lg-7 pt-15">
|
||||
<h5>What this course includes</h5>
|
||||
<ul class="list-style-two mt-25">
|
||||
<li>Basic Driver Training Manual.</li>
|
||||
<li>Theory session and discussion.</li>
|
||||
<li>Spend the afternoon on the track learning the basic practices of 4X4 driving.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-lg-5">
|
||||
<div class="image rmt-45">
|
||||
<img src="assets/images/drivertraining/dt04.jpg" alt="Product Details">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="information">
|
||||
<!-- <p>Circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses</p> -->
|
||||
<ul class="list-style-two my-35">
|
||||
<li>Coffee and Welcome: Start the day with a warm cup of coffee, meet the instructors, and get an overview of the training schedule.</li>
|
||||
<li>Theory Session: Learn the fundamentals of 4x4 vehicle mechanics, terrain types, recovery equipment, and off-road safety.</li>
|
||||
<li>Practical Demonstrations: Observe demonstrations of essential techniques like gear selection, tire pressure adjustment, and recovery setups.</li>
|
||||
<li>Lunch Break: Bring along a packed lunch or something to braai. Fires will be provided.</li>
|
||||
<li>Track Driving and Practical Training: Put theory into action with hands-on driving exercises on a custom-designed off-road track.</li>
|
||||
<li>Debrief and Certificates: Wrap up the day with a recap of key lessons, feedback from instructors, and certificates of completion.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-pane fade mb-20" id="reviews">
|
||||
<?php include_once('review_box.php'); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Product Details End -->
|
||||
|
||||
|
||||
<!-- Shop Details Area start -->
|
||||
<!-- <section class="shop-details-page pt-80 pb-100 rel z-1">
|
||||
<div class="container">
|
||||
<div class="section-title text-center mb-40">
|
||||
<h2>Other Courses</h2>
|
||||
</div>
|
||||
<div class="product-slider">
|
||||
<div class="product-item" data-aos="flip-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image">
|
||||
<img src="assets/images/shop/product1.png" alt="Product">
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ratting">
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star-half-alt"></i>
|
||||
</div>
|
||||
<h6><a href="product-details.html">Airport Travel Suitcases</a></h6>
|
||||
<span class="price">$188.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="product-item" data-aos="flip-left" data-aos-duration="1500" data-aos-offset="50" data-aos-delay="50">
|
||||
<div class="image">
|
||||
<img src="assets/images/shop/product2.png" alt="Product">
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ratting">
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star-half-alt"></i>
|
||||
</div>
|
||||
<h6><a href="product-details.html">Travel Great blue hat</a></h6>
|
||||
<span class="price">$188.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="product-item" data-aos="flip-left" data-aos-duration="1500" data-aos-offset="50" data-aos-delay="100">
|
||||
<div class="image">
|
||||
<img src="assets/images/shop/product3.png" alt="Product">
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ratting">
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star-half-alt"></i>
|
||||
</div>
|
||||
<h6><a href="product-details.html">Waistband and Mesh Fashion</a></h6>
|
||||
<span class="price">$188.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="product-item" data-aos="flip-left" data-aos-duration="1500" data-aos-offset="50" data-aos-delay="150">
|
||||
<div class="image">
|
||||
<img src="assets/images/shop/product4.png" alt="Product">
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ratting">
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star-half-alt"></i>
|
||||
</div>
|
||||
<h6><a href="product-details.html">Sandals for Casual Techies</a></h6>
|
||||
<span class="price">$188.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="product-item" data-aos="flip-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image">
|
||||
<img src="assets/images/shop/product5.png" alt="Product">
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ratting">
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star-half-alt"></i>
|
||||
</div>
|
||||
<h6><a href="product-details.html">Children With Jute Soles</a></h6>
|
||||
<span class="price">$188.00</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section> -->
|
||||
<!-- Shop Details Area end -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||
<script>
|
||||
const indemnityBox = document.getElementById('indemnityBox');
|
||||
const agreeCheckbox = document.getElementById('agreeCheckbox');
|
||||
const bookingForm = document.querySelector('form');
|
||||
|
||||
indemnityBox.addEventListener('scroll', function() {
|
||||
const scrollTop = indemnityBox.scrollTop;
|
||||
const scrollHeight = indemnityBox.scrollHeight;
|
||||
const offsetHeight = indemnityBox.offsetHeight;
|
||||
|
||||
// Enable checkbox when scrolled to bottom
|
||||
if (scrollTop + offsetHeight >= scrollHeight - 1) {
|
||||
agreeCheckbox.disabled = false;
|
||||
document.getElementById('agreeLabel').style.color = "#000"; // optional: make label active
|
||||
}
|
||||
});
|
||||
|
||||
bookingForm.addEventListener('submit', function(e) {
|
||||
if (agreeCheckbox.disabled || !agreeCheckbox.checked) {
|
||||
alert('Please read and agree to the indemnity terms before booking.');
|
||||
e.preventDefault(); // stop form submission
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Function to calculate booking total
|
||||
function calculateTotal() {
|
||||
// Get selected values from the form
|
||||
var members = parseInt($('#members').val()) || 0; // Default to 1 vehicle if not selected
|
||||
var nonmembers = parseInt($('#non-members').val()) || 0; // Default to 1 adult if not selected
|
||||
|
||||
// Fetch PHP variables
|
||||
var isMember = <?php echo $is_member ? 'true' : 'false'; ?>;
|
||||
var pendingMember = <?php echo $pending_member ? 'true' : 'false'; ?>;
|
||||
var cost_members = <?= getPrice('driver_training', 'member'); ?>;
|
||||
var cost_nonmembers = <?= getPrice('driver_training', 'nonmember'); ?>;
|
||||
|
||||
// Calculate the total cost based on membership
|
||||
var total = 0;
|
||||
|
||||
// Calculate cost for members
|
||||
if (isMember || pendingMember) {
|
||||
total = (cost_members) + (members * cost_members) + (nonmembers * cost_nonmembers);
|
||||
} else {
|
||||
// Calculate cost for non-members
|
||||
total = (cost_nonmembers) + (members * cost_members) + (nonmembers * cost_nonmembers);
|
||||
}
|
||||
|
||||
// Update total price in the DOM
|
||||
$('#booking_total').text('R ' + total.toFixed(2));
|
||||
|
||||
}
|
||||
|
||||
// Event listeners to trigger recalculation when any form field changes
|
||||
$('#members, #non-members').on('change', function() {
|
||||
calculateTotal();
|
||||
});
|
||||
|
||||
// Initial calculation on page load
|
||||
calculateTotal();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php') ?>
|
||||
676
src/pages/bookings/trip-details.php
Normal file
676
src/pages/bookings/trip-details.php
Normal file
@@ -0,0 +1,676 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once(dirname(dirname(dirname(__DIR__))) . '/header.php');
|
||||
checkUserSession();
|
||||
|
||||
if (!isset($_GET['token']) || empty($_GET['token'])) {
|
||||
die("Invalid request.");
|
||||
}
|
||||
$token = $_GET['token'];
|
||||
// echo $token;
|
||||
|
||||
// Sanitize the trip_id to prevent SQL injection
|
||||
$trip_id = intval(decryptData($token, $salt)); // Ensures $trip_id is treated as an integer
|
||||
|
||||
// Prepare the SQL query
|
||||
$sql = "SELECT trip_id, trip_name, location, short_description, long_description, start_date, end_date,
|
||||
vehicle_capacity, cost_members, cost_nonmembers, places_booked, booking_fee, cost_pensioner, cost_pensioner_member
|
||||
FROM trips
|
||||
WHERE trip_id = ?";
|
||||
|
||||
// Use prepared statements for added security
|
||||
$stmt = $conn->prepare($sql);
|
||||
|
||||
if ($stmt) {
|
||||
// Bind the parameter
|
||||
$stmt->bind_param("i", $trip_id);
|
||||
|
||||
// Execute the query
|
||||
$stmt->execute();
|
||||
|
||||
// Get the result
|
||||
$result = $stmt->get_result();
|
||||
|
||||
// Check if the trip exists
|
||||
if ($result->num_rows > 0) {
|
||||
// Fetch the data
|
||||
$row = $result->fetch_assoc();
|
||||
|
||||
// Populate the variables
|
||||
$trip_id = $row['trip_id'];
|
||||
$trip_name = $row['trip_name'];
|
||||
$location = $row['location'];
|
||||
$short_description = $row['short_description'];
|
||||
$long_description = $row['long_description'];
|
||||
$start_date = $row['start_date'];
|
||||
$end_date = $row['end_date'];
|
||||
$capacity = $row['vehicle_capacity'];
|
||||
$cost_members = $row['cost_members'];
|
||||
$cost_nonmembers = $row['cost_nonmembers'];
|
||||
$cost_pensioner = $row['cost_pensioner'];
|
||||
$cost_pensioner_member = $row['cost_pensioner_member'];
|
||||
$member_discount = $cost_nonmembers - $cost_members;
|
||||
$member_discount_pensioner = $cost_pensioner - $cost_pensioner_member;
|
||||
$places_booked = $row['places_booked'];
|
||||
$booking_fee = $row['booking_fee'];
|
||||
$remaining_places = getAvailableSpaces($trip_id);
|
||||
|
||||
// Determine the badge text based on the status
|
||||
$badge_text = ($remaining_places > 0) ? $remaining_places . ' PLACES LEFT!!' : 'FULLY BOOKED';
|
||||
|
||||
// Convert newlines into <br> tags to preserve line breaks
|
||||
$formatted_description = nl2br($long_description);
|
||||
|
||||
// Wrap the text in <p> tags at the beginning and end
|
||||
$formatted_description = '<p>' . $formatted_description . '</p>';
|
||||
} else {
|
||||
echo "No trip found with ID: $trip_id";
|
||||
}
|
||||
|
||||
// Close the statement
|
||||
$stmt->close();
|
||||
} else {
|
||||
echo "Error preparing the statement: " . $conn->error;
|
||||
}
|
||||
|
||||
// Always close the database connection when done
|
||||
$conn->close();
|
||||
|
||||
?>
|
||||
<style>
|
||||
.gallery-item {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
padding-top: 66.66%;
|
||||
border-radius: 10px;
|
||||
/* This is equivalent to a 3:2 aspect ratio (height/width * 100) */
|
||||
}
|
||||
|
||||
.gallery-item img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
}
|
||||
|
||||
.gallery-item-portrait {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
padding-top: 136%;
|
||||
/* This is equivalent to a 3:2 aspect ratio (height/width * 100) */
|
||||
}
|
||||
|
||||
.allery-item-portrait img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
}
|
||||
|
||||
.price-display {
|
||||
display: block;
|
||||
/* Ensures each price display is on a new line */
|
||||
margin-bottom: 8px;
|
||||
/* Adds space between the two price blocks */
|
||||
}
|
||||
|
||||
.price-wrapper {
|
||||
display: inline-flex;
|
||||
align-items: baseline;
|
||||
/* Align the price and '/per person' on the same baseline */
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 3rem;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.per-person {
|
||||
font-size: 1rem;
|
||||
margin-left: 8px;
|
||||
color: #777;
|
||||
/* Optional: makes '/per person' text softer */
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.non-member .price {
|
||||
font-size: 1.5rem;
|
||||
/* Smaller price for non-members */
|
||||
color: rgb(86, 86, 86);
|
||||
/* Optional: makes non-member price stand out */
|
||||
}
|
||||
</style>
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
include_once(dirname(dirname(dirname(__DIR__))) . '/header.php');
|
||||
?>
|
||||
|
||||
<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 */
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<section class=" pt-50 pb-35 rel z-1 ">
|
||||
|
||||
<div class="container">
|
||||
<div class="banner-inner text-black mb-50">
|
||||
<h2 class="page-title mb-10" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50"><?php echo $trip_name; ?></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">4WDCSA Trips</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Tour Gallery start -->
|
||||
<div class="tour-gallery">
|
||||
<div class="container-fluid">
|
||||
<div class="row gap-10 justify-content-center rel">
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="gallery-item image-landscape">
|
||||
<img src="assets/images/trips/<?php echo $trip_id; ?>_01.jpg" alt="">
|
||||
</div>
|
||||
<div class="gallery-item image-landscape">
|
||||
<img src="assets/images/trips/<?php echo $trip_id; ?>_02.jpg" alt="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="gallery-item gallery-item-portrait image-portrait">
|
||||
<img src="assets/images/trips/<?php echo $trip_id; ?>_03.jpg" alt="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="gallery-item image-landscape">
|
||||
<img src="assets/images/trips/<?php echo $trip_id; ?>_04.jpg" alt="">
|
||||
</div>
|
||||
<div class="gallery-item image-landscape">
|
||||
<img src="assets/images/trips/<?php echo $trip_id; ?>_05.jpg" alt="">
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="col-lg-12">
|
||||
<div class="gallery-more-btn">
|
||||
<a href="contact.html" class="theme-btn style-two bgc-secondary">
|
||||
<span data-hover="See All Photos">See All Photos</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tour Gallery End -->
|
||||
|
||||
|
||||
<!-- Tour Header Area start -->
|
||||
<section class="tour-header-area pt-70 rel z-1">
|
||||
<div class="container">
|
||||
<div class="row justify-content-between">
|
||||
<div class="col-xl-6 col-lg-7">
|
||||
<div class="tour-header-content mb-15" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<span class="location d-inline-block mb-10"><i class="fal fa-map-marker-alt"></i> <?php echo $location; ?></span>
|
||||
<div class="section-title pb-5">
|
||||
<h2><?php echo $trip_name; ?></h2>
|
||||
</div>
|
||||
<!-- <div class="ratting">
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star-half-alt"></i>
|
||||
</div> -->
|
||||
|
||||
</div>
|
||||
<span class="subtitle mb-15"><?php echo $badge_text; ?></span>
|
||||
</div>
|
||||
<!-- <div class="col-xl-4 col-lg-5 text-lg-end" data-aos="fade-right" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="tour-header-social mb-10">
|
||||
<a href="#"><i class="far fa-share-alt"></i>Share tours</a>
|
||||
<a href="#"><i class="fas fa-heart bgc-secondary"></i>Wish list</a>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<hr class="mt-50 mb-70">
|
||||
</div>
|
||||
</section>
|
||||
<!-- Tour Header Area end -->
|
||||
|
||||
|
||||
<!-- Tour Details Area start -->
|
||||
<section class="tour-details-page pb-100">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<div class="tour-details-content">
|
||||
<h3>Trip Info</h3>
|
||||
<p><?php echo $formatted_description; ?></p>
|
||||
<div class="price-display">
|
||||
<div class="price-wrapper">
|
||||
<h2 class="price">R <?php echo $cost_members; ?></h2><span class="per-person">/per member</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="price-display non-member">
|
||||
<div class="price-wrapper">
|
||||
<h2 class="price">R <?php echo $cost_nonmembers; ?></h2><span class="per-person">/per non-member</span>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="price-display non-member">
|
||||
<div class="price-wrapper">
|
||||
<h2 class="price">R <?php echo $booking_fee; ?></h2><span class="per-person">/club fee per vehicle</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="row pb-55">
|
||||
<div class="col-md-6">
|
||||
<div class="tour-include-exclude mt-30">
|
||||
<h5>Included and Excluded</h5>
|
||||
<ul class="list-style-one check mt-25">
|
||||
<li><i class="far fa-check"></i> Pick and Drop Services</li>
|
||||
<li><i class="far fa-check"></i> 1 Meal Per Day</li>
|
||||
<li><i class="far fa-check"></i> Cruise Dinner & Music Event</li>
|
||||
<li><i class="far fa-check"></i> Visit 7 Best Places in the City</li>
|
||||
<li><i class="far fa-check"></i> Bottled Water on Buses</li>
|
||||
<li><i class="far fa-check"></i> Transportation Luxury Tour Bus</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="tour-include-exclude mt-30">
|
||||
<h5>Excluded</h5>
|
||||
<ul class="list-style-one mt-25">
|
||||
<li><i class="far fa-times"></i> Gratuities</li>
|
||||
<li><i class="far fa-times"></i> Hotel pickup and drop-off</li>
|
||||
<li><i class="far fa-times"></i> Lunch, Food & Drinks</li>
|
||||
<li><i class="far fa-times"></i> Optional upgrade to a glass</li>
|
||||
<li><i class="far fa-times"></i> Additional Services</li>
|
||||
<li><i class="far fa-times"></i> Insurance</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
<!-- <h3>Activities</h3>
|
||||
<div class="tour-activities mt-30 mb-45">
|
||||
<div class="tour-activity-item">
|
||||
<i class="flaticon-hiking"></i>
|
||||
<b>Hiking</b>
|
||||
</div>
|
||||
<div class="tour-activity-item">
|
||||
<i class="flaticon-fishing"></i>
|
||||
<b>Fishing</b>
|
||||
</div>
|
||||
<div class="tour-activity-item">
|
||||
<i class="flaticon-man"></i>
|
||||
<b>Kayak shooting</b>
|
||||
</div>
|
||||
<div class="tour-activity-item">
|
||||
<i class="flaticon-kayak-1"></i>
|
||||
<b>Kayak</b>
|
||||
</div>
|
||||
<div class="tour-activity-item">
|
||||
<i class="flaticon-bonfire"></i>
|
||||
<b>Campfire</b>
|
||||
</div>
|
||||
<div class="tour-activity-item">
|
||||
<i class="flaticon-flashlight"></i>
|
||||
<b>Night Exploring</b>
|
||||
</div>
|
||||
<div class="tour-activity-item">
|
||||
<i class="flaticon-cycling"></i>
|
||||
<b>Biking</b>
|
||||
</div>
|
||||
<div class="tour-activity-item">
|
||||
<i class="flaticon-meditation"></i>
|
||||
<b>Yoga</b>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- <h3>Itinerary</h3>
|
||||
<div class="accordion-two mt-25 mb-60" id="faq-accordion-two">
|
||||
<div class="accordion-item">
|
||||
<h5 class="accordion-header">
|
||||
<button class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#collapseTwoOne">
|
||||
Day 1 - Arrive at campground
|
||||
</button>
|
||||
</h5>
|
||||
<div id="collapseTwoOne" class="accordion-collapse collapse" data-bs-parent="#faq-accordion-two">
|
||||
<div class="accordion-body">
|
||||
<p>To take a trivial example which undertakes laborious physical exercise except to obtain some advantage pleasure annoying consequences</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="accordion-item">
|
||||
<h5 class="accordion-header">
|
||||
<button class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#collapseTwoTwo">
|
||||
Day 2 - Wake up early and embark on a day hike
|
||||
</button>
|
||||
</h5>
|
||||
<div id="collapseTwoTwo" class="accordion-collapse collapse" data-bs-parent="#faq-accordion-two">
|
||||
<div class="accordion-body">
|
||||
<p>The early start ensures you can fully immerse yourself in the tranquility of nature before the world fully awakens. As the morning light filters through the trees, you'll experience the crisp, fresh air and the peaceful sounds of the forest. The trail ahead offers both a physical challenge promise of breathtaking.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="accordion-item">
|
||||
<h5 class="accordion-header">
|
||||
<button class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#collapseTwoThree">
|
||||
Day 3 - Join a guided ranger-led nature walk
|
||||
</button>
|
||||
</h5>
|
||||
<div id="collapseTwoThree" class="accordion-collapse collapse" data-bs-parent="#faq-accordion-two">
|
||||
<div class="accordion-body">
|
||||
<p>To take a trivial example which undertakes laborious physical exercise except to obtain some advantage pleasure annoying consequences</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="accordion-item">
|
||||
<h5 class="accordion-header">
|
||||
<button class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#collapseTwoFour">
|
||||
Day 4 - Take a break from hiking
|
||||
</button>
|
||||
</h5>
|
||||
<div id="collapseTwoFour" class="accordion-collapse collapse" data-bs-parent="#faq-accordion-two">
|
||||
<div class="accordion-body">
|
||||
<p>To take a trivial example which undertakes laborious physical exercise except to obtain some advantage pleasure annoying consequences</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="accordion-item">
|
||||
<h5 class="accordion-header">
|
||||
<button class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#collapseTwoFive">
|
||||
Day 5 - Pack a lunch and embark on a longer hike
|
||||
</button>
|
||||
</h5>
|
||||
<div id="collapseTwoFive" class="accordion-collapse collapse" data-bs-parent="#faq-accordion-two">
|
||||
<div class="accordion-body">
|
||||
<p>To take a trivial example which undertakes laborious physical exercise except to obtain some advantage pleasure annoying consequences</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- <h3>Maps</h3> -->
|
||||
<div class="tour-map mt-30 mb-50">
|
||||
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d13894.816708766162!2d29.256367272652284!3d-29.46664742147583!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x1ef37aefd73de6bd%3A0xf35ffec07e766685!2sDrakensberg!5e0!3m2!1sen!2sza!4v1750666087092!5m2!1sen!2sza" style="border:0; width: 100%;" allowfullscreen="" loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-8 col-sm-10 rmt-75">
|
||||
<div class="blog-sidebar tour-sidebar">
|
||||
<div class="widget widget-booking" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<h5 class="widget-title">Book your Trip</h5>
|
||||
<form action="process_trip_booking" method="POST">
|
||||
<input type="hidden" name="trip_id" id="trip_id" value="<?php echo $trip_id; ?>">
|
||||
<ul class="radio-filter pt-5">
|
||||
<li>
|
||||
<label for="add-extra1">Start Date <span><?php echo $start_date; ?></span></label>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="radio-filter pt-5">
|
||||
<li>
|
||||
<label for="add-extra1">End Date <span><?php echo $end_date; ?></span></label>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr class="mb-25">
|
||||
<ul class="tickets clearfix">
|
||||
<li>
|
||||
Vehicles <span class="price"></span>
|
||||
<select name="vehicles" id="vehicles">
|
||||
<option value="1" selected>01</option>
|
||||
<option value="2">02</option>
|
||||
<option value="3">03</option>
|
||||
<option value="4">04</option>
|
||||
</select>
|
||||
</li>
|
||||
<li>
|
||||
Adults <span class="price"></span>
|
||||
<select name="adults" id="adults">
|
||||
<option value="0">00</option>
|
||||
<option value="1" selected>01</option>
|
||||
<option value="2">02</option>
|
||||
<option value="3">03</option>
|
||||
<option value="4">04</option>
|
||||
</select>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Children <span class="price"></span>
|
||||
<select name="children" id="children">
|
||||
<option value="0" selected>00</option>
|
||||
<option value="1">01</option>
|
||||
<option value="2">02</option>
|
||||
<option value="3">03</option>
|
||||
</select>
|
||||
</li>
|
||||
<li>
|
||||
Pensioners <span class="price"></span>
|
||||
<select name="pensioners" id="pensioners">
|
||||
<option value="0" selected>00</option>
|
||||
<option value="1">01</option>
|
||||
<option value="2">02</option>
|
||||
<option value="3">03</option>
|
||||
</select>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- <hr class="mb-25"> -->
|
||||
<!-- <h6>Extras:</h6> -->
|
||||
<!-- <ul class="radio-filter pt-5">
|
||||
<li>
|
||||
<input class="form-check-input" type="checkbox" name="AddExtra" id="add-extra1" value="50" style="background:#fff;">
|
||||
<label for="add-extra1">4WDCSA Pensioner Discount </label>
|
||||
</li>
|
||||
</ul> -->
|
||||
|
||||
<hr>
|
||||
|
||||
<?php if ($is_member) : ?>
|
||||
<div id="discount_section">
|
||||
<h6>Discount:</h6>
|
||||
<ul class="radio-filter pt-5">
|
||||
<li>
|
||||
<label for="add-extra1">4WDCSA Member Discount <span id="discount_amount">R 0,00</span></label>
|
||||
</li>
|
||||
</ul>
|
||||
<hr>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
<ul class="radio-filter pt-5">
|
||||
<li>
|
||||
<label for="add-extra1">4WDCSA Booking Fee <span id="booking_fee">R <?php echo $booking_fee; ?></span></label>
|
||||
</li>
|
||||
</ul>
|
||||
<div style="margin: 20px 0;">
|
||||
<div id="indemnityBox" style="border: 1px solid #ccc; padding: 10px; height: 150px; overflow-y: scroll; background: #f9f9f9; font-size: 12px;">
|
||||
<p><strong>INDEMNITY AND WAIVER</strong></p>
|
||||
<p>1. I agree to abide by the Code of Conduct as listed below, as well as any reasonable instructions given by any Member of the Committee of the Club, or any person appointed by the Club to organise or control any event (Club Officer).</p>
|
||||
<p>2. I acknowledge that driving the off-road track is inherently dangerous, and that I am fully aware of the dangers thereof. I warrant that I will make all members of my party aware of such dangers prior to driving the track.</p>
|
||||
<p>3. While I, or any member of my party, enjoy the facilities at Base 4 including overnight camping, picnicking, driving the track, using the swimming pool facility or activity or any other activity while at Base 4, I agree that under no circumstances shall the Club be liable for any loss or damage of any kind whatsoever (including consequential loss) which I or any of my party may suffer, regardless of how such loss or damage may have been caused or sustained, and whether or not as a result of the negligence or breach of contract (whether fundamental or otherwise) or other wrongful act of the Club, or any Club Officer, or any of the Club’s agents or contractors, and I hereby indemnify and hold harmless the Club and any Club Officer against all such loss or damage.</p>
|
||||
<p>4. The expression, ‘member of my party’, means all persons who accompany me or attending any event at my specific invitation, request or suggestion, and includes without limitation, members of family, guests and invitees.</p>
|
||||
<p>5. I understand that I am responsible for ensuring my vehicle and equipment and that all members of my party have adequate health and medical insurance to cover any and all likely occurrences.</p>
|
||||
<p>6. This indemnity is irrevocable and shall apply to me and the members of my party for any Club events in which I may participate or attend.</p>
|
||||
<p><strong>BASE 4 CODE OF CONDUCT</strong></p>
|
||||
<p>1. No motorbikes or quadbikes.</p>
|
||||
<p>2. No loud music (unless authorised by the Committee or its representatives).</p>
|
||||
<p>3. Dogs to be controlled by their owners who take full responsibility for the animal’s behaviour.</p>
|
||||
<p>4. No dogs belonging to non-members are allowed at Base 4 unless with the express permission of the Committee.</p>
|
||||
<p>5. No person in the rear of open vehicles when driving on obstacles.</p>
|
||||
<p>6. When driving the obstacles stay on the tracks.</p>
|
||||
<p>7. Engage 4WD when driving the obstacles to minimise wear and damage to the track.</p>
|
||||
<p>8. No alcohol to be consumed while driving the track.</p>
|
||||
<p>9. No littering (please pick up cigarette butts etc.)</p>
|
||||
<p>10. All rubbish is to be taken away with you when leaving. Dustbins and refuse collection is not provided.</p>
|
||||
<p>11. Use water sparingly. Please bring your own water and a little extra for the Club.</p>
|
||||
<p>I am a member of the Four Wheel Drive Club of Southern Africa and I will strive to uphold these Codes.</p>
|
||||
</div>
|
||||
<div style="margin-top: 10px;">
|
||||
<input type="checkbox" id="agreeCheckbox" name="agree" disabled required>
|
||||
<label for="agreeCheckbox" id="agreeLabel" style="color: #888;">I have read and agree to the indemnity terms</label>
|
||||
</div>
|
||||
</div>
|
||||
<h6>Total: <span id="booking_total" class="price">-</span></h6>
|
||||
<input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
|
||||
<?php if ($remaining_places < 1): ?>
|
||||
<button type="button" class="theme-btn style-two w-100 mt-15 mb-5" disabled>
|
||||
<span>FULLY BOOKED</span>
|
||||
<i class="fal fa-times-circle"></i>
|
||||
</button>
|
||||
<?php else: ?>
|
||||
<button type="submit" class="theme-btn style-two w-100 mt-15 mb-5">
|
||||
<span data-hover="Book Now">Book Now</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<div class="text-center">
|
||||
<a href="contact">Need some help?</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="widget widget-contact" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<h5 class="widget-title">Need Help?</h5>
|
||||
<ul class="list-style-one">
|
||||
<li><i class="far fa-envelope"></i> <a href="mailto:info@4wdcsa.co.za">info@4wdcsa.co.za</a></li>
|
||||
<li><i class="far fa-phone-volume"></i> <a href="#">+27 79 065 2795</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- <div class="widget widget-cta" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="content text-white">
|
||||
<span class="h6">Explore The World</span>
|
||||
<h3>Best Tourist Place</h3>
|
||||
<a href="tour-grid.html" class="theme-btn style-two bgc-secondary">
|
||||
<span data-hover="Explore Now">Explore Now</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="image">
|
||||
<img src="assets/images/widgets/cta-widget.png" alt="CTA">
|
||||
</div>
|
||||
<div class="cta-shape"><img src="assets/images/widgets/cta-shape3.png" alt="Shape"></div>
|
||||
</div> -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Tour Details Area end -->
|
||||
|
||||
|
||||
<!-- About Us Area end -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||
<!-- Shop Details Area end -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||
<script>
|
||||
const indemnityBox = document.getElementById('indemnityBox');
|
||||
const agreeCheckbox = document.getElementById('agreeCheckbox');
|
||||
const bookingForm = document.querySelector('form');
|
||||
|
||||
indemnityBox.addEventListener('scroll', function() {
|
||||
const scrollTop = indemnityBox.scrollTop;
|
||||
const scrollHeight = indemnityBox.scrollHeight;
|
||||
const offsetHeight = indemnityBox.offsetHeight;
|
||||
|
||||
// Enable checkbox when scrolled to bottom
|
||||
if (scrollTop + offsetHeight >= scrollHeight - 1) {
|
||||
agreeCheckbox.disabled = false;
|
||||
document.getElementById('agreeLabel').style.color = "#000"; // optional: make label active
|
||||
}
|
||||
});
|
||||
|
||||
bookingForm.addEventListener('submit', function(e) {
|
||||
if (agreeCheckbox.disabled || !agreeCheckbox.checked) {
|
||||
alert('Please read and agree to the indemnity terms before booking.');
|
||||
e.preventDefault(); // stop form submission
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Function to calculate booking total
|
||||
function calculateTotal() {
|
||||
// Get selected values from the form
|
||||
var vehicles = parseInt($('#vehicles').val()) || 1; // Default to 1 vehicle if not selected
|
||||
var adults = parseInt($('#adults').val()) || 0; // Default to 1 adult if not selected
|
||||
var pensioners = parseInt($('#pensioners').val()) || 0; // Default to 1 adult if not selected
|
||||
var children = parseInt($('#children').val()) || 0; // Default to 0 children if not selected
|
||||
var radio = $('#add-extra1').is(':checked') ? 50 : 0; // Extra cost for radio rental
|
||||
|
||||
// Fetch PHP variables
|
||||
const isMember = <?php echo isset($is_member) && $is_member ? 'true' : 'false'; ?>;
|
||||
const cost_members = <?php echo $cost_members ?? 0; ?>;
|
||||
const cost_nonmembers = <?php echo $cost_nonmembers ?? 0; ?>;
|
||||
const cost_pensioner = <?php echo $cost_pensioner ?? 0; ?>;
|
||||
const cost_pensioner_member = <?php echo $cost_pensioner_member ?? 0; ?>;
|
||||
const member_discount = <?php echo $member_discount ?? 0; ?>;
|
||||
const member_discount_pensioner = <?php echo $member_discount_pensioner ?? 0; ?>;
|
||||
const booking_fee = <?php echo $booking_fee ?? 0; ?>;
|
||||
|
||||
// Calculate the total cost based on membership
|
||||
let total = 0;
|
||||
let discountAmount = 0;
|
||||
|
||||
if (isMember) {
|
||||
total = ((adults + children) * cost_members) + (pensioners * cost_pensioner_member) + radio + (vehicles * booking_fee);
|
||||
discountAmount = ((adults + children) * member_discount) + (pensioners * member_discount_pensioner);
|
||||
} else {
|
||||
total = ((adults + children) * cost_nonmembers) + (pensioners * cost_pensioner) + radio + (vehicles * booking_fee);
|
||||
}
|
||||
|
||||
$('#booking_total').text('R ' + total.toFixed(2));
|
||||
if (isMember) {
|
||||
$('#discount_amount').text('R ' + discountAmount.toFixed(2));
|
||||
$('#discount_section').show();
|
||||
} else {
|
||||
$('#discount_section').hide();
|
||||
}
|
||||
}
|
||||
|
||||
$('#vehicles, #adults, #children, #pensioners, #add-extra1').on('change', calculateTotal);
|
||||
calculateTotal();
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include_once(dirname(dirname(dirname(__DIR__))) . '/components/insta_footer.php') ?>
|
||||
141
src/pages/bookings/trips.php
Normal file
141
src/pages/bookings/trips.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
$headerStyle = 'light';
|
||||
// Determine the correct path to header.php based on file location
|
||||
$rootPath = dirname(dirname(dirname(__DIR__)));
|
||||
include_once($rootPath . '/header.php');
|
||||
?>
|
||||
|
||||
<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 */
|
||||
}
|
||||
</style>
|
||||
|
||||
<?php
|
||||
$pageTitle = 'Trips';
|
||||
$breadcrumbs = [['Home' => 'index.php']];
|
||||
require_once($rootPath . '/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">
|
||||
<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 getTripCount();?> Trips available
|
||||
</div>
|
||||
<!-- <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 trips table
|
||||
$sql = "SELECT trip_id, trip_name, location, short_description, start_date, end_date, vehicle_capacity, cost_members, places_booked FROM trips WHERE published = 1 AND start_date > CURDATE()";
|
||||
$result = $conn->query($sql);
|
||||
|
||||
if ($result->num_rows > 0) {
|
||||
// Loop through each row
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$trip_id = $row['trip_id'];
|
||||
$trip_name = $row['trip_name'];
|
||||
$location = $row['location'];
|
||||
$short_description = $row['short_description'];
|
||||
$start_date = $row['start_date'];
|
||||
$end_date = $row['end_date'];
|
||||
$capacity = $row['vehicle_capacity'];
|
||||
$cost_members = $row['cost_members'];
|
||||
$places_booked = $row['places_booked'];
|
||||
$remaining_places = getAvailableSpaces($trip_id);
|
||||
|
||||
// Determine the badge text based on the status
|
||||
$badge_text = ($remaining_places > 0) ? $remaining_places.' PLACES LEFT!!' : 'FULLY BOOKED';
|
||||
|
||||
// Output the HTML structure with dynamic data
|
||||
echo '
|
||||
<div class="destination-item style-three bgc-lighter" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image">
|
||||
<span class="badge bgc-pink">' . $badge_text . '</span>
|
||||
<img src="assets/images/trips/' . $trip_id . '_01.jpg" alt="' . $trip_name . '">
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="destination-header">
|
||||
<span class="location"><i class="fal fa-map-marker-alt"></i> ' . $location . '</span>
|
||||
<div class="ratting">
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
<i class="fas fa-star"></i>
|
||||
</div>
|
||||
</div>
|
||||
<h5><a href="trip-details.php?token=' . encryptData($trip_id, $salt) . '">' . $trip_name . '</a></h5>
|
||||
<p>' . $short_description . '</p>
|
||||
<ul class="blog-meta">
|
||||
<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>' . $capacity . ' vehicles max</li>
|
||||
</ul>
|
||||
<div class="destination-footer">
|
||||
<span class="price"><span>R ' . $cost_members . '</span>/person</span>
|
||||
<a href="trip-details.php?token=' . encryptData($trip_id, $salt) . '" class="theme-btn style-two style-three">
|
||||
<span data-hover="Book Now">Book Now</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
}
|
||||
|
||||
// Close connection
|
||||
$conn->close();
|
||||
?>
|
||||
|
||||
<!-- <ul class="pagination pt-15 flex-wrap" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link"><i class="far fa-chevron-left"></i></span>
|
||||
</li>
|
||||
<li class="page-item active">
|
||||
<span class="page-link">
|
||||
1
|
||||
<span class="sr-only">(current)</span>
|
||||
</span>
|
||||
</li>
|
||||
<li class="page-item"><a class="page-link" href="#">2</a></li>
|
||||
<li class="page-item"><a class="page-link" href="#">3</a></li>
|
||||
<li class="page-item"><a class="page-link" href="#">...</a></li>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="#"><i class="far fa-chevron-right"></i></a>
|
||||
</li>
|
||||
</ul> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Tour List Area end -->
|
||||
|
||||
|
||||
<?php include_once($rootPath . '/components/insta_footer.php'); ?>
|
||||
Reference in New Issue
Block a user