Files
4WDCSA.co.za/src/pages/blog/admin_blogs.php
twotalesanimation bbc0aecbcb force update CSS2
2025-12-08 10:55:08 +02:00

165 lines
6.8 KiB
PHP

<?php
$rootPath = dirname(dirname(dirname(__DIR__)));
require_once($rootPath . "/src/config/env.php");
require_once($rootPath . "/src/config/connection.php");
require_once($rootPath . "/src/config/functions.php");
require_once($rootPath . "/header.php");
checkAdmin();
checkUserSession();
$pageTitle = 'Manage Blog Posts';
$breadcrumbs = [['Home' => 'index']];
require_once($rootPath . '/components/banner.php');
$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 = 'published'
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);
?>
<!-- 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>Manage Blog 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'">&times;</span>
</div>
<?php unset($_SESSION['message']); ?>
<?php endif; ?>
<a href="blog_create.php">+ New Post</a>
<?php while ($post = $posts->fetch_assoc()):
// Determine cover image - use provided image or fallback placeholder
$coverImage = $post["image"] ? $post["image"] : 'assets/images/placeholder.jpg';
// 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="' . htmlspecialchars($coverImage) . '" alt="' . htmlspecialchars($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;">
<a href="blog_edit.php?token=' . encryptData($post["blog_id"], $salt) . '" data-bs-toggle="tooltip" data-bs-placement="top" title="Edit"><span class="material-icons">edit</span></a>
<a href="blog_read.php?token=' . encryptData($post["blog_id"], $salt) . '" data-bs-toggle="tooltip" data-bs-placement="top" title="Preview"><span class="material-icons">visibility</span></a>
<button type="button" class="publish-btn" data-blog-id="' . $post["blog_id"] . '" data-status="' . $post["status"] . '" data-bs-toggle="tooltip" data-bs-placement="top" title="' . ($post["status"] == "published" ? "Unpublish" : "Publish") . '" style="background:none; border:none; cursor:pointer; color:inherit;"><span class="material-icons">' . ($post["status"] == "published" ? "cloud_off" : "cloud_upload") . '</span></button>
<a href="blog_delete.php?token=' . encryptData($post["blog_id"], $salt) . '" data-bs-toggle="tooltip" data-bs-placement="top" title="Delete"><span class="material-icons">delete</span></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));
// Handle publish/unpublish button clicks
document.querySelectorAll('.publish-btn').forEach(btn => {
btn.addEventListener('click', function() {
const blogId = this.dataset.blogId;
const status = this.dataset.status;
const action = status === 'published' ? 'unpublish' : 'publish';
const endpoint = status === 'published' ? 'blog_unpublish' : 'publish_blog';
const formData = new FormData();
formData.append('id', blogId);
fetch(endpoint, {
method: 'POST',
body: formData
})
.then(response => {
if (response.ok) {
alert(action.charAt(0).toUpperCase() + action.slice(1) + ' successful!');
location.reload();
} else {
alert(action + ' failed.');
console.error('Error:', response.statusText);
}
})
.catch(err => {
console.error('Error:', err);
alert(action + ' failed due to network error.');
});
});
});
</script>
<?php include_once($rootPath . '/components/insta_footer.php'); ?>