Compare commits
8 Commits
feature/ho
...
feature/bl
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d078cb954 | |||
|
|
b69f8f5f1b | ||
|
|
53c29b62ca | ||
|
|
c8c8dfb9c7 | ||
| 561592bc0d | |||
| d1dc0b4ad0 | |||
|
|
4bdfbff0b6 | ||
| 488e3c156d |
3
.gitignore
vendored
@@ -1,3 +1,6 @@
|
||||
.env
|
||||
/vendor/
|
||||
.htaccess
|
||||
/uploads/
|
||||
|
||||
/uploads/pop/
|
||||
144
admin_blogs.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php include_once('header02.php');
|
||||
checkAdmin();
|
||||
checkUserSession();
|
||||
|
||||
$result = $conn->prepare("
|
||||
SELECT
|
||||
b.blog_id,
|
||||
b.title,
|
||||
b.description,
|
||||
b.status,
|
||||
b.date,
|
||||
b.image,
|
||||
CONCAT(u.first_name, ' ', u.last_name) AS author_name,
|
||||
u.email AS author_email,
|
||||
u.profile_pic
|
||||
FROM blogs b
|
||||
JOIN users u ON b.author = u.user_id
|
||||
WHERE b.status != 'deleted'
|
||||
ORDER BY b.date DESC
|
||||
");
|
||||
|
||||
$result->execute();
|
||||
$posts = $result->get_result();
|
||||
|
||||
|
||||
?>
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
<?php
|
||||
$bannerFolder = 'assets/images/banners/';
|
||||
$bannerImages = glob($bannerFolder . '*.{jpg,jpeg,png,webp}', GLOB_BRACE);
|
||||
|
||||
$randomBanner = 'assets/images/base4/camping.jpg'; // default fallback
|
||||
if (!empty($bannerImages)) {
|
||||
$randomBanner = $bannerImages[array_rand($bannerImages)];
|
||||
}
|
||||
?>
|
||||
<section class="page-banner-area pt-50 pb-35 rel z-1 bgs-cover" style="background-image: url('<?php echo $randomBanner; ?>');">
|
||||
<!-- Overlay PNG -->
|
||||
<div class="banner-overlay"></div>
|
||||
<div class="container">
|
||||
<div class="banner-inner text-white">
|
||||
<h2 class="page-title mb-10" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">Admin Blogs</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.php">Home</a></li>
|
||||
<li class="breadcrumb-item active">Admin Blogs</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Page Banner End -->
|
||||
|
||||
|
||||
|
||||
<!-- Blog List Area start -->
|
||||
<section class="blog-list-page py-100 rel z-1">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
|
||||
<h2>My Posts</h2>
|
||||
<?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; ?>
|
||||
<a href="blog_create.php">+ New Post</a>
|
||||
|
||||
<?php while ($post = $posts->fetch_assoc()):
|
||||
// Output the HTML structure with dynamic data
|
||||
echo '
|
||||
<div class="destination-item style-three bgc-lighter booking" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image" style="width:200px;height:200px;">
|
||||
<img src="' . $post["image"] . '" alt="' . $post["title"] . '">
|
||||
</div>
|
||||
<div class="content" style="width:100%;">
|
||||
<div class="destination-header d-flex align-items-start gap-3">
|
||||
<img src="' . $post["profile_pic"] . '" alt="Author" class="rounded-circle border" width="80" height="80">
|
||||
<div>
|
||||
<span class="badge bg-dark mb-1">' . strtoupper($post["status"]) . '</span>
|
||||
<h5 class="mb-0">' . $post["title"] . '</h5>
|
||||
<small class="text-muted">' . $post["author_name"] . '</small>
|
||||
</div>
|
||||
</div>
|
||||
<p>' . $post["description"] . '</p>
|
||||
<div class="destination-footer">
|
||||
<div class="btn-group" style="display:flex; justify-content:flex-end; gap:10px; margin-top:10px;">
|
||||
<a href="blog_edit.php?token='.encryptData($post["blog_id"], $salt).'" class="btn btn-sm" data-bs-toggle="tooltip" data-bs-placement="top" title="Edit"><i class="bi bi-pencil"></i></a>
|
||||
<a href="blog_read.php?token='.encryptData($post["blog_id"], $salt).'" class="btn btn-sm" data-bs-toggle="tooltip" data-bs-placement="top" title="Preview"><i class="bi bi-eye"></i></a>
|
||||
<a href="blog_delete.php?token='.encryptData($post["blog_id"], $salt).'" class="btn btn-sm" data-bs-toggle="tooltip" data-bs-placement="top" title="Delete"><i class="bi bi-trash"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
endwhile; ?>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Blog List Area end -->
|
||||
<script>
|
||||
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]');
|
||||
tooltipTriggerList.forEach(el => new bootstrap.Tooltip(el));
|
||||
</script>
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
@@ -2,7 +2,8 @@
|
||||
checkAdmin();
|
||||
|
||||
// Fetch all trips
|
||||
$courseSql = "SELECT date, course_id, course_type FROM courses";
|
||||
$courseSql = "SELECT date, course_id, course_type FROM courses WHERE DATE(date) >= CURDATE()";
|
||||
|
||||
$courseResult = $conn->query($courseSql);
|
||||
if (!$courseResult) {
|
||||
echo "Error in SQL query: " . $conn->error;
|
||||
|
||||
@@ -198,6 +198,10 @@ if (!empty($bannerImages)) {
|
||||
echo "<td><a href='process_eft.php?token=" . encryptData($row['eft_id'], $salt) . "' class='theme-btn style-two style-three'>
|
||||
<span data-hover='PAYMENT RECEIVED'>" . htmlspecialchars($row['status']) . "</span>
|
||||
</a></td></tr>";
|
||||
} elseif (($row['status']) == 'PROCESSING') {
|
||||
echo "<td><a href='process_payments.php' class='theme-btn style-two style-three'>
|
||||
<span data-hover='PROCESS'>PROCESS</span>
|
||||
</a></td></tr>";
|
||||
} else {
|
||||
echo "<td>" . htmlspecialchars($row['status']) . "</td>";
|
||||
}
|
||||
|
||||
@@ -1,7 +1,19 @@
|
||||
<?php include_once('header02.php');
|
||||
checkAdmin();
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST['accept_indemnity'])) {
|
||||
$user_id = intval($_POST['user_id']);
|
||||
$stmt = $conn->prepare("UPDATE membership_application SET accept_indemnity = 1 WHERE user_id = ?");
|
||||
if ($stmt) {
|
||||
$stmt->bind_param("i", $user_id);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
}
|
||||
}
|
||||
|
||||
// SQL query to fetch data
|
||||
$sql = "SELECT user_id, first_name, last_name, tel_cell, email, dob FROM membership_application";
|
||||
$sql = "SELECT user_id, first_name, last_name, tel_cell, email, dob, accept_indemnity FROM membership_application";
|
||||
|
||||
$result = $conn->query($sql);
|
||||
?>
|
||||
<style>
|
||||
@@ -82,6 +94,10 @@ $result = $conn->query($sql);
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.theme-btn,
|
||||
a.theme-btn {
|
||||
padding: 0px 14px;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
@@ -137,7 +153,7 @@ if (!empty($bannerImages)) {
|
||||
}
|
||||
?>
|
||||
<section class="page-banner-area pt-50 pb-35 rel z-1 bgs-cover" style="background-image: url('<?php echo $randomBanner; ?>');">
|
||||
<div class="banner-overlay"></div>
|
||||
<div class="banner-overlay"></div>
|
||||
<div class="container">
|
||||
<div class="banner-inner text-white mb-50">
|
||||
<h2 class="page-title mb-10" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">4WDCSA Members</h2>
|
||||
@@ -167,7 +183,9 @@ if (!empty($bannerImages)) {
|
||||
<th>Cell Number</th>
|
||||
<th>Email</th>
|
||||
<th>Date of Birth</th>
|
||||
<th>Membership</th>
|
||||
<th>Membership</th>
|
||||
<th>View Info</th>
|
||||
<th>Indemnity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -176,23 +194,32 @@ if (!empty($bannerImages)) {
|
||||
// Output data of each row
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
echo "<tr>
|
||||
<td>" . htmlspecialchars($row['first_name']) . "</td>
|
||||
<td>" . htmlspecialchars($row['last_name']) . "</td>
|
||||
<td>" . htmlspecialchars($row['tel_cell']) . "</td>
|
||||
<td>" . htmlspecialchars($row['email']) . "</td>
|
||||
<td>" . htmlspecialchars($row['dob']) . "</td>
|
||||
<td>";
|
||||
if (getUserMemberStatus($row['user_id'])) {
|
||||
echo 'ACTIVE';
|
||||
<td>" . htmlspecialchars($row['first_name']) . "</td>
|
||||
<td>" . htmlspecialchars($row['last_name']) . "</td>
|
||||
<td>" . htmlspecialchars($row['tel_cell']) . "</td>
|
||||
<td>" . htmlspecialchars($row['email']) . "</td>
|
||||
<td>" . htmlspecialchars($row['dob']) . "</td>
|
||||
<td>" . (getUserMemberStatus($row['user_id']) ? 'ACTIVE' : 'INACTIVE') . "</td>
|
||||
<td><a href='member_info.php?token=" . encryptData($row['user_id'], $salt) . "' class='theme-btn style-two style-three'><span data-hover='PAYMENT RECEIVED'>View Info</span></a></td>
|
||||
<td>";
|
||||
|
||||
if (!$row['accept_indemnity']) {
|
||||
echo "<form method='POST' style='display:inline;'>
|
||||
<input type='hidden' name='user_id' value='" . $row['user_id'] . "'>
|
||||
<button type='submit' name='accept_indemnity' class='theme-btn small'>Accept</button>
|
||||
</form>";
|
||||
} else {
|
||||
echo 'INACTIVE';
|
||||
};
|
||||
echo "✅ Accepted";
|
||||
}
|
||||
|
||||
echo "</td>
|
||||
</tr>";
|
||||
</tr>";
|
||||
}
|
||||
} else {
|
||||
echo '<tr><td colspan="5">No records found</td></tr>';
|
||||
} ?>
|
||||
echo '<tr><td colspan="8">No records found</td></tr>';
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -170,7 +170,7 @@ if (!empty($bannerImages)) {
|
||||
echo "<h4>{$tripName}</h4>";
|
||||
|
||||
// Fetch bookings for the current trip
|
||||
$bookingsSql = "SELECT b.user_id, b.num_vehicles, b.num_adults, b.num_children, b.radio, b.status,
|
||||
$bookingsSql = "SELECT b.user_id, b.num_vehicles, b.num_adults, b.num_children, b.num_pensioners, b.radio, b.status,
|
||||
u.first_name, u.last_name,
|
||||
(b.total_amount - b.discount_amount) AS paid
|
||||
FROM bookings b
|
||||
@@ -192,6 +192,7 @@ if (!empty($bannerImages)) {
|
||||
<th>Vehicles</th>
|
||||
<th>Adults</th>
|
||||
<th>Children</th>
|
||||
<th>Pensioners</th>
|
||||
<th>Radio</th>
|
||||
<th>Status</th>
|
||||
<th>Amount</th>
|
||||
@@ -202,6 +203,7 @@ if (!empty($bannerImages)) {
|
||||
$userName = htmlspecialchars($booking['first_name'] . ' ' . $booking['last_name']);
|
||||
$numVehicles = htmlspecialchars($booking['num_vehicles']);
|
||||
$numAdults = htmlspecialchars($booking['num_adults']);
|
||||
$numPensioners = htmlspecialchars($booking['num_pensioners']);
|
||||
$numChildren = htmlspecialchars($booking['num_children']);
|
||||
$radio = $booking['radio'] == 1 ? "YES" : "NO";
|
||||
$status = htmlspecialchars($booking['status']);
|
||||
@@ -213,6 +215,7 @@ if (!empty($bannerImages)) {
|
||||
<td>{$numVehicles}</td>
|
||||
<td>{$numAdults}</td>
|
||||
<td>{$numChildren}</td>
|
||||
<td>{$numPensioners}</td>
|
||||
<td>{$radio}</td>
|
||||
<td>{$status}</td>
|
||||
<td>{$paid}</td>
|
||||
|
||||
@@ -170,7 +170,7 @@ if (!empty($bannerImages)) {
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<!-- <th></th> -->
|
||||
<th>First Name</th>
|
||||
<th>Last Name</th>
|
||||
<th>Email</th>
|
||||
@@ -209,7 +209,7 @@ if (!empty($bannerImages)) {
|
||||
|
||||
echo "<tr>
|
||||
<td><img src=" . $row['profile_pic'] . " alt='Profile Picture' class='profile-pic'></td>
|
||||
<td>" . htmlspecialchars($row['user_id']) . "</td>
|
||||
|
||||
<td>" . htmlspecialchars($row['first_name']) . "</td>
|
||||
<td>" . htmlspecialchars($row['last_name']) . "</td>
|
||||
<td>" . htmlspecialchars($row['email']) . "</td>
|
||||
@@ -228,10 +228,10 @@ if (!empty($bannerImages)) {
|
||||
} else {
|
||||
echo "\u{2713}";
|
||||
}
|
||||
echo "</td>
|
||||
<td><a href='linkmembership.php?user_id=".$row['user_id']."'>Link Membership</a></td>
|
||||
// echo "</td>
|
||||
// <td><a href='linkmembership.php?user_id=".$row['user_id']."'>Link Membership</a></td>
|
||||
|
||||
</tr>";
|
||||
// </tr>";
|
||||
}
|
||||
} else {
|
||||
echo '<tr><td colspan="5">No records found</td></tr>';
|
||||
|
||||
BIN
assets/images/events/medicine.jpg
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
BIN
assets/images/promo/potjie.jpg
Normal file
|
After Width: | Height: | Size: 334 KiB |
BIN
assets/images/trips/6_01.jpg
Normal file
|
After Width: | Height: | Size: 62 KiB |
BIN
assets/images/trips/6_02.jpg
Normal file
|
After Width: | Height: | Size: 136 KiB |
BIN
assets/images/trips/6_03.jpg
Normal file
|
After Width: | Height: | Size: 128 KiB |
BIN
assets/images/trips/6_04.jpg
Normal file
|
After Width: | Height: | Size: 258 KiB |
BIN
assets/images/trips/6_05.jpg
Normal file
|
After Width: | Height: | Size: 95 KiB |
101
autosave.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("session.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
http_response_code(401);
|
||||
echo "Not authorized";
|
||||
exit;
|
||||
}
|
||||
|
||||
$article_id = (int)($_POST['id'] ?? 0);
|
||||
$title = $_POST['title'] ?? '';
|
||||
$content = $_POST['content'] ?? '';
|
||||
$description = $_POST['subtitle'] ?? '';
|
||||
$category = $_POST['category'] ?? '';
|
||||
$user_id = $_SESSION['user_id'];
|
||||
|
||||
|
||||
// Default to current user
|
||||
$author_id = $_SESSION['user_id'];
|
||||
|
||||
// Allow override if admin
|
||||
$role = getUserRole();
|
||||
if (($role === 'admin' || $role === 'superadmin') && isset($_POST['author'])) {
|
||||
$author_id = (int)$_POST['author'];
|
||||
}
|
||||
echo $author_id;
|
||||
|
||||
$cover_image_path = null;
|
||||
|
||||
// Only attempt upload if a file was submitted
|
||||
if (!empty($_FILES['cover_image']['name'])) {
|
||||
$uploadDir = __DIR__ . "/uploads/blogs/".$article_id."/images/";
|
||||
if (!is_dir($uploadDir)) {
|
||||
mkdir($uploadDir, 0777, true);
|
||||
}
|
||||
|
||||
// Sanitize and rename file
|
||||
$originalName = basename($_FILES['cover_image']['name']);
|
||||
$originalName = preg_replace("/[^a-zA-Z0-9\._-]/", "_", $originalName); // remove unsafe characters
|
||||
|
||||
$targetPath = $uploadDir . $originalName;
|
||||
$publicPath = "/uploads/blogs/".$article_id."/images/" . $originalName;
|
||||
|
||||
// Error detection before upload
|
||||
$fileError = $_FILES['cover_image']['error'];
|
||||
if ($fileError !== UPLOAD_ERR_OK) {
|
||||
$errorMessages = [
|
||||
UPLOAD_ERR_INI_SIZE => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.',
|
||||
UPLOAD_ERR_FORM_SIZE => 'The uploaded file exceeds the MAX_FILE_SIZE directive in the HTML form.',
|
||||
UPLOAD_ERR_PARTIAL => 'The uploaded file was only partially uploaded.',
|
||||
UPLOAD_ERR_NO_FILE => 'No file was uploaded.',
|
||||
UPLOAD_ERR_NO_TMP_DIR => 'Missing a temporary folder.',
|
||||
UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk.',
|
||||
UPLOAD_ERR_EXTENSION => 'A PHP extension stopped the upload.',
|
||||
];
|
||||
$errorMessage = $errorMessages[$fileError] ?? 'Unknown upload error.';
|
||||
http_response_code(500);
|
||||
echo "Upload error: $errorMessage";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Skip upload if identical file already exists
|
||||
if (file_exists($targetPath)) {
|
||||
$cover_image_path = $publicPath;
|
||||
} else {
|
||||
if (move_uploaded_file($_FILES['cover_image']['tmp_name'], $targetPath)) {
|
||||
$cover_image_path = $publicPath;
|
||||
} else {
|
||||
http_response_code(500);
|
||||
echo "Failed to move uploaded file.";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare SQL with/without image update
|
||||
if ($cover_image_path) {
|
||||
$stmt = $conn->prepare("
|
||||
UPDATE blogs
|
||||
SET title = ?, content = ?, description = ?, category = ?, image = ?, author = ?
|
||||
WHERE blog_id = ?
|
||||
");
|
||||
$stmt->bind_param("ssssssi", $title, $content, $description, $category, $cover_image_path, $author_id, $article_id);
|
||||
} else {
|
||||
$stmt = $conn->prepare("
|
||||
UPDATE blogs
|
||||
SET title = ?, content = ?, description = ?, category = ?, author = ?
|
||||
WHERE blog_id = ?
|
||||
");
|
||||
$stmt->bind_param("ssssii", $title, $content, $description, $category, $author_id, $article_id);
|
||||
}
|
||||
|
||||
if ($stmt->execute()) {
|
||||
echo "Saved";
|
||||
} else {
|
||||
http_response_code(500);
|
||||
echo "Database update failed: " . $stmt->error;
|
||||
}
|
||||
8
blog.php
@@ -64,7 +64,7 @@ if (!empty($bannerImages)) {
|
||||
<div class="col-lg-8">
|
||||
<?php
|
||||
// Query to retrieve data from the trips table
|
||||
$sql = "SELECT blog_id, title, date, category, image, description, author, members_only, link FROM blogs ORDER BY date DESC";
|
||||
$sql = "SELECT blog_id, title, date, category, image, description, author, members_only, link FROM blogs WHERE status = 'published' ORDER BY date DESC";
|
||||
$result = $conn->query($sql);
|
||||
|
||||
if ($result->num_rows > 0) {
|
||||
@@ -86,7 +86,7 @@ if (!empty($bannerImages)) {
|
||||
$icon = "fa-lock";
|
||||
} else {
|
||||
if (getUserMemberStatus($_SESSION['user_id'])) {
|
||||
$blog_link = $row['link'];
|
||||
$blog_link = "blog_read.php?token=".encryptData($blog_id, $salt);
|
||||
$button_hover = "Read More";
|
||||
$icon = "fa-arrow-right";
|
||||
} else {
|
||||
@@ -96,7 +96,7 @@ if (!empty($bannerImages)) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$blog_link = $row['link'];
|
||||
$blog_link = "blog_read.php?token=".encryptData($blog_id, $salt);
|
||||
$button_hover = "Read More";
|
||||
$icon = "fa-arrow-right";
|
||||
}
|
||||
@@ -105,7 +105,7 @@ if (!empty($bannerImages)) {
|
||||
echo '
|
||||
<div class="blog-item style-three" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image">
|
||||
<img style="border-radius:20px;" src="assets/images/blog/' . $blog_id . '/' . $image . '" alt="Blog List">
|
||||
<img style="border-radius:20px;" src="' . $image . '" alt="Blog List">
|
||||
</div>
|
||||
<div class="content">
|
||||
<a href="blog.php" class="category">' . $category . '</a>
|
||||
|
||||
33
blog_create.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
// session_start();
|
||||
require_once("env.php");
|
||||
require_once("session.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
die("Not logged in");
|
||||
}
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$role = getUserRole();
|
||||
|
||||
if(!getUserMemberStatus($user_id)){
|
||||
if ($role === 'user'){
|
||||
$_SESSION['message'] = "Blogs only available to active members. Please contact info@4wdcsa.co.za for more information.";
|
||||
header("Location: user_blogs.php");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$date = date('Y-m-d');
|
||||
$status = 'draft';
|
||||
|
||||
$stmt = $conn->prepare("INSERT INTO blogs (author, title, category, description, content, date, status)
|
||||
VALUES (?, '', '', '', '', ?, ?)");
|
||||
$stmt->bind_param("iss", $user_id, $date, $status);
|
||||
$stmt->execute();
|
||||
|
||||
$blog_id = $stmt->insert_id;
|
||||
header("Location: blog_edit.php?token=" . encryptData($blog_id, $salt));
|
||||
exit;
|
||||
36
blog_delete.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("session.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
$_SESSION['message'] = "Not authorized.";
|
||||
header("Location: user_blogs.php");
|
||||
exit;
|
||||
}
|
||||
|
||||
$token = $_GET['token'];
|
||||
// Sanitize the trip_id to prevent SQL injection
|
||||
$article_id = intval(decryptData($token, $salt)); // Ensures $trip_id is treated as an integer
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
|
||||
if ($article_id <= 0) {
|
||||
$_SESSION['message'] = "Invalid blog ID.";
|
||||
header("Location: user_blogs.php");
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = $conn->prepare("UPDATE blogs SET status = 'deleted' WHERE blog_id = ? AND author = ?");
|
||||
$stmt->bind_param("ii", $article_id, $user_id);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$_SESSION['message'] = "Blog deleted!";
|
||||
} else {
|
||||
$_SESSION['message'] = "Failed to delete blog: " . $stmt->error;
|
||||
}
|
||||
|
||||
header("Location: user_blogs.php");
|
||||
exit;
|
||||
?>
|
||||
265
blog_edit.php
Normal file
@@ -0,0 +1,265 @@
|
||||
<?php
|
||||
include_once('header02.php');
|
||||
|
||||
// Ensure the user is logged in
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
die("User not logged in.");
|
||||
}
|
||||
|
||||
$token = $_GET['token'];
|
||||
// Sanitize the trip_id to prevent SQL injection
|
||||
$blog_id = intval(decryptData($token, $salt)); // Ensures $trip_id is treated as an integer
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$role = getUserRole();
|
||||
|
||||
// Fetch article info
|
||||
$stmt = $conn->prepare("SELECT * FROM blogs WHERE blog_id = ?");
|
||||
$stmt->bind_param("i", $blog_id);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
if ($result->num_rows === 0) {
|
||||
die("Blog post not found.");
|
||||
}
|
||||
$article = $result->fetch_assoc();
|
||||
$stmt->close();
|
||||
?>
|
||||
|
||||
<script src="https://cdn.tiny.cloud/1/o6xuedbd9z22xk0p5zszinevn4bdbljxnfwn0tjjvv6r37pb/tinymce/6/tinymce.min.js" referrerpolicy="origin"></script>
|
||||
<script>
|
||||
tinymce.init({
|
||||
selector: '#content',
|
||||
plugins: 'image code link',
|
||||
toolbar: 'undo redo | blocks | bold italic | alignleft aligncenter alignright | code | image | link',
|
||||
images_upload_url: 'upload.php?blog_id=<?= $blog_id ?>',
|
||||
image_class_list: [
|
||||
{ title: 'None', value: '' },
|
||||
{ title: 'Left Align', value: 'img-left' },
|
||||
{ title: 'Right Align', value: 'img-right' },
|
||||
{ title: 'Rounded', value: 'img-rounded' }
|
||||
],
|
||||
automatic_uploads: true,
|
||||
images_upload_credentials: true, // include cookies if needed
|
||||
content_style: "body { font-family:Helvetica,Arial,sans-serif; font-size:14px }",
|
||||
|
||||
setup: function (editor) {
|
||||
editor.on('init', function () {
|
||||
setTimeout(() => {
|
||||
editor.setContent(`<?= str_replace("`", "\`", addslashes($article['content'])) ?>`);
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<section class="account-settings-area py-70 rel z-1">
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-lg-12">
|
||||
<div class="comment-form bgc-lighter z-1 rel mb-55">
|
||||
<form action="submit_blog.php" method="POST" enctype="multipart/form-data">
|
||||
<input type="hidden" name="article_id" value="<?= htmlspecialchars($blog_id) ?>">
|
||||
<div class="section-title py-20">
|
||||
<h2>Edit Blog</h2>
|
||||
<div id="autosave-status" style="font-style: italic; font-size: 0.9em;"></div>
|
||||
</div>
|
||||
<div class="row mt-35">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="title">Blog Title</label>
|
||||
<input type="text" id="title" class="form-control" name="title" placeholder="Title" required value="<?= htmlspecialchars($article['title']) ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="form-group">
|
||||
<label for="subtitle">Description</label>
|
||||
<input type="text" id="subtitle" class="form-control" name="subtitle" placeholder="Description" required value="<?= htmlspecialchars($article['description']) ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="form-group">
|
||||
<label for="cover_image">Cover Image</label>
|
||||
<input type="file" class="form-control" name="cover_image" id="cover_image" accept="image/*">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12 mb-10">
|
||||
<div class="form-group">
|
||||
<label for="category">Blog Category</label>
|
||||
<select name="category" class="form-control" id="category" required>
|
||||
<option value="Trip Report" <?= $article['category'] == 'Trip Report' ? 'selected' : '' ?>>Trip Report</option>
|
||||
<option value="Gear Review" <?= $article['category'] == 'Gear Review' ? 'selected' : '' ?>>Gear Review</option>
|
||||
<option value="Talking Dirty" <?= $article['category'] == 'Talking Dirty' ? 'selected' : '' ?>>Talking Dirty</option>
|
||||
<option value="Report" <?= $article['category'] == 'Report' ? 'selected' : '' ?>>Report</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12 mb-10">
|
||||
<div class="form-group">
|
||||
<?php if ($role === 'admin' || $role === 'superadmin'): ?>
|
||||
<label for="author">Author:</label>
|
||||
<select class="form-control" name="author" id="author">
|
||||
<?php
|
||||
$user_query = $conn->query("SELECT user_id, CONCAT(first_name, ' ', last_name) AS name FROM users ORDER BY first_name ASC");
|
||||
while ($user = $user_query->fetch_assoc()):
|
||||
?>
|
||||
<option value="<?= $user['user_id'] ?>" <?= $user['user_id'] == $article['author'] ? 'selected' : '' ?>>
|
||||
<?= htmlspecialchars($user['name']) ?>
|
||||
</option>
|
||||
<?php endwhile; ?>
|
||||
</select>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="form-group">
|
||||
<textarea id="content" name="content"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="form-group">
|
||||
<button type="button" class="theme-btn style-three" style="width:100%;" id="manualSaveBtn">Save Draft</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<a href="blog_read.php?token=<?php echo encryptData($blog_id, $salt); ?>" class="theme-btn style-three" style="width:100%;">Preview</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<?php
|
||||
if ($article['status'] == 'draft'){
|
||||
echo '<div class="form-group">
|
||||
<button type="button" class="theme-btn style-two" style="width:100%;" id="manualPostBtn">Publish</button>
|
||||
|
||||
</div> ';
|
||||
} else {
|
||||
echo '<div class="form-group">
|
||||
<button type="button" class="theme-btn style-two" style="width:100%;" id="manualDraftBtn">Un-Publish</button>
|
||||
|
||||
</div> ';
|
||||
}?>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||
<script>
|
||||
function autosavePost() {
|
||||
const title = document.querySelector('[name="title"]').value;
|
||||
const content = tinymce.get("content").getContent();
|
||||
const subtitle = document.querySelector('[name="subtitle"]').value;
|
||||
const category = document.querySelector('[name="category"]').value;
|
||||
const author = document.querySelector('[name="author"]').value;
|
||||
const articleId = document.querySelector('[name="article_id"]').value;
|
||||
const coverImageInput = document.querySelector('[name="cover_image"]');
|
||||
|
||||
console.log("Saving: ", { title, subtitle, content, category, articleId, author });
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("id", articleId);
|
||||
formData.append("title", title);
|
||||
formData.append("content", content);
|
||||
formData.append("subtitle", subtitle);
|
||||
formData.append("category", category);
|
||||
formData.append("author", author);
|
||||
|
||||
// Only append image if a new file is selected
|
||||
if (coverImageInput.files.length > 0) {
|
||||
formData.append("cover_image", coverImageInput.files[0]);
|
||||
}
|
||||
|
||||
return fetch("autosave.php", {
|
||||
method: "POST",
|
||||
body: formData
|
||||
}).then(response => {
|
||||
if (response.ok) {
|
||||
document.getElementById("autosave-status").innerText = "Draft autosaved at " + new Date().toLocaleTimeString();
|
||||
return true;
|
||||
} else {
|
||||
document.getElementById("autosave-status").innerText = "Autosave failed";
|
||||
console.error("Autosave failed", response.statusText);
|
||||
return false;
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error("Autosave error:", err);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
// Trigger autosave every 15s
|
||||
setInterval(autosavePost, 15000);
|
||||
|
||||
// Manual autosave button
|
||||
document.getElementById("manualSaveBtn").addEventListener("click", autosavePost);
|
||||
|
||||
// Manual publish button
|
||||
document.getElementById("manualPostBtn").addEventListener("click", function () {
|
||||
autosavePost().then(success => {
|
||||
if (!success) return;
|
||||
|
||||
const articleId = document.querySelector('[name="article_id"]').value;
|
||||
const publishData = new FormData();
|
||||
publishData.append("id", articleId);
|
||||
|
||||
fetch("publish_blog.php", {
|
||||
method: "POST",
|
||||
body: publishData
|
||||
}).then(response => {
|
||||
if (response.ok) {
|
||||
alert("Post published successfully!");
|
||||
// Optional: redirect to the live post
|
||||
window.location.href = "blog_read.php?token=<?php echo encryptData($blog_id, $salt);?>";
|
||||
} else {
|
||||
alert("Publish failed.");
|
||||
console.error("Publish error:", response.statusText);
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error("Publish error:", err);
|
||||
alert("Publish failed due to network error.");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Manual unpublish button
|
||||
document.getElementById("manualDraftBtn").addEventListener("click", function () {
|
||||
autosavePost().then(success => {
|
||||
if (!success) return;
|
||||
|
||||
const articleId = document.querySelector('[name="article_id"]').value;
|
||||
const publishData = new FormData();
|
||||
publishData.append("id", articleId);
|
||||
|
||||
fetch("blog_unpublish.php", {
|
||||
method: "POST",
|
||||
body: publishData
|
||||
}).then(response => {
|
||||
if (response.ok) {
|
||||
alert("Post unpublished successfully!");
|
||||
// Optional: redirect to the live post
|
||||
window.location.href = "blog_read.php?token=<?php echo encryptData($blog_id, $salt);?>";
|
||||
} else {
|
||||
alert("unPublish failed.");
|
||||
console.error("Publish error:", response.statusText);
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error("Publish error:", err);
|
||||
alert("Publish failed due to network error.");
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
176
blog_read.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php include_once('header02.php');
|
||||
|
||||
$token = $_GET['token'];
|
||||
// Sanitize the trip_id to prevent SQL injection
|
||||
$blog_id = intval(decryptData($token, $salt)); // Ensures $trip_id is treated as an integer
|
||||
|
||||
|
||||
$page_id = 'blog_'.$blog_id;
|
||||
echo getCommentCount($page_id);
|
||||
|
||||
|
||||
$stmt = $conn->prepare("
|
||||
SELECT a.title, a.category, a.description, a.content, a.date,
|
||||
u.first_name, u.last_name
|
||||
FROM blogs a
|
||||
JOIN users u ON a.author = u.user_id
|
||||
WHERE a.blog_id = ?
|
||||
");
|
||||
$stmt->bind_param("i", $blog_id);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
if ($result->num_rows === 0) {
|
||||
die("Article not found.");
|
||||
}
|
||||
|
||||
$row = $result->fetch_assoc();
|
||||
$author = htmlspecialchars($row['first_name'] . ' ' . $row['last_name']);
|
||||
?>
|
||||
|
||||
|
||||
<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>
|
||||
<style>
|
||||
body {
|
||||
/* font-family: Arial, sans-serif; */
|
||||
line-height: 1.6;
|
||||
/* max-width: 800px; */
|
||||
margin: auto;
|
||||
/* padding: 20px; */
|
||||
}
|
||||
|
||||
h1,
|
||||
h2 {
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.img-left,
|
||||
.img-right {
|
||||
max-width: 30%;
|
||||
margin: 20px;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.img-left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.img-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.clearfix {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<?php
|
||||
$bannerFolder = 'assets/images/banners/';
|
||||
$bannerImages = glob($bannerFolder . '*.{jpg,jpeg,png,webp}', GLOB_BRACE);
|
||||
|
||||
$randomBanner = 'assets/images/base4/camping.jpg'; // default fallback
|
||||
if (!empty($bannerImages)) {
|
||||
$randomBanner = $bannerImages[array_rand($bannerImages)];
|
||||
}
|
||||
?>
|
||||
<section class="page-banner-area pt-50 pb-35 rel z-1 bgs-cover" style="background-image: url('<?php echo $randomBanner; ?>');">
|
||||
<div class="banner-overlay"></div>
|
||||
<div class="container">
|
||||
<div class="banner-inner text-white">
|
||||
<h2 class="page-title mb-10" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50"><?= htmlspecialchars($row['title']) ?></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.php">Home</a></li>
|
||||
<li class="breadcrumb-item active"><?= htmlspecialchars($row['title']) ?></li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Page Banner End -->
|
||||
|
||||
|
||||
<!-- Blog Detaisl Area start -->
|
||||
<section class="blog-detaisl-page py-100 rel z-1">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<div class="blog-details-content" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<a href="blog.html" class="category"><?= htmlspecialchars($row['category']) ?></a>
|
||||
<ul class="blog-meta mb-30">
|
||||
<li><img src="assets/images/pp/default.png" alt="Admin"> <a href="#"><?= $author?></a></li>
|
||||
<li><i class="far fa-calendar-alt"></i> <a href="#"><?= htmlspecialchars($row['date']) ?></a></li>
|
||||
<li><i class="far fa-comments"></i> <a href="#">Comments (<?= getCommentCount($page_id);?>)</a></li>
|
||||
</ul>
|
||||
|
||||
<?= $row['content'] ?>
|
||||
</div>
|
||||
<hr class="mb-45">
|
||||
<div class="tag-share mb-50">
|
||||
<div class="item" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">
|
||||
<h6>Tags </h6>
|
||||
<div class="tag-coulds">
|
||||
<a href="blog.php"><?= htmlspecialchars($row['category']) ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php include_once('comment_box.php'); ?>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-8 col-sm-10 rmt-75">
|
||||
<div class="blog-sidebar">
|
||||
<div class="widget widget-gallery" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<h5 class="widget-title">Gallery</h5>
|
||||
<div class="gallery">
|
||||
<?php
|
||||
$folder = 'uploads/blogs/'.$blog_id.'/images/';
|
||||
$files = glob($folder . '*.{jpg,jpeg,png,webp}', GLOB_BRACE);
|
||||
shuffle($files); // Randomize the order
|
||||
|
||||
foreach ($files as $file) {
|
||||
echo '<a href="' . $file . '" style="width: 110px; height: 110px; overflow: hidden; display: inline-block; margin: 2px;">';
|
||||
echo '<img src="' . $file . '" alt="Gallery" style="width: 100%; height: 100%; object-fit: cover; display: block;">';
|
||||
echo '</a>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
31
blog_unpublish.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("session.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
http_response_code(401);
|
||||
echo "Not authorized";
|
||||
exit;
|
||||
}
|
||||
|
||||
$article_id = (int)($_POST['id'] ?? 0);
|
||||
$user_id = $_SESSION['user_id'];
|
||||
|
||||
if ($article_id <= 0) {
|
||||
http_response_code(400);
|
||||
echo "Invalid blog ID";
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = $conn->prepare("UPDATE blogs SET status = 'draft' WHERE blog_id = ? AND author = ?");
|
||||
$stmt->bind_param("ii", $article_id, $user_id);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
echo "Published";
|
||||
} else {
|
||||
http_response_code(500);
|
||||
echo "Failed to publish: " . $stmt->error;
|
||||
}
|
||||
?>
|
||||
128
events.php
@@ -2,20 +2,66 @@
|
||||
|
||||
<style>
|
||||
.image {
|
||||
width: 400px; /* Set your desired width */
|
||||
height: 320px; /* Set your desired height */
|
||||
overflow: hidden; /* Hide any overflow */
|
||||
display: block; /* Ensure proper block behavior */
|
||||
}
|
||||
width: 400px;
|
||||
/* Set your desired width */
|
||||
height: 320px;
|
||||
/* 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 */
|
||||
}
|
||||
.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 */
|
||||
}
|
||||
|
||||
.custom-modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
background-color: rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
|
||||
.custom-modal-content {
|
||||
margin: 5% auto;
|
||||
padding: 20px;
|
||||
max-width: 800px;
|
||||
text-align: center;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.custom-modal-content img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.custom-modal-close {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 20px;
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
<?php
|
||||
@@ -28,7 +74,7 @@ if (!empty($bannerImages)) {
|
||||
}
|
||||
?>
|
||||
<section class="page-banner-area pt-50 pb-35 rel z-1 bgs-cover" style="background-image: url('<?php echo $randomBanner; ?>');">
|
||||
<div class="banner-overlay"></div>
|
||||
<div class="banner-overlay"></div>
|
||||
<div class="container">
|
||||
<div class="banner-inner text-white mb-50">
|
||||
<h2 class="page-title mb-10" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">4WDCSA events</h2>
|
||||
@@ -66,10 +112,10 @@ if (!empty($bannerImages)) {
|
||||
<option value="low-to-high">Low To High</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
<?php
|
||||
// Query to retrieve data from the trips table
|
||||
$sql = "SELECT event_id, date, time, name, image, description, feature, location, type FROM events WHERE date > CURDATE()";
|
||||
$sql = "SELECT event_id, date, time, name, image, description, feature, location, type, promo FROM events WHERE date > CURDATE() ORDER BY date ASC";
|
||||
|
||||
$result = $conn->query($sql);
|
||||
|
||||
@@ -85,6 +131,7 @@ if (!empty($bannerImages)) {
|
||||
$feature = $row['feature'];
|
||||
$location = $row['location'];
|
||||
$type = $row['type'];
|
||||
$promo = $row['promo'];
|
||||
|
||||
// Determine the badge text based on the status
|
||||
$badge_text = 'OPEN DAY';
|
||||
@@ -104,8 +151,14 @@ if (!empty($bannerImages)) {
|
||||
<p>' . $description . '</p>
|
||||
<ul class="blog-meta">
|
||||
<li><i class="far fa-calendar"></i> ' . convertDate($date) . '</li>
|
||||
<li><i class="far fa-clock"></i> '.$time.'</li>
|
||||
</ul>
|
||||
<li><i class="far fa-clock"></i> ' . $time . '</li>
|
||||
</ul>
|
||||
<button type="button" class="theme-btn style-three view-image-btn" style="padding: 2px 20px"
|
||||
data-image-src="' . $promo . '"
|
||||
data-image-title="' . htmlspecialchars($name, ENT_QUOTES) . '">
|
||||
View Promo
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
@@ -117,12 +170,51 @@ if (!empty($bannerImages)) {
|
||||
$conn->close();
|
||||
?>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Tour List Area end -->
|
||||
<!-- Custom Image Modal -->
|
||||
<div id="customImageModal" class="custom-modal">
|
||||
<div class="custom-modal-content">
|
||||
<span class="custom-modal-close">×</span>
|
||||
<h5 id="modalImageTitle"></h5>
|
||||
<img id="modalImageElement" src="" alt="" class="img-fluid">
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const modal = document.getElementById("customImageModal");
|
||||
const modalImg = document.getElementById("modalImageElement");
|
||||
const modalTitle = document.getElementById("modalImageTitle");
|
||||
const closeBtn = document.querySelector(".custom-modal-close");
|
||||
|
||||
document.querySelectorAll(".view-image-btn").forEach(button => {
|
||||
button.addEventListener("click", () => {
|
||||
const src = button.getAttribute("data-image-src");
|
||||
const title = button.getAttribute("data-image-title");
|
||||
modalImg.src = src;
|
||||
modalTitle.textContent = title;
|
||||
modal.style.display = "block";
|
||||
});
|
||||
});
|
||||
|
||||
closeBtn.addEventListener("click", () => {
|
||||
modal.style.display = "none";
|
||||
modalImg.src = "";
|
||||
});
|
||||
|
||||
// Optional: click outside modal to close
|
||||
window.addEventListener("click", (e) => {
|
||||
if (e.target === modal) {
|
||||
modal.style.display = "none";
|
||||
modalImg.src = "";
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
@@ -32,7 +32,7 @@ function getTripCount()
|
||||
$conn = openDatabaseConnection();
|
||||
|
||||
// SQL query to count the number of rows
|
||||
$sql = "SELECT COUNT(*) AS total FROM trips WHERE start_date > CURDATE()";
|
||||
$sql = "SELECT COUNT(*) AS total FROM trips WHERE published = 1 AND start_date > CURDATE()";
|
||||
$result = $conn->query($sql);
|
||||
|
||||
// Fetch the count from the result
|
||||
@@ -236,7 +236,7 @@ function sendAdminNotification($subject, $message)
|
||||
{
|
||||
global $mailjet;
|
||||
|
||||
$message = [
|
||||
$mail = [
|
||||
'Messages' => [
|
||||
[
|
||||
'From' => [
|
||||
@@ -245,7 +245,7 @@ function sendAdminNotification($subject, $message)
|
||||
],
|
||||
'To' => [
|
||||
[
|
||||
'Email' => "info@4wdcsa.co.za",
|
||||
'Email' => $_ENV['NOTIFICATION_ADDR'],
|
||||
'Name' => 'Jacqui Boshoff'
|
||||
]
|
||||
],
|
||||
@@ -265,7 +265,7 @@ function sendAdminNotification($subject, $message)
|
||||
]);
|
||||
|
||||
$response = $client->request('POST', 'send', [
|
||||
'json' => $message,
|
||||
'json' => $mail,
|
||||
'auth' => ['1a44f8d5e847537dbb8d3c76fe73a93c', 'ec98b45c53a7694c4f30d09eee9ad280']
|
||||
]);
|
||||
|
||||
@@ -1391,7 +1391,8 @@ function countUpcomingTrips()
|
||||
// Open database connection
|
||||
$conn = openDatabaseConnection();
|
||||
|
||||
$query = "SELECT COUNT(*) AS trip_count FROM trips WHERE start_date > CURDATE()";
|
||||
$query = "SELECT COUNT(*) AS trip_count FROM trips WHERE published = 1 AND start_date > CURDATE()";
|
||||
|
||||
|
||||
if ($result = $conn->query($query)) {
|
||||
$row = $result->fetch_assoc();
|
||||
@@ -1783,8 +1784,8 @@ function getCommentCount($page_id) {
|
||||
$conn = openDatabaseConnection();
|
||||
|
||||
// Prepare statement to avoid SQL injection
|
||||
$stmt = $conn->prepare("SELECT COUNT(*) FROM comments WHERE page_id = ?");
|
||||
$stmt->bind_param("i", $page_id);
|
||||
$stmt = $conn->prepare("SELECT COUNT(*) FROM comments WHERE `page_id` = ?");
|
||||
$stmt->bind_param("s", $page_id);
|
||||
$stmt->execute();
|
||||
|
||||
// Get result
|
||||
|
||||
@@ -210,6 +210,8 @@ logVisitor();
|
||||
<!-- <li><a href="admin_camp_bookings.php">Camping Bookings</a></li> -->
|
||||
<!-- <li><a href="admin_payments.php">Payfast Payments</a></li> -->
|
||||
<li><a href="admin_efts.php">EFT Payments</a></li>
|
||||
<li><a href="process_payments.php">Process Payments</a></li>
|
||||
<li><a href="admin_blogs.php">Manage Blogs</a></li>
|
||||
<!-- <li><a href="bar_tabs.php">Bar</a></li> -->
|
||||
<?php if ($role === 'superadmin') { ?>
|
||||
<li><a href="admin_visitors.php">Visitor Log</a></li>
|
||||
@@ -231,6 +233,8 @@ logVisitor();
|
||||
<li><a href="account_settings.php">Account Settings</a></li>
|
||||
<li><a href="membership_details.php">Membership</a></li>
|
||||
<li><a href="bookings.php">My Bookings</a></li>
|
||||
<li><a href="user_blogs.php">My Blogs</a></li>
|
||||
<li><a href="submit_pop.php">Submit P.O.P</a></li>
|
||||
<li><a href="logout.php">Log Out</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ logVisitor();
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css">
|
||||
|
||||
<!-- Flaticon -->
|
||||
<link rel="stylesheet" href="assets/css/flaticon.min.css">
|
||||
<!-- Font Awesome -->
|
||||
@@ -223,6 +225,8 @@ logVisitor();
|
||||
<!-- <li><a href="admin_camp_bookings.php">Camping Bookings</a></li> -->
|
||||
<!-- <li><a href="admin_payments.php">Payfast Payments</a></li> -->
|
||||
<li><a href="admin_efts.php">EFT Payments</a></li>
|
||||
<li><a href="process_payments.php">Process Payments</a></li>
|
||||
<li><a href="admin_blogs.php">Manage Blogs</a></li>
|
||||
<?php if ($role === 'superadmin') { ?>
|
||||
<li><a href="admin_visitors.php">Visitor Log</a></li>
|
||||
<?php } ?>
|
||||
@@ -237,6 +241,8 @@ logVisitor();
|
||||
<li><a href="account_settings.php">Account Settings</a></li>
|
||||
<li><a href="membership_details.php">Membership</a></li>
|
||||
<li><a href="bookings.php">My Bookings</a></li>
|
||||
<li><a href="user_blogs.php">My Blogs</a></li>
|
||||
<li><a href="submit_pop.php">Submit P.O.P</a></li>
|
||||
<li><a href="logout.php">Log Out</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
20
index.php
@@ -51,7 +51,7 @@ if (!empty($bannerImages)) {
|
||||
<div style="padding-top: 50px; padding-bottom: 50px;">
|
||||
<img style="width: 250px; margin-bottom: 20px;" src="assets/images/logos/weblogo2.png" alt="Logo">
|
||||
<h1 class="hero-title" data-aos="flip-up" data-aos-delay="50" data-aos-duration="1500" data-aos-offset="50">
|
||||
Welcome to<br>the Four Wheel Drive Club<br>of Southern Africa
|
||||
Welcome to<br>the 4 Wheel Drive Club<br>of Southern Africa
|
||||
</h1>
|
||||
<a href="membership.php" class="theme-btn style-two bgc-secondary" style="margin-top: 20px; background-color: #e90000; padding: 10px 20px; color: white; text-decoration: none; border-radius: 25px;">
|
||||
<span data-hover="Become a Member">Become a Member</span>
|
||||
@@ -81,7 +81,11 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
<div class="row justify-content-center">
|
||||
<?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 ORDER BY trip_id DESC LIMIT 4";
|
||||
$sql = "SELECT trip_id, trip_name, location, short_description, start_date, end_date, vehicle_capacity, cost_members, places_booked
|
||||
FROM trips
|
||||
WHERE published = 1
|
||||
ORDER BY trip_id DESC
|
||||
LIMIT 4";
|
||||
$result = $conn->query($sql);
|
||||
|
||||
if ($result->num_rows > 0) {
|
||||
@@ -108,13 +112,13 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="location"><i class="fal fa-map-marker-alt"></i> ' . $location . '</span>
|
||||
<h5><a href="trip-details.php?trip_id=' . $trip_id . '">' . $trip_name . '</a></h5>
|
||||
<h5><a href="trip-details.php?token=' . encryptData($trip_id, $salt) . '">' . $trip_name . '</a></h5>
|
||||
<span class="time">' . convertDate($start_date) . ' - ' . convertDate($end_date) . '</span><br>
|
||||
<span class="time">' . calculateDaysAndNights($start_date, $end_date) . '</span>
|
||||
</div>
|
||||
<div class="destination-footer">
|
||||
<span class="price"><span>R ' . $cost_members . '</span>/per member</span>
|
||||
<a href="trip-details.php?trip_id=' . $trip_id . '" class="read-more">Book Now <i class="fal fa-angle-right"></i></a>
|
||||
<a href="trip-details.php?token=' . encryptData($trip_id, $salt) . '" class="read-more">Book Now <i class="fal fa-angle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
@@ -537,7 +541,7 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<?php
|
||||
$sql = "SELECT blog_id, title, date, category, image, description, author, link, members_only FROM blogs ORDER BY date DESC LIMIT 3";
|
||||
$sql = "SELECT blog_id, title, date, category, image, description, author, link, members_only FROM blogs WHERE status = 'published' ORDER BY date DESC LIMIT 3 ";
|
||||
$result = $conn->query($sql);
|
||||
|
||||
if ($result->num_rows > 0) {
|
||||
@@ -558,7 +562,7 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
$icon = "fa-lock";
|
||||
}else{
|
||||
if (getUserMemberStatus($_SESSION['user_id'])) {
|
||||
$blog_link = $row['link'];
|
||||
$blog_link = "blog_read.php?token=".encryptData($blog_id, $salt);
|
||||
$button_hover = "Read More";
|
||||
$icon = "fa-arrow-right";
|
||||
}else{
|
||||
@@ -568,7 +572,7 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$blog_link = $row['link'];
|
||||
$blog_link = "blog_read.php?token=".encryptData($blog_id, $salt);
|
||||
$button_hover = "Read More";
|
||||
$icon = "fa-arrow-right";
|
||||
}
|
||||
@@ -587,7 +591,7 @@ if (countUpcomingTrips() > 0) { ?>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="image">
|
||||
<img style="border-radius:20px;" src="assets/images/blog/' . $blog_id . '/' . $blog_image . '" alt="Blog List">
|
||||
<img style="border-radius:20px;" src="' . $blog_image . '" alt="Blog List">
|
||||
</div>
|
||||
<a style="width:100%;" href="' . $blog_link . '" class="theme-btn">
|
||||
<span style="width:100%;" data-hover="'.$button_hover.'">Read More</span>
|
||||
|
||||
280
member_info.php
Normal file
@@ -0,0 +1,280 @@
|
||||
<?php
|
||||
include_once('header02.php');
|
||||
checkAdmin();
|
||||
if (!isset($_GET['token']) || empty($_GET['token'])) {
|
||||
die("Invalid request.");
|
||||
}
|
||||
$token = $_GET['token'];
|
||||
// echo $token;
|
||||
|
||||
// Use ?user_id=... in the URL to view another user's info
|
||||
$viewing_user_id = isset($_GET['token']) ? decryptData($token, $salt) : $_SESSION['user_id'];
|
||||
checkMembershipApplication2($viewing_user_id);
|
||||
|
||||
// Fetch membership details
|
||||
$sql = "SELECT membership_start_date, membership_end_date, payment_status, payment_amount, payment_id FROM membership_fees WHERE user_id = ?";
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bind_param("i", $viewing_user_id);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$membership = $result->fetch_assoc();
|
||||
|
||||
// Fetch application data
|
||||
$query = "SELECT * FROM membership_application WHERE user_id = ?";
|
||||
$stmt = $conn->prepare($query);
|
||||
$stmt->bind_param("i", $viewing_user_id);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$application = $result->fetch_assoc();
|
||||
$stmt->close();
|
||||
?>
|
||||
<style>
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
thead th {
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
padding: 10px;
|
||||
font-weight: bold;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
thead th::after {
|
||||
content: '\25B2';
|
||||
/* Up arrow */
|
||||
font-size: 0.8em;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
thead th.asc::after {
|
||||
content: '\25B2';
|
||||
/* Up arrow */
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
thead th.desc::after {
|
||||
content: '\25BC';
|
||||
/* Down arrow */
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
tbody tr:nth-child(odd) {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
tbody tr:nth-child(even) {
|
||||
background-color: rgb(255, 255, 255);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
tbody td {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
tbody tr:nth-child(even) td:first-child {
|
||||
border-top-left-radius: 10px;
|
||||
border-bottom-left-radius: 10px;
|
||||
}
|
||||
|
||||
tbody tr:nth-child(even) td:last-child {
|
||||
border-top-right-radius: 10px;
|
||||
border-bottom-right-radius: 10px;
|
||||
}
|
||||
</style>
|
||||
<section class="account-settings-area py-70 rel z-1">
|
||||
<div class="container">
|
||||
<button onclick="downloadMembershipPDF()">📄 Open as PDF</button>
|
||||
|
||||
|
||||
<div class="row align-items-center">
|
||||
<div class="col-lg-12">
|
||||
<div class="comment-form bgc-lighter z-1 rel mb-30 rmb-55">
|
||||
<div id="membership-info">
|
||||
<div class="section-title py-20">
|
||||
<h2>Member Information: <?php echo getFullName($viewing_user_id); ?></h2>
|
||||
</div>
|
||||
|
||||
<div style='padding:10px;'>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Start Date</th>
|
||||
<th>Renewal Date</th>
|
||||
<th>Indemnity</th>
|
||||
<th>Amount</th>
|
||||
<th>Payment Reference</th>
|
||||
<th>Payment Status</th>
|
||||
<th>Membership Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if ($membership): ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($membership['membership_start_date']); ?></td>
|
||||
<td><?php echo htmlspecialchars($membership['membership_end_date']); ?></td>
|
||||
<td><?php echo hasAcceptedIndemnity($viewing_user_id) ? 'SIGNED' : 'NOT SIGNED'; ?></td>
|
||||
<td><?php echo htmlspecialchars($membership['payment_amount']); ?></td>
|
||||
<td><?php echo htmlspecialchars($membership['payment_id']); ?></td>
|
||||
<td><?php echo htmlspecialchars($membership['payment_status']); ?></td>
|
||||
<td><?php echo getUserMemberStatus($viewing_user_id) ? 'ACTIVE' : 'INACTIVE'; ?></td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
<tr>
|
||||
<td colspan="7">No membership records found.</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h3>Main Member</h3>
|
||||
<div class="row mt-35">
|
||||
<?php
|
||||
$fields = [
|
||||
'first_name' => 'First Name',
|
||||
'last_name' => 'Surname',
|
||||
'id_number' => 'ID Number / Passport Number',
|
||||
'dob' => 'Date of Birth',
|
||||
'occupation' => 'Occupation',
|
||||
'tel_cell' => 'Cell Phone',
|
||||
'email' => 'Email Address'
|
||||
];
|
||||
foreach ($fields as $key => $label): ?>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label><?php echo $label; ?></label>
|
||||
<p class="form-control-static"><?php echo htmlspecialchars($application[$key] ?? ''); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<h3>Spouse / Life Partner / Other Details</h3>
|
||||
<div class="row mt-35">
|
||||
<?php
|
||||
$spouse_fields = [
|
||||
'spouse_first_name' => 'First Name',
|
||||
'spouse_last_name' => 'Surname',
|
||||
'spouse_id_number' => 'ID Number / Passport Number',
|
||||
'spouse_dob' => 'Date of Birth',
|
||||
'spouse_occupation' => 'Occupation',
|
||||
'spouse_tel_cell' => 'Cell Phone',
|
||||
'spouse_email' => 'Email Address'
|
||||
];
|
||||
foreach ($spouse_fields as $key => $label): ?>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label><?php echo $label; ?></label>
|
||||
<p class="form-control-static"><?php echo htmlspecialchars($application[$key] ?? ''); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<h3>Children's Names</h3>
|
||||
<div class="row mt-35">
|
||||
<?php for ($i = 1; $i <= 3; $i++): ?>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>Child <?php echo $i; ?> Name</label>
|
||||
<p class="form-control-static"><?php echo htmlspecialchars($application['child_name' . $i] ?? ''); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>Child <?php echo $i; ?> DOB</label>
|
||||
<p class="form-control-static"><?php echo htmlspecialchars($application['child_dob' . $i] ?? ''); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php endfor; ?>
|
||||
</div>
|
||||
|
||||
<h3>Address</h3>
|
||||
<div class="row mt-35">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>Physical Address</label>
|
||||
<p class="form-control-static"><?php echo nl2br(htmlspecialchars($application['physical_address'] ?? '')); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>Postal Address</label>
|
||||
<p class="form-control-static"><?php echo nl2br(htmlspecialchars($application['postal_address'] ?? '')); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Interests and Hobbies</h3>
|
||||
<div class="row mt-35">
|
||||
<div class="col-md-12">
|
||||
<div class="form-group">
|
||||
<p class="form-control-static"><?php echo nl2br(htmlspecialchars($application['interests_hobbies'] ?? '')); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Primary Vehicle</h3>
|
||||
<div class="row mt-35">
|
||||
<?php
|
||||
$vehicle_fields = [
|
||||
'vehicle_make' => 'Make',
|
||||
'vehicle_model' => 'Model',
|
||||
'vehicle_year' => 'Year',
|
||||
'vehicle_registration' => 'Registration'
|
||||
];
|
||||
foreach ($vehicle_fields as $key => $label): ?>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label><?php echo $label; ?></label>
|
||||
<p class="form-control-static"><?php echo htmlspecialchars($application[$key] ?? ''); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<!-- You can add secondary vehicle and other custom sections in the same way -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
|
||||
|
||||
<script>
|
||||
function downloadMembershipPDF() {
|
||||
const element = document.getElementById('membership-info');
|
||||
|
||||
// Temporarily shrink element for PDF
|
||||
element.style.transform = 'scale(0.8)';
|
||||
element.style.transformOrigin = 'top left';
|
||||
|
||||
const opt = {
|
||||
margin: 0.5,
|
||||
filename: 'membership-info.pdf',
|
||||
image: { type: 'jpeg', quality: 0.98 },
|
||||
html2canvas: { scale: 2 },
|
||||
jsPDF: { unit: 'in', format: 'a4', orientation: 'portrait' }
|
||||
};
|
||||
|
||||
html2pdf().from(element).set(opt).outputPdf('bloburl').then((pdfUrl) => {
|
||||
window.open(pdfUrl, '_blank');
|
||||
// Restore original size
|
||||
element.style.transform = '';
|
||||
element.style.transformOrigin = '';
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
@@ -105,9 +105,13 @@ if (!empty($bannerImages)) {
|
||||
<?php echo
|
||||
'<h5>Membership Start Date: ' . $membership_start_date . '<br>Membership Renewal Date: ' . $membership_end_date . '</h5>'; ?>
|
||||
</div>
|
||||
<p>Your invoice has been sent to <b><?php echo htmlspecialchars($user_email); ?></b>. Please send your proof of payment to <b>info@4wdcsa.co.za</b>.</p>
|
||||
<p>Your invoice has been sent to <b><?php echo htmlspecialchars($user_email); ?></b>. Please upload your proof of payment below.</p>
|
||||
<h5>Payment Details:</h5>
|
||||
<p>The Four Wheel Drive Club of Southern Africa<br>FNB<br>Account Number: 58810022334<br>Branch code: 250655<br>Reference: <?php echo htmlspecialchars($eft_id); ?><br>Amount: R <?php echo number_format($payment_amount, 2); ?></p>
|
||||
<a href="submit_pop.php" class="theme-btn style-two style-three" style="width:100%;">
|
||||
<span data-hover="Submit Proof of Payment">Submit Proof of Payment</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-6" data-aos="fade-right" data-aos-duration="1500" data-aos-offset="50">
|
||||
|
||||
@@ -131,10 +131,14 @@ if (!empty($bannerImages)) {
|
||||
|
||||
|
||||
</div>
|
||||
<p>Your invoice has been sent to <b><?php echo htmlspecialchars($user_email); ?></b>. Please send your proof of payment to <b>info@4wdcsa.co.za</b>.</p>
|
||||
<p>Bookings not paid for within 24 hours will be forfeited.</p>
|
||||
<p>Your invoice has been sent to <b><?php echo htmlspecialchars($user_email); ?></b>. Please upload your proof of payment below.</p>
|
||||
<!-- <p>Bookings not paid for within 24 hours will be forfeited.</p> -->
|
||||
<h5>Payment Details:</h5>
|
||||
<p>The Four Wheel Drive Club of Southern Africa<br>FNB<br>Account Number: 58810022334<br>Branch code: 250655<br>Reference: <?php echo htmlspecialchars($eft_id); ?><br>Amount: R <?php echo number_format($payment_amount, 2); ?></p>
|
||||
<a href="submit_pop.php" class="theme-btn style-two style-three" style="width:100%;">
|
||||
<span data-hover="Submit Proof of Payment">Submit Proof of Payment</span>
|
||||
<i class="fal fa-arrow-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
3
phpinfo.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
echo phpinfo();
|
||||
149
process_payments.php
Normal file
@@ -0,0 +1,149 @@
|
||||
<?php include_once('header02.php');
|
||||
checkAdmin();
|
||||
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
|
||||
$status = "PROCESSING";
|
||||
$bannerFolder = 'assets/images/banners/';
|
||||
$bannerImages = glob($bannerFolder . '*.{jpg,jpeg,png,webp}', GLOB_BRACE);
|
||||
|
||||
$randomBanner = 'assets/images/base4/camping.jpg'; // default fallback
|
||||
if (!empty($bannerImages)) {
|
||||
$randomBanner = $bannerImages[array_rand($bannerImages)];
|
||||
}
|
||||
?>
|
||||
<section class="page-banner-area pt-50 pb-35 rel z-1 bgs-cover" style="background-image: url('<?php echo $randomBanner; ?>');">
|
||||
<div class="banner-overlay"></div>
|
||||
<div class="container">
|
||||
<div class="banner-inner text-white mb-50">
|
||||
<h2 class="page-title mb-10" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">Process Payments</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.php">Home</a></li>
|
||||
<li class="breadcrumb-item active">Process Payments</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 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; ?>
|
||||
<?php
|
||||
// Query to retrieve data from the bookings table
|
||||
$sql = "SELECT * FROM efts WHERE status = ? ORDER BY timestamp DESC";
|
||||
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bind_param("s", $status);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
if ($result->num_rows > 0) {
|
||||
// Loop through each row
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$eft_id = $row['eft_id'];
|
||||
$file_name = str_replace(' ', '_', $eft_id);
|
||||
$eft_user = $row['user_id'];
|
||||
$eft_amount = $row['amount'];
|
||||
$eft_description = $row['description'];
|
||||
|
||||
// Output the HTML structure with dynamic data
|
||||
echo '
|
||||
<div class="destination-item style-three bgc-lighter booking " data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="p-4" >
|
||||
<iframe src="uploads/pop/'.$file_name.'.pdf#toolbar=0" width="400px" height="200px"></iframe>
|
||||
<p><a href="uploads/pop/'.$file_name.'.pdf" target="_new" class="theme-btn style-three" style="width:100%;">View Full PDF</a></p>
|
||||
|
||||
</div>
|
||||
<div style="width:100%;" class="content">
|
||||
<h5>' . htmlspecialchars($eft_description) . '</a></h5>
|
||||
<h5>' . getFullName($eft_user) . '</a></h5>
|
||||
<div class="destination-footer">
|
||||
<span class="price"><span>Booking Total: R ' . number_format($eft_amount, 2) . '</span></span>
|
||||
<a href="process_eft.php?token=' . encryptData($eft_id, $salt) . '" class="theme-btn style-three"><span data-hover="POP RECEIVED">PROCESS</span></a>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
} else {
|
||||
echo '<p>There are no pending payments for processing.</p>';
|
||||
}
|
||||
// Close connection
|
||||
$conn->close();
|
||||
?>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Tour List Area end -->
|
||||
|
||||
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
@@ -34,9 +34,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$num_vehicles = isset($_POST['vehicles']) ? intval($_POST['vehicles']) : 1; // Default to 1 vehicle
|
||||
$num_adults = isset($_POST['adults']) ? intval($_POST['adults']) : 1; // Default to 1 adult
|
||||
$num_children = isset($_POST['children']) ? intval($_POST['children']) : 0; // Default to 0 children
|
||||
$radio = isset($_POST['AddExtra']) ? 1 : 0; // Checkbox for extras
|
||||
$num_pensioners = isset($_POST['pensioners']) ? intval($_POST['pensioners']) : 0; // Default to 0 pensioners
|
||||
// $radio = isset($_POST['AddExtra']) ? 1 : 0; // Checkbox for extras
|
||||
// Fetch trip costs from the database
|
||||
$query = "SELECT trip_name, cost_members, cost_nonmembers, booking_fee, start_date, end_date, trip_code FROM trips WHERE trip_id = ?";
|
||||
$query = "SELECT trip_name, cost_members, cost_nonmembers, cost_pensioner_member, cost_pensioner, booking_fee, start_date, end_date, trip_code FROM trips WHERE trip_id = ?";
|
||||
$stmt = $conn->prepare($query);
|
||||
$stmt->bind_param('i', $trip_id);
|
||||
$stmt->execute();
|
||||
@@ -56,7 +57,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$trip_name = $trip['trip_name'];
|
||||
$cost_members = intval($trip['cost_members']);
|
||||
$cost_nonmembers = intval($trip['cost_nonmembers']);
|
||||
$cost_pensioner_member = intval($trip['cost_pensioner_member']);
|
||||
$cost_pensioner = intval($trip['cost_pensioner']);
|
||||
$member_discount = $cost_nonmembers - $cost_members;
|
||||
$member_discount_pensioner = $cost_pensioner - $cost_pensioner_member;
|
||||
$booking_fee = $trip['booking_fee'];
|
||||
$radioCost = $radio ? 50 : 0;
|
||||
$start_date = $trip['start_date']; // Start date of the trip
|
||||
@@ -72,11 +76,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
||||
// Calculate total based on membership
|
||||
if ($is_member) {
|
||||
$total = (($num_adults + $num_children) * $cost_nonmembers) + $radioCost + ($num_vehicles * $booking_fee);
|
||||
$discountAmount = ($num_adults + $num_children) * $member_discount;
|
||||
$total = (($num_adults + $num_children) * $cost_nonmembers) + ($num_pensioners * $cost_pensioner) + $radioCost + ($num_vehicles * $booking_fee);
|
||||
$discountAmount = (($num_adults + $num_children) * $member_discount) + ($num_pensioners * $member_discount_pensioner );
|
||||
$payment_amount = $total - $discountAmount;
|
||||
} else {
|
||||
$total = (($num_adults + $num_children) * $cost_nonmembers) + $radioCost + ($num_vehicles * $booking_fee);
|
||||
$total = (($num_adults + $num_children) * $cost_nonmembers) + ($num_pensioners * $cost_pensioner) + $radioCost + ($num_vehicles * $booking_fee);
|
||||
$payment_amount = $total;
|
||||
}
|
||||
|
||||
@@ -85,19 +89,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$type = 'trip';
|
||||
$payment_id = uniqid();
|
||||
// $eft_id = strtoupper(base_convert(time(), 10, 36)); // Convert timestamp to base36
|
||||
$eft_id = strtoupper($trip_code." ".getLastName($user_id));
|
||||
$eft_id = strtoupper($trip_code." ".getInitialSurname($user_id));
|
||||
|
||||
|
||||
// Insert booking into the database
|
||||
$sql = "INSERT INTO bookings (booking_type, user_id, from_date, to_date, num_vehicles, num_adults, num_children, total_amount, discount_amount, status, payment_id, trip_id, radio, eft_id)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
$sql = "INSERT INTO bookings (booking_type, user_id, from_date, to_date, num_vehicles, num_adults, num_children, total_amount, discount_amount, status, payment_id, trip_id, radio, eft_id, num_pensioners)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
$stmt = $conn->prepare($sql);
|
||||
|
||||
if (!$stmt) {
|
||||
die("Preparation failed: " . $conn->error);
|
||||
}
|
||||
|
||||
$stmt->bind_param('sissiiiddssiis', $type, $user_id, $start_date, $end_date, $num_vehicles, $num_adults, $num_children, $total, $discountAmount, $status, $payment_id, $trip_id, $radio, $eft_id);
|
||||
$stmt->bind_param('sissiiiddssiisi', $type, $user_id, $start_date, $end_date, $num_vehicles, $num_adults, $num_children, $total, $discountAmount, $status, $payment_id, $trip_id, $radio, $eft_id, $num_pensioners);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
// Get the generated booking_id
|
||||
|
||||
31
publish_blog.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
require_once("env.php");
|
||||
require_once("session.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
http_response_code(401);
|
||||
echo "Not authorized";
|
||||
exit;
|
||||
}
|
||||
|
||||
$article_id = (int)($_POST['id'] ?? 0);
|
||||
$user_id = $_SESSION['user_id'];
|
||||
|
||||
if ($article_id <= 0) {
|
||||
http_response_code(400);
|
||||
echo "Invalid blog ID";
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = $conn->prepare("UPDATE blogs SET status = 'published' WHERE blog_id = ? AND author = ?");
|
||||
$stmt->bind_param("ii", $article_id, $user_id);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
echo "Published";
|
||||
} else {
|
||||
http_response_code(500);
|
||||
echo "Failed to publish: " . $stmt->error;
|
||||
}
|
||||
?>
|
||||
24
submit_blog.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once("env.php");
|
||||
require_once("session.php");
|
||||
require_once("connection.php");
|
||||
require_once("functions.php");
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
die("Login required");
|
||||
}
|
||||
|
||||
$title = $_POST['title'];
|
||||
$category = $_POST['category'];
|
||||
$description = $_POST['description'];
|
||||
$content = $_POST['content'];
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$date = date('Y-m-d');
|
||||
|
||||
|
||||
$stmt = $conn->prepare("INSERT INTO blogs (author, title, content, description, category, date) VALUES (?, ?, ?, ?, ?, ?)");
|
||||
$stmt->bind_param("isssss", $user_id, $title, $content, $description, $category, $date);
|
||||
$stmt->execute();
|
||||
|
||||
header("Location: blog.php");
|
||||
219
submit_pop.php
Normal file
@@ -0,0 +1,219 @@
|
||||
<?php include_once('header02.php');
|
||||
checkUserSession();
|
||||
|
||||
$user_id = $_SESSION['user_id'] ?? null;
|
||||
|
||||
if (!$user_id) {
|
||||
die("Not logged in.");
|
||||
}
|
||||
|
||||
// Handle POST submission
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$eft_id = $_POST['eft_id'] ?? null;
|
||||
$file_name = str_replace(' ', '_', $eft_id);
|
||||
|
||||
|
||||
if (!$eft_id || !isset($_FILES['pop_file'])) {
|
||||
echo "<div class='alert alert-danger'>Invalid submission: missing eft_id or file.</div>";
|
||||
echo "<pre>";
|
||||
echo "POST data: " . print_r($_POST, true);
|
||||
echo "FILES data: " . print_r($_FILES, true);
|
||||
echo "</pre>";
|
||||
} else {
|
||||
$file = $_FILES['pop_file'];
|
||||
$target_dir = "uploads/pop/";
|
||||
$target_file = $target_dir . $file_name . ".pdf";
|
||||
|
||||
// Check for upload errors first
|
||||
if ($file['error'] !== UPLOAD_ERR_OK) {
|
||||
echo "<div class='alert alert-danger'>Upload error code: " . $file['error'] . "</div>";
|
||||
// You can decode error code if needed:
|
||||
// https://www.php.net/manual/en/features.file-upload.errors.php
|
||||
exit;
|
||||
}
|
||||
|
||||
// Check for PDF extension
|
||||
$file_type = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
|
||||
if ($file_type !== "pdf") {
|
||||
echo "<div class='alert alert-danger'>Only PDF files allowed. You tried uploading: .$file_type</div>";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Make sure target directory exists and writable
|
||||
if (!is_dir($target_dir)) {
|
||||
echo "<div class='alert alert-danger'>Upload directory does not exist: $target_dir</div>";
|
||||
exit;
|
||||
}
|
||||
if (!is_writable($target_dir)) {
|
||||
echo "<div class='alert alert-danger'>Upload directory is not writable: $target_dir</div>";
|
||||
exit;
|
||||
}
|
||||
|
||||
if (move_uploaded_file($file['tmp_name'], $target_file)) {
|
||||
// Update EFT and booking status
|
||||
$payment_type = $_POST['payment_type'] ?? 'booking';
|
||||
|
||||
if ($payment_type === 'membership') {
|
||||
// Update EFT and booking status
|
||||
$stmt1 = $conn->prepare("UPDATE efts SET status = 'PROCESSING' WHERE eft_id = ?");
|
||||
$stmt1->bind_param("s", $eft_id);
|
||||
$stmt1->execute();
|
||||
// Update membership fee status
|
||||
$stmt = $conn->prepare("UPDATE membership_fees SET payment_status = 'PROCESSING' WHERE payment_id = ?");
|
||||
$stmt->bind_param("s", $eft_id);
|
||||
$stmt->execute();
|
||||
} else {
|
||||
// Update EFT and booking status
|
||||
$stmt1 = $conn->prepare("UPDATE efts SET status = 'PROCESSING' WHERE eft_id = ?");
|
||||
$stmt1->bind_param("s", $eft_id);
|
||||
$stmt1->execute();
|
||||
|
||||
$stmt2 = $conn->prepare("UPDATE bookings SET status = 'PROCESSING' WHERE eft_id = ?");
|
||||
$stmt2->bind_param("s", $eft_id);
|
||||
$stmt2->execute();
|
||||
}
|
||||
|
||||
// Notify n8n and send the path to the uploaded file
|
||||
$webhook_url = 'https://n8n.4wdcsa.co.za/webhook/process-pop';
|
||||
|
||||
$postData = [
|
||||
'eft_id' => $eft_id,
|
||||
'payment_type' => $payment_type,
|
||||
];
|
||||
|
||||
$ch = curl_init($webhook_url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json'
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$error = curl_error($ch);
|
||||
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
if ($error) {
|
||||
error_log("Webhook Error: $error");
|
||||
$_SESSION['message'] = $error;
|
||||
header("Location: bookings.php");
|
||||
} else {
|
||||
$_SESSION['message'] = "Thank you! We are busy processing your payment!";
|
||||
header("Location: bookings.php");
|
||||
}
|
||||
|
||||
exit;
|
||||
} else {
|
||||
echo "<div class='alert alert-danger'>Unable to move uploaded file.</div>";
|
||||
echo "<pre>Tmp file exists? " . (file_exists($file['tmp_name']) ? "Yes" : "No") . "</pre>";
|
||||
echo "<pre>Tmp file path: " . htmlspecialchars($file['tmp_name']) . "</pre>";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Fetch bookings for dropdown
|
||||
$stmt = $conn->prepare("
|
||||
SELECT eft_id AS id, 'booking' AS type FROM bookings WHERE user_id = ? AND status = 'AWAITING PAYMENT'
|
||||
UNION
|
||||
SELECT payment_id AS id, 'membership' AS type FROM membership_fees WHERE user_id = ? AND payment_status = 'PENDING'
|
||||
");
|
||||
$stmt->bind_param("ii", $user_id, $user_id);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$items = $result->fetch_all(MYSQLI_ASSOC);
|
||||
|
||||
|
||||
|
||||
|
||||
$bannerFolder = 'assets/images/banners/';
|
||||
$bannerImages = glob($bannerFolder . '*.{jpg,jpeg,png,webp}', GLOB_BRACE);
|
||||
|
||||
$randomBanner = 'assets/images/base4/camping.jpg'; // default fallback
|
||||
if (!empty($bannerImages)) {
|
||||
$randomBanner = $bannerImages[array_rand($bannerImages)];
|
||||
}
|
||||
?>
|
||||
<section class="page-banner-area pt-50 pb-35 rel z-1 bgs-cover" style="background-image: url('<?php echo $randomBanner; ?>');">
|
||||
<div class="banner-overlay"></div>
|
||||
<div class="container">
|
||||
<div class="banner-inner text-white mb-50">
|
||||
<h2 class="page-title mb-10" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">Submit Proof of Payment</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.php">Home</a></li>
|
||||
<li class="breadcrumb-item active">Submit Proof of Payment</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Tour List Area start -->
|
||||
<section class="tour-list-page py-100 rel z-1">
|
||||
<div class="container" style="max-width:600px;">
|
||||
<div class="row">
|
||||
<div class="comment-form bgc-lighter z-1 rel mb-30 rmb-55" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="widget widget-booking" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="section-title">
|
||||
<h3>Submit Proof of Payment</h3>
|
||||
<div style="text-align: center;" id="responseMessage"></div>
|
||||
<p>To finalise your booking/membership, select the payment reference below, and then upload your PDF proof of payment.</p> <!-- Message display area -->
|
||||
</div>
|
||||
<?php if (count($items) > 0) {?>
|
||||
|
||||
<form enctype="multipart/form-data" method="POST">
|
||||
|
||||
<div class="row mt-35">
|
||||
<ul class="tickets clearfix">
|
||||
<li>
|
||||
Select Payment Reference:
|
||||
<select name="eft_id" id="eft_id" required onchange="updatePaymentType(this)">
|
||||
<?php
|
||||
if (count($items) > 0) {
|
||||
foreach ($items as $item) {
|
||||
$label = strtoupper($item['type']) . ' - ' . htmlspecialchars($item['id']);
|
||||
echo '<option value="' . htmlspecialchars($item['id']) . '" data-type="' . $item['type'] . '">' . $label . '</option>';
|
||||
}
|
||||
} else {
|
||||
echo '<option value="" disabled selected>No payments available</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<input type="hidden" name="payment_type" id="payment_type">
|
||||
</li>
|
||||
</ul>
|
||||
<li>
|
||||
<input style="border-radius:30px;" type="file" name="pop_file" id="pop_file" accept="application/pdf" class="form-control" required>
|
||||
</li>
|
||||
</div>
|
||||
<div class="mt-10 mb-0">
|
||||
<button type="submit" class="theme-btn style-two" style="width:100%;">Submit POP</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<?php
|
||||
}else{
|
||||
echo 'No unpaid bookings';
|
||||
}?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
function updatePaymentType(selectEl) {
|
||||
const selectedOption = selectEl.options[selectEl.selectedIndex];
|
||||
const type = selectedOption.getAttribute('data-type');
|
||||
document.getElementById('payment_type').value = type;
|
||||
}
|
||||
window.onload = function() {
|
||||
const dropdown = document.getElementById('eft_id');
|
||||
updatePaymentType(dropdown); // set default value on page load
|
||||
};
|
||||
</script>
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||
212
trip-details.php
@@ -12,7 +12,7 @@ $trip_id = intval(decryptData($token, $salt)); // Ensures $trip_id is treated as
|
||||
|
||||
// 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
|
||||
vehicle_capacity, cost_members, cost_nonmembers, places_booked, booking_fee, cost_pensioner, cost_pensioner_member
|
||||
FROM trips
|
||||
WHERE trip_id = ?";
|
||||
|
||||
@@ -45,7 +45,10 @@ if ($stmt) {
|
||||
$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);
|
||||
@@ -145,25 +148,52 @@ $conn->close();
|
||||
/* Optional: makes non-member price stand out */
|
||||
}
|
||||
</style>
|
||||
<!-- Page Banner Start -->
|
||||
<section class="page-banner-two rel z-1">
|
||||
<div class="container-fluid">
|
||||
<hr class="mt-0">
|
||||
<div class="container">
|
||||
<div class="banner-inner pt-15 pb-25">
|
||||
<h2 class="page-title mb-10" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50"><?php echo $trip_name; ?></h2>
|
||||
<div class="banner-overlay"></div>
|
||||
<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.html">Home</a></li>
|
||||
<li class="breadcrumb-item active">Tour Details</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
<?php include_once('header02.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.php">Home</a></li>
|
||||
<li class="breadcrumb-item active">4WDCSA Trips</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Page Banner End -->
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Tour Gallery start -->
|
||||
@@ -215,23 +245,23 @@ $conn->close();
|
||||
<div class="section-title pb-5">
|
||||
<h2><?php echo $trip_name; ?></h2>
|
||||
</div>
|
||||
<div class="ratting">
|
||||
<!-- <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> -->
|
||||
|
||||
</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="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> -->
|
||||
</div>
|
||||
<hr class="mt-50 mb-70">
|
||||
</div>
|
||||
@@ -263,7 +293,7 @@ $conn->close();
|
||||
<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="row pb-55">
|
||||
<div class="col-md-6">
|
||||
<div class="tour-include-exclude mt-30">
|
||||
<h5>Included and Excluded</h5>
|
||||
@@ -290,10 +320,10 @@ $conn->close();
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
<h3>Activities</h3>
|
||||
<!-- <h3>Activities</h3>
|
||||
<div class="tour-activities mt-30 mb-45">
|
||||
<div class="tour-activity-item">
|
||||
<i class="flaticon-hiking"></i>
|
||||
@@ -327,9 +357,9 @@ $conn->close();
|
||||
<i class="flaticon-meditation"></i>
|
||||
<b>Yoga</b>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<h3>Itinerary</h3>
|
||||
<!-- <h3>Itinerary</h3>
|
||||
<div class="accordion-two mt-25 mb-60" id="faq-accordion-two">
|
||||
<div class="accordion-item">
|
||||
<h5 class="accordion-header">
|
||||
@@ -391,11 +421,11 @@ $conn->close();
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<h3>Maps</h3>
|
||||
<!-- <h3>Maps</h3> -->
|
||||
<div class="tour-map mt-30 mb-50">
|
||||
<iframe src="https://www.google.com/maps/embed?pb=!1m10!1m8!1m3!1d96777.16150026117!2d-74.00840582560909!3d40.71171357405996!3m2!1i1024!2i768!4f13.1!5e0!3m2!1sen!2sbd!4v1706508986625!5m2!1sen!2sbd" style="border:0; width: 100%;" allowfullscreen="" loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe>
|
||||
<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>
|
||||
@@ -430,6 +460,7 @@ $conn->close();
|
||||
<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>
|
||||
@@ -446,15 +477,24 @@ $conn->close();
|
||||
<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 Handheld Radio Rental <span>R 50,00</span></label>
|
||||
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>
|
||||
|
||||
@@ -474,6 +514,34 @@ $conn->close();
|
||||
<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>
|
||||
<?php if ($remaining_places < 1): ?>
|
||||
<button type="button" class="theme-btn style-two w-100 mt-15 mb-5" disabled>
|
||||
@@ -487,7 +555,7 @@ $conn->close();
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<div class="text-center">
|
||||
<a href="contact.html">Need some help?</a> | Payments will be redirected to Payfast.
|
||||
<a href="contact.php">Need some help?</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -498,12 +566,12 @@ $conn->close();
|
||||
<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:4wdcsa@gmail.com">4wdcsa@gmail.com</a></li>
|
||||
<li><i class="far fa-phone-volume"></i> <a href="#">+27 </a></li>
|
||||
<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="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>
|
||||
@@ -516,7 +584,7 @@ $conn->close();
|
||||
<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>
|
||||
@@ -528,40 +596,65 @@ $conn->close();
|
||||
|
||||
<!-- 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()) || 1; // Default to 1 adult 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
|
||||
var isMember = <?php echo $is_member ? 'true' : 'false'; ?>;
|
||||
var cost_members = <?php echo $cost_members; ?>;
|
||||
var cost_nonmembers = <?php echo $cost_nonmembers; ?>;
|
||||
var member_discount = <?php echo $member_discount; ?>;
|
||||
var booking_fee = <?php echo $booking_fee; ?>;
|
||||
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
|
||||
var total = 0;
|
||||
var discountAmount = 0;
|
||||
let total = 0;
|
||||
let discountAmount = 0;
|
||||
|
||||
// Calculate cost for members
|
||||
if (isMember) {
|
||||
total = ((adults + children) * cost_members) + radio + (vehicles * booking_fee);
|
||||
discountAmount = ((adults + children) * member_discount); // Member discount
|
||||
total = ((adults + children) * cost_members) + (pensioners * cost_pensioner_member) + radio + (vehicles * booking_fee);
|
||||
discountAmount = ((adults + children) * member_discount) + (pensioners * member_discount_pensioner);
|
||||
} else {
|
||||
// Calculate cost for non-members
|
||||
total = ((adults + children) * cost_nonmembers) + radio + (vehicles * booking_fee);
|
||||
total = ((adults + children) * cost_nonmembers) + (pensioners * cost_pensioner) + radio + (vehicles * booking_fee);
|
||||
}
|
||||
|
||||
// Update total price in the DOM
|
||||
$('#booking_total').text('R ' + total.toFixed(2));
|
||||
|
||||
// If the user is a member, show the discount section
|
||||
if (isMember) {
|
||||
$('#discount_amount').text('R ' + discountAmount.toFixed(2));
|
||||
$('#discount_section').show();
|
||||
@@ -570,12 +663,7 @@ $conn->close();
|
||||
}
|
||||
}
|
||||
|
||||
// Event listeners to trigger recalculation when any form field changes
|
||||
$('#vehicles, #adults, #children, #add-extra1').on('change', function() {
|
||||
calculateTotal();
|
||||
});
|
||||
|
||||
// Initial calculation on page load
|
||||
$('#vehicles, #adults, #children, #pensioners, #add-extra1').on('change', calculateTotal);
|
||||
calculateTotal();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -80,7 +80,7 @@ if (!empty($bannerImages)) {
|
||||
|
||||
|
||||
// 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 start_date > CURDATE()";
|
||||
$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) {
|
||||
|
||||
27
upload.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$blog_id = $_GET['blog_id'] ?? null;
|
||||
|
||||
|
||||
if (!isset($_FILES['file'])) {
|
||||
echo json_encode(['error' => 'No file uploaded']);
|
||||
http_response_code(400);
|
||||
exit;
|
||||
}
|
||||
|
||||
$targetDir = "uploads/blogs/".$blog_id."/images/";
|
||||
if (!file_exists($targetDir)) {
|
||||
mkdir($targetDir, 0777, true);
|
||||
}
|
||||
|
||||
$tmp = $_FILES['file']['tmp_name'];
|
||||
$name = basename($_FILES['file']['name']);
|
||||
$targetFile = $targetDir . uniqid() . "-" . $name;
|
||||
|
||||
if (move_uploaded_file($tmp, $targetFile)) {
|
||||
echo json_encode(['location' => $targetFile]);
|
||||
} else {
|
||||
echo json_encode(['error' => 'Failed to move uploaded file']);
|
||||
http_response_code(500);
|
||||
}
|
||||
24
upload_blog_image.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (!isset($_FILES['file'])) {
|
||||
echo json_encode(['error' => 'No file uploaded']);
|
||||
http_response_code(400);
|
||||
exit;
|
||||
}
|
||||
|
||||
$targetDir = "uploads/blogs/images/";
|
||||
if (!file_exists($targetDir)) {
|
||||
mkdir($targetDir, 0777, true);
|
||||
}
|
||||
|
||||
$tmp = $_FILES['file']['tmp_name'];
|
||||
$name = basename($_FILES['file']['name']);
|
||||
$targetFile = $targetDir . uniqid() . "-" . $name;
|
||||
|
||||
if (move_uploaded_file($tmp, $targetFile)) {
|
||||
echo json_encode(['location' => $targetFile]);
|
||||
} else {
|
||||
echo json_encode(['error' => 'Failed to move uploaded file']);
|
||||
http_response_code(500);
|
||||
}
|
||||
0
upload_debug.log
Normal file
124
user_blogs.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php include_once('header02.php');
|
||||
|
||||
checkUserSession();
|
||||
|
||||
$result = $conn->prepare("SELECT blog_id, title, description, status, date, image FROM blogs WHERE author = ? AND status != 'deleted' ORDER BY date DESC");
|
||||
|
||||
$result->bind_param("i", $user_id);
|
||||
$result->execute();
|
||||
$posts = $result->get_result();
|
||||
?>
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
<?php
|
||||
$bannerFolder = 'assets/images/banners/';
|
||||
$bannerImages = glob($bannerFolder . '*.{jpg,jpeg,png,webp}', GLOB_BRACE);
|
||||
|
||||
$randomBanner = 'assets/images/base4/camping.jpg'; // default fallback
|
||||
if (!empty($bannerImages)) {
|
||||
$randomBanner = $bannerImages[array_rand($bannerImages)];
|
||||
}
|
||||
?>
|
||||
<section class="page-banner-area pt-50 pb-35 rel z-1 bgs-cover" style="background-image: url('<?php echo $randomBanner; ?>');">
|
||||
<!-- Overlay PNG -->
|
||||
<div class="banner-overlay"></div>
|
||||
<div class="container">
|
||||
<div class="banner-inner text-white">
|
||||
<h2 class="page-title mb-10" data-aos="fade-left" data-aos-duration="1500" data-aos-offset="50">My Blogs</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.php">Home</a></li>
|
||||
<li class="breadcrumb-item active">My Blogs</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Page Banner End -->
|
||||
|
||||
|
||||
|
||||
<!-- Blog List Area start -->
|
||||
<section class="blog-list-page py-100 rel z-1">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
|
||||
<h2>My Posts</h2>
|
||||
<?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; ?>
|
||||
<a href="blog_create.php">+ New Post</a>
|
||||
|
||||
<?php while ($post = $posts->fetch_assoc()):
|
||||
// Output the HTML structure with dynamic data
|
||||
echo '
|
||||
<div class="destination-item style-three bgc-lighter booking" data-aos="fade-up" data-aos-duration="1500" data-aos-offset="50">
|
||||
<div class="image" style="width:200px;height:200px;"><img src="' . $post["image"] . '" alt="' . $post["title"] . '"></div>
|
||||
<div class="content" style="width:100%;">
|
||||
|
||||
<div class="destination-header">
|
||||
<span class="badge bg-dark"> ' . strtoupper($post["status"]) . '</span>
|
||||
</div>
|
||||
|
||||
<h5>' . $post["title"] . '</a></h5>
|
||||
<p>' . $post["description"] . '</p>
|
||||
<div class="destination-footer">
|
||||
<div class="btn-group" style="display:flex; justify-content:flex-end; gap:10px; margin-top:10px;">
|
||||
<a href="blog_edit.php?token='.encryptData($post["blog_id"], $salt).'" class="btn btn-sm" data-bs-toggle="tooltip" data-bs-placement="top" title="Edit"><i class="bi bi-pencil"></i></a>
|
||||
<a href="blog_read.php?token='.encryptData($post["blog_id"], $salt).'" class="btn btn-sm" data-bs-toggle="tooltip" data-bs-placement="top" title="Preview"><i class="bi bi-eye"></i></a>
|
||||
<a href="blog_delete.php?token='.encryptData($post["blog_id"], $salt).'" class="btn btn-sm" data-bs-toggle="tooltip" data-bs-placement="top" title="Delete"><i class="bi bi-trash"></i></a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
endwhile; ?>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Blog List Area end -->
|
||||
<script>
|
||||
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]');
|
||||
tooltipTriggerList.forEach(el => new bootstrap.Tooltip(el));
|
||||
</script>
|
||||
|
||||
|
||||
<?php include_once("insta_footer.php"); ?>
|
||||