vote csrf & ajax

This commit is contained in:
2025-08-22 05:18:39 +05:30
parent f34b412cc9
commit 631605ed0e
+86 -3
View File
@@ -10,7 +10,7 @@
{% if user.is_authenticated %}
<a href="{% url 'citizen_dashboard' %}" class="btn btn-primary btn-lg px-4 gap-3">Report an Issue</a>
{% else %}
<a href="{% url 'register' %}" class="btn btn-primary btn-lg px-4 gap-3">Report an Issue</a>
<a href="{% url 'login' %}" class="btn btn-primary btn-lg px-4 gap-3">Report an Issue</a>
{% endif %}
<a href="#how-it-works" class="btn btn-outline-light btn-lg px-4">Learn More</a>
</div>
@@ -126,7 +126,7 @@
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="fw-bold">Recently Reported Issues</h2>
{% if user.is_authenticated %}
<a href="{% url 'citizen_dashboard' %}" class="btn btn-outline-primary">View All Issues</a>
<a href="{% url 'view_all_issues' %}" class="btn btn-primary">View All Issues</a>
{% else %}
<a href="{% url 'register' %}" class="btn btn-outline-primary">View All Issues</a>
{% endif %}
@@ -148,7 +148,22 @@
<p class="card-text text-muted">{{ issue.description|truncatewords:15 }}</p>
<div class="d-flex justify-content-between align-items-center">
<small class="text-muted"><i class="fas fa-map-marker-alt me-1"></i> {{ issue.location|truncatewords:2 }}</small>
<small class="text-muted"><i class="fas fa-thumbs-up me-1"></i> {{ issue.votes.count|default:"0" }}</small>
<!-- Vote Button -->
<div class="vote-section">
{% if user.is_authenticated %}
<button class="btn btn-sm btn-outline-primary vote-btn {% if issue.user_has_voted %}active{% endif %}"
data-issue-id="{{ issue.id }}">
<i class="fas fa-thumbs-up"></i>
<span class="vote-count">{{ issue.vote_count }}</span>
</button>
{% else %}
<a href="{% url 'login' %}" class="btn btn-sm btn-outline-primary">
<i class="fas fa-thumbs-up"></i>
<span class="vote-count">{{ issue.vote_count }}</span>
</a>
{% endif %}
</div>
</div>
</div>
<div class="card-footer bg-transparent">
@@ -182,4 +197,72 @@
{% endif %}
</div>
</section>
{% endblock %}
{% block extra_js %}
<script>
$(document).ready(function() {
// Vote functionality
$('.vote-btn').click(function() {
const issueId = $(this).data('issue-id');
const button = $(this);
// Show loading state
const originalHtml = button.html();
button.prop('disabled', true);
button.html('<i class="fas fa-spinner fa-spin"></i>');
// Send vote request
$.ajax({
url: "{% url 'vote_issue' 0 %}".replace('0', issueId),
type: 'POST',
headers: {
'X-CSRFToken': '{{ csrf_token }}'
},
success: function(response) {
if (response.success) {
// Update button state
if (response.voted) {
button.addClass('active');
} else {
button.removeClass('active');
}
// Update vote count
button.find('.vote-count').text(response.vote_count);
// Update button text
button.html('<i class="fas fa-thumbs-up"></i> <span class="vote-count">' + response.vote_count + '</span>');
} else {
alert('Error: ' + response.error);
button.html(originalHtml);
}
},
error: function() {
alert('Error voting. Please try again.');
button.html(originalHtml);
},
complete: function() {
button.prop('disabled', false);
}
});
});
});
</script>
<style>
.vote-btn.active {
background-color: #0d6efd;
color: white;
border-color: #0d6efd;
}
.vote-btn:hover:not(:disabled) {
transform: scale(1.05);
transition: transform 0.2s;
}
.vote-btn:disabled {
opacity: 0.7;
cursor: not-allowed;
}
</style>
{% endblock %}