Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions website/static/js/blog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* Blog functionality
*/
document.addEventListener('DOMContentLoaded', function() {
// Search functionality
const searchInput = document.getElementById('post-search');
const blogCards = document.querySelectorAll('.blog-card');

if (searchInput && blogCards.length > 0) {
searchInput.addEventListener('input', function() {
const searchTerm = this.value.toLowerCase().trim();

blogCards.forEach(card => {
const title = card.querySelector('h2').textContent.toLowerCase();
const authorElement = card.querySelector('.text-white.text-sm.font-medium');
const author = authorElement ? authorElement.textContent.toLowerCase() : '';

if (title.includes(searchTerm) || author.includes(searchTerm)) {
card.classList.remove('hidden');
card.classList.add('block');
} else {
card.classList.remove('block');
card.classList.add('hidden');
}
});

checkEmptyState();
});
}

function checkEmptyState() {
const visibleCards = document.querySelectorAll('.blog-card:not(.hidden)');
const grid = document.querySelector('.blog-grid');
const existingEmptyState = document.querySelector('.empty-state-message');

if (visibleCards.length === 0 && !existingEmptyState && searchInput.value.trim() !== '') {
const emptyState = document.createElement('div');
emptyState.className = 'empty-state-message col-span-full flex flex-col items-center justify-center py-16 text-center';
emptyState.innerHTML = `
<svg class="w-16 h-16 text-red-500 opacity-50 mb-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
<h2 class="text-xl font-semibold text-gray-700 mb-2">No matching posts found</h2>
<p class="text-gray-500 max-w-md">Try adjusting your search criteria or browse all posts below.</p>
`;
grid.appendChild(emptyState);
} else if ((visibleCards.length > 0 || searchInput.value.trim() === '') && existingEmptyState) {
existingEmptyState.remove();
}
}

// Style blog content links to be blue
const blogContent = document.querySelector('.blog-content');
if (blogContent) {
const links = blogContent.querySelectorAll('a');
links.forEach(link => {
// Apply blue styling to all links in blog content
link.classList.add('text-blue-600', 'hover:text-blue-800', 'hover:underline');
link.style.color = '#2563eb'; // Ensures the color is applied even if CSS classes don't load

// Add hover event listeners for better control
link.addEventListener('mouseenter', function() {
this.style.color = '#1d4ed8';
this.style.textDecoration = 'underline';
});

link.addEventListener('mouseleave', function() {
this.style.color = '#2563eb';
this.style.textDecoration = 'none';
});
});
}

// Smooth scroll to comments
const commentLinks = document.querySelectorAll('[href="#comments"]');
commentLinks.forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
const commentsSection = document.getElementById('comment_root');
if (commentsSection) {
commentsSection.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});

// Blog card hover effects
const cards = document.querySelectorAll('.blog-card');
cards.forEach(card => {
card.addEventListener('mouseenter', function() {
this.classList.add('transform', 'scale-105');
});

card.addEventListener('mouseleave', function() {
this.classList.remove('transform', 'scale-105');
});
});
});
3 changes: 2 additions & 1 deletion website/templates/blog/post_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<article class="max-w-3xl mx-auto bg-white rounded-lg shadow-md p-6">
<h1 class="text-4xl font-bold text-gray-900 text-center mb-4">{{ post.title }}</h1>
<p class="text-gray-600 text-center mb-6">By {{ post.author }} on {{ post.created_at }}</p>
<div class="text-gray-700 leading-relaxed">{{ post.content | safe }}</div>
<div class="text-gray-700 leading-relaxed blog-content">{{ post.content | safe }}</div>
{% if post.image %}
<div class="my-6">
<img class="w-full h-auto rounded-lg shadow-lg"
Expand All @@ -47,4 +47,5 @@ <h1 class="text-4xl font-bold text-gray-900 text-center mb-4">{{ post.title }}</
<div class="mt-8 px-6 py-4 bg-white rounded-lg">{% include "../comments2.html" %}</div>
</article>
</div>
<script src="{% static 'js/blog.js' %}"></script>
{% endblock content %}
50 changes: 3 additions & 47 deletions website/templates/blog/post_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ <h2 class="text-xl font-bold text-gray-900 mb-2 line-clamp-2 group-hover:text-[#
</div>
<!-- Read More -->
<a href="{% url 'post_detail' slug=post.slug %}"
class="inline-flex items-center font-medium text-[#e74c3c] hover:text-[#c0392b] transition-colors">
class="inline-flex items-center font-medium text-blue-600 hover:text-blue-800 transition-colors">
Read more
<svg class="ml-1 h-4 w-4"
xmlns="http://www.w3.org/2000/svg"
Expand Down Expand Up @@ -164,50 +164,6 @@ <h2 class="text-2xl font-semibold text-gray-700">No posts available yet</h2>
</svg>
<span class="sr-only">New Blog Post</span>
</a>
<!-- Search JavaScript -->
<script>
document.addEventListener('DOMContentLoaded', function() {
// Search functionality
const searchInput = document.getElementById('post-search');
const blogCards = document.querySelectorAll('.blog-card');

searchInput.addEventListener('input', function() {
const searchTerm = this.value.toLowerCase().trim();

blogCards.forEach(card => {
const title = card.querySelector('h2').textContent.toLowerCase();
const author = card.querySelector('.text-white.text-sm').textContent.toLowerCase();

if (title.includes(searchTerm) || author.includes(searchTerm)) {
card.style.display = 'block';
} else {
card.style.display = 'none';
}
});

checkEmptyState();
});

function checkEmptyState() {
const visibleCards = document.querySelectorAll('.blog-card[style="display: block"]');
const grid = document.querySelector('.blog-grid');
const existingEmptyState = document.querySelector('.empty-state-message');

if (visibleCards.length === 0 && !existingEmptyState) {
const emptyState = document.createElement('div');
emptyState.className = 'empty-state-message col-span-full flex flex-col items-center justify-center py-16 text-center';
emptyState.innerHTML = `
<svg class="w-24 h-24 text-[#e74c3c] opacity-50 mb-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z" />
</svg>
<h2 class="text-2xl font-semibold text-gray-700">No matching posts found</h2>
<p class="mt-2 text-gray-500 max-w-md">Try adjusting your search criteria</p>
`;
grid.appendChild(emptyState);
} else if (visibleCards.length > 0 && existingEmptyState) {
existingEmptyState.remove();
}
}
});
</script>
<!-- Blog JavaScript -->
<script src="{% static 'js/blog.js' %}"></script>
{% endblock content %}