minor update

This commit is contained in:
2025-08-26 13:24:30 +05:30
parent 15e8344d0e
commit 87515609ef
6 changed files with 225 additions and 209 deletions
Binary file not shown.
+4 -3
View File
@@ -83,7 +83,8 @@
<ul class="dropdown-menu dropdown-menu-end"> <ul class="dropdown-menu dropdown-menu-end">
{% if user.is_citizen %} {% if user.is_citizen %}
<li> <li>
<a class="dropdown-item" href="{% url 'citizen_dashboard' %}">Citizen Dashboard</a> <a class="dropdown-item" href="{% url 'citizen_dashboard' %}">
<i class="fas fa-users me-2 text-primary"></i>Citizen Dashboard</a>
</li> </li>
{% endif %} {% endif %}
@@ -97,7 +98,7 @@
{% if user.is_superuser %} {% if user.is_superuser %}
<li> <li>
<a class="dropdown-item text-danger fw-bold" href="{% url 'superadmin_dashboard' %}"> <a class="dropdown-item text-danger fw-bold" href="{% url 'superadmin_dashboard' %}">
<i class="fas fa-crown me-1"></i> Super Admin <i class="fas fa-crown me-1 text-warning fw-bold"></i> Super Admin
</a> </a>
</li> </li>
{% endif %} {% endif %}
@@ -108,7 +109,7 @@
<li> <li>
<form method="post" action="{% url 'logout' %}"> <form method="post" action="{% url 'logout' %}">
{% csrf_token %} {% csrf_token %}
<button type="submit" class="dropdown-item">Logout</button> <button type="submit" class="dropdown-item"><i class="fas fa-right-from-bracket me-2"></i>Logout</button>
</form> </form>
</li> </li>
</ul> </ul>
+207 -188
View File
@@ -1,147 +1,160 @@
{% extends "core/base.html" %} {% extends "core/base.html" %}
{% block content %} {% block content %}
<!-- Hero Section --> <!-- Hero Section -->
<section class="hero-section text-center"> <section class="hero-section text-center">
<div class="container"> <div class="container">
<h1 class="display-4 fw-bold mb-4">Report. Resolve. Rejoice.</h1> <h1 class="display-4 fw-bold mb-4">Report. Resolve. Rejoice.</h1>
<p class="lead mb-5">Your voice matters in making our community better. Report local issues and track their resolution in real-time.</p> <p class="lead mb-5">Your voice matters in making our community better. Report local issues and track their
<div class="d-grid gap-2 d-sm-flex justify-content-sm-center"> resolution in real-time.</p>
{% if user.is_authenticated %} <div class="d-grid gap-2 d-sm-flex justify-content-sm-center">
<a href="{% url 'citizen_dashboard' %}" class="btn btn-primary btn-lg px-4 gap-3">Report an Issue</a>
{% else %}
<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>
</div>
</section>
<!-- Stats Section -->
<section class="container mb-5">
<div class="row text-center">
<div class="col-md-3">
<h3 class="fw-bold text-primary">{{ total_issues|default:"0" }}+</h3>
<p class="text-muted">Issues Reported</p>
</div>
<div class="col-md-3">
<h3 class="fw-bold text-primary">Soon</h3>
<p class="text-muted">Issues Resolved</p>
</div>
<div class="col-md-3">
<h3 class="fw-bold text-primary">{{ active_users|default:"0" }}+</h3>
<p class="text-muted">Active Users</p>
</div>
<div class="col-md-3">
<h3 class="fw-bold text-primary">Soon</h3>
<p class="text-muted">Municipal Departments</p>
</div>
</div>
</section>
<!-- Features Section -->
<section id="features" class="container mb-5">
<div class="text-center mb-5">
<h2 class="fw-bold">Why Choose Civixfix?</h2>
<p class="lead text-muted">Transparent, efficient, and community-driven problem solving</p>
</div>
<div class="row g-4">
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<div class="feature-icon">
<i class="fas fa-map-marked-alt"></i>
</div>
<h5 class="card-title">Location-Based Reporting</h5>
<p class="card-text text-muted">Pinpoint issues on an interactive map for accurate location tracking and faster resolution.</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<div class="feature-icon">
<i class="fas fa-tasks"></i>
</div>
<h5 class="card-title">Real-Time Tracking</h5>
<p class="card-text text-muted">Follow your reported issues through every stage from reporting to resolution.</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<div class="feature-icon">
<i class="fas fa-users"></i>
</div>
<h5 class="card-title">Community Engagement</h5>
<p class="card-text text-muted">Vote and comment on issues to help prioritize what matters most to your neighborhood.</p>
</div>
</div>
</div>
</div>
</section>
<!-- How It Works Section -->
<section id="how-it-works" class="bg-light py-5 mb-5">
<div class="container">
<div class="text-center mb-5">
<h2 class="fw-bold">How Civixfix Works</h2>
<p class="lead text-muted">Simple steps to make your community better</p>
</div>
<div class="row g-4">
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<span class="badge bg-primary rounded-circle mb-3" style="width: 50px; height: 50px; line-height: 50px; font-size: 1.5rem;">1</span>
<h5 class="card-title">Report an Issue</h5>
<p class="card-text text-muted">Take a photo, add details, and drop a pin on the map to report problems in your area.</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<span class="badge bg-primary rounded-circle mb-3" style="width: 50px; height: 50px; line-height: 50px; font-size: 1.5rem;">2</span>
<h5 class="card-title">Community Support</h5>
<p class="card-text text-muted">Others can vote and comment to show support and add details to your report.</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<span class="badge bg-primary rounded-circle mb-3" style="width: 50px; height: 50px; line-height: 50px; font-size: 1.5rem;">3</span>
<h5 class="card-title">Official Response</h5>
<p class="card-text text-muted">Municipal authorities receive, prioritize, and work on resolving the issues.</p>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Recent Issues Section -->
<section class="container mb-5">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="fw-bold">Recently Reported Issues</h2>
{% if user.is_authenticated %} {% if user.is_authenticated %}
<a href="{% url 'view_all_issues' %}" class="btn btn-primary">View All Issues</a> <a href="{% url 'citizen_dashboard' %}" class="btn btn-primary btn-lg px-4 gap-3">Report an Issue</a>
{% else %} {% else %}
<a href="{% url 'login' %}" class="btn btn-outline-primary">View All Issues</a> <a href="{% url 'login' %}" class="btn btn-primary btn-lg px-4 gap-3">Report an Issue</a>
{% endif %} {% endif %}
<a href="#how-it-works" class="btn btn-outline-light btn-lg px-4">Learn More</a>
</div>
</div>
</section>
<!-- Stats Section -->
<section class="container mb-5">
<div class="row text-center">
<div class="col-md-3">
<h3 class="fw-bold text-primary">{{ total_issues|default:"0" }}+</h3>
<p class="text-muted">Issues Reported</p>
</div>
<div class="col-md-3">
<h3 class="fw-bold text-primary">{{ resolved_issues|default:"0" }}+</h3>
<p class="text-muted">Issues Resolved</p>
</div>
<div class="col-md-3">
<h3 class="fw-bold text-primary">{{ active_users|default:"0" }}+</h3>
<p class="text-muted">Active Users</p>
</div>
<div class="col-md-3">
<h3 class="fw-bold text-primary">{{ total_departments|default:"0" }}</h3>
<p class="text-muted">Municipal Departments</p>
</div>
</div>
</section>
<!-- Features Section -->
<section id="features" class="container mb-5">
<div class="text-center mb-5">
<h2 class="fw-bold">Why Choose Civixfix?</h2>
<p class="lead text-muted">Transparent, efficient, and community-driven problem solving</p>
</div>
<div class="row g-4">
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<div class="feature-icon">
<i class="fas fa-map-marked-alt"></i>
</div>
<h5 class="card-title">Location-Based Reporting</h5>
<p class="card-text text-muted">Pinpoint issues on an interactive map for accurate location tracking
and faster resolution.</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<div class="feature-icon">
<i class="fas fa-tasks"></i>
</div>
<h5 class="card-title">Real-Time Tracking</h5>
<p class="card-text text-muted">Follow your reported issues through every stage from reporting to
resolution.</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<div class="feature-icon">
<i class="fas fa-users"></i>
</div>
<h5 class="card-title">Community Engagement</h5>
<p class="card-text text-muted">Vote and comment on issues to help prioritize what matters most to
your neighborhood.</p>
</div>
</div>
</div>
</div>
</section>
<!-- How It Works Section -->
<section id="how-it-works" class="bg-light py-5 mb-5">
<div class="container">
<div class="text-center mb-5">
<h2 class="fw-bold">How Civixfix Works</h2>
<p class="lead text-muted">Simple steps to make your community better</p>
</div> </div>
<div class="row g-4"> <div class="row g-4">
{% for issue in recent_issues %}
<div class="col-md-4"> <div class="col-md-4">
<div class="card issue-card h-100"> <div class="card h-100 border-0 shadow-sm">
{% if issue.photo %} <div class="card-body text-center p-4">
<img src="{{ issue.photo.url }}" class="card-img-top" alt="{{ issue.title }}" style="height: 200px; object-fit: cover;"> <span class="badge bg-primary rounded-circle mb-3"
{% else %} style="width: 50px; height: 50px; line-height: 50px; font-size: 1.5rem;">1</span>
<img src="https://via.placeholder.com/300x200/6c757d/ffffff?text=No+Image" class="card-img-top" alt="No image"> <h5 class="card-title">Report an Issue</h5>
{% endif %} <p class="card-text text-muted">Take a photo, add details, and drop a pin on the map to report
<div class="card-body"> problems in your area.</p>
<span class="badge </div>
</div>
</div>
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<span class="badge bg-primary rounded-circle mb-3"
style="width: 50px; height: 50px; line-height: 50px; font-size: 1.5rem;">2</span>
<h5 class="card-title">Community Support</h5>
<p class="card-text text-muted">Others can vote and comment to show support and add details to
your report.</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<span class="badge bg-primary rounded-circle mb-3"
style="width: 50px; height: 50px; line-height: 50px; font-size: 1.5rem;">3</span>
<h5 class="card-title">Official Response</h5>
<p class="card-text text-muted">Municipal authorities receive, prioritize, and work on resolving
the issues.</p>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Recent Issues Section -->
<section class="container mb-5">
<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 'view_all_issues' %}" class="btn btn-primary">View All Issues</a>
{% else %}
<a href="{% url 'login' %}" class="btn btn-outline-primary">View All Issues</a>
{% endif %}
</div>
<div class="row g-4">
{% for issue in recent_issues %}
<div class="col-md-4">
<div class="card issue-card h-100">
{% if issue.photo %}
<img src="{{ issue.photo.url }}" class="card-img-top" alt="{{ issue.title }}"
style="height: 200px; object-fit: cover;">
{% else %}
<img src="https://via.placeholder.com/300x200/6c757d/ffffff?text=No+Image" class="card-img-top"
alt="No image">
{% endif %}
<div class="card-body">
<span class="badge
{% if issue.department.name == 'Roads & Transportation' %} bg-primary {% if issue.department.name == 'Roads & Transportation' %} bg-primary
{% elif issue.department.name == 'Sanitation & Waste Management' %} bg-success {% elif issue.department.name == 'Sanitation & Waste Management' %} bg-success
{% elif issue.department.name == 'Public Safety' %} bg-danger {% elif issue.department.name == 'Public Safety' %} bg-danger
@@ -152,68 +165,72 @@
{% elif issue.department.name == 'Public Works' %} bg-teal text-white {% elif issue.department.name == 'Public Works' %} bg-teal text-white
{% else %} bg-light text-dark {% else %} bg-light text-dark
{% endif %} mb-2"> {% endif %} mb-2">
{{ issue.department.name|default:"General" }} {{ issue.department.name|default:"General" }}
</span> </span>
<h5 class="card-title">{{ issue.title|truncatewords:5 }}</h5> <h5 class="card-title">{{ issue.title|truncatewords:5 }}</h5>
<p class="card-text text-muted">{{ issue.description|truncatewords:15 }}</p> <p class="card-text text-muted">{{ issue.description|truncatewords:15 }}</p>
<div class="d-flex justify-content-between align-items-center"> <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-map-marker-alt me-1"></i> {{ issue.location|truncatewords:2 }}</small>
<!-- Vote Button --> <!-- Vote Button -->
<div class="vote-section"> <div class="vote-section">
{% if user.is_authenticated %} {% if user.is_authenticated %}
<button class="btn btn-sm btn-outline-primary vote-btn {% if issue.user_has_voted %}active{% endif %}" <button
data-issue-id="{{ issue.id }}"> class="btn btn-sm btn-outline-primary vote-btn {% if issue.user_has_voted %}active{% endif %}"
<i class="fas fa-thumbs-up"></i> data-issue-id="{{ issue.id }}">
<span class="vote-count">{{ issue.vote_count }}</span> <i class="fas fa-thumbs-up"></i>
</button> <span class="vote-count">{{ issue.vote_count }}</span>
{% else %} </button>
<a href="{% url 'login' %}" class="btn btn-sm btn-outline-primary"> {% else %}
<i class="fas fa-thumbs-up"></i> <a href="{% url 'login' %}" class="btn btn-sm btn-outline-primary">
<span class="vote-count">{{ issue.vote_count }}</span> <i class="fas fa-thumbs-up"></i>
</a> <span class="vote-count">{{ issue.vote_count }}</span>
{% endif %} </a>
</div> {% endif %}
</div> </div>
</div> </div>
<div class="card-footer bg-transparent"> </div>
<small class="text-{% if issue.status == 'resolved' %}success{% elif issue.status == 'in_progress' %}warning{% else %}info{% endif %}"> <div class="card-footer bg-transparent">
<i class="fas fa-{% if issue.status == 'resolved' %}check-circle{% elif issue.status == 'in_progress' %}tasks{% else %}clock{% endif %} me-1"></i> <small
{{ issue.get_status_display }} class="text-{% if issue.status == 'resolved' %}success{% elif issue.status == 'in_progress' %}warning{% else %}info{% endif %}">
</small> <i
</div> class="fas fa-{% if issue.status == 'resolved' %}check-circle{% elif issue.status == 'in_progress' %}tasks{% else %}clock{% endif %} me-1"></i>
{{ issue.get_status_display }}
</small>
</div> </div>
</div> </div>
{% empty %}
<div class="col-12 text-center py-5">
<i class="fas fa-inbox fa-3x text-muted mb-3"></i>
<h4>No issues reported yet</h4>
<p class="text-muted">Be the first to report an issue in your community!</p>
<a href="{% url 'login' %}" class="btn btn-primary">Get Started</a>
</div>
{% endfor %}
</div> </div>
</section> {% empty %}
<div class="col-12 text-center py-5">
<i class="fas fa-inbox fa-3x text-muted mb-3"></i>
<h4>No issues reported yet</h4>
<p class="text-muted">Be the first to report an issue in your community!</p>
<a href="{% url 'login' %}" class="btn btn-primary">Get Started</a>
</div>
{% endfor %}
</div>
</section>
<!-- Call to Action --> <!-- Call to Action -->
<section class="bg-primary text-white py-5"> <section class="bg-primary text-white py-5">
<div class="container text-center"> <div class="container text-center">
<h2 class="fw-bold mb-4">Ready to make a difference in your community?</h2> <h2 class="fw-bold mb-4">Ready to make a difference in your community?</h2>
<p class="lead mb-4">Join {{ active_users|default:"thousands of" }} citizens who are actively improving their neighborhoods.</p> <p class="lead mb-4">Join {{ active_users|default:"thousands of" }} citizens who are actively improving their
{% if user.is_authenticated %} neighborhoods.</p>
<a href="{% url 'citizen_dashboard' %}" class="btn btn-light btn-lg px-4">Report an Issue</a> {% if user.is_authenticated %}
{% else %} <a href="{% url 'citizen_dashboard' %}" class="btn btn-light btn-lg px-4">Report an Issue</a>
<a href="{% url 'login' %}" class="btn btn-light btn-lg px-4">Get Started Now</a> {% else %}
{% endif %} <a href="{% url 'login' %}" class="btn btn-light btn-lg px-4">Get Started Now</a>
</div> {% endif %}
</section> </div>
</section>
{% endblock %} {% endblock %}
{% block extra_js %} {% block extra_js %}
<script> <script>
$(document).ready(function() { $(document).ready(function () {
// Vote functionality // Vote functionality
$('.vote-btn').click(function() { $('.vote-btn').click(function () {
const issueId = $(this).data('issue-id'); const issueId = $(this).data('issue-id');
const button = $(this); const button = $(this);
@@ -229,7 +246,7 @@
headers: { headers: {
'X-CSRFToken': '{{ csrf_token }}' 'X-CSRFToken': '{{ csrf_token }}'
}, },
success: function(response) { success: function (response) {
if (response.success) { if (response.success) {
// Update button state // Update button state
if (response.voted) { if (response.voted) {
@@ -248,11 +265,11 @@
button.html(originalHtml); button.html(originalHtml);
} }
}, },
error: function() { error: function () {
alert('Error voting. Please try again.'); alert('Error voting. Please try again.');
button.html(originalHtml); button.html(originalHtml);
}, },
complete: function() { complete: function () {
button.prop('disabled', false); button.prop('disabled', false);
} }
}); });
@@ -266,10 +283,12 @@
color: white; color: white;
border-color: #0d6efd; border-color: #0d6efd;
} }
.vote-btn:hover:not(:disabled) { .vote-btn:hover:not(:disabled) {
transform: scale(1.05); transform: scale(1.05);
transition: transform 0.2s; transition: transform 0.2s;
} }
.vote-btn:disabled { .vote-btn:disabled {
opacity: 0.7; opacity: 0.7;
cursor: not-allowed; cursor: not-allowed;
@@ -7,7 +7,7 @@
<h3>Super Admin Dashboard</h3> <h3>Super Admin Dashboard</h3>
</div> </div>
<div class="card-body"> <div class="card-body">
<p>Welcome, {{ request.user.username }} 👑</p> <p>Welcome, {{ request.user.username }} <i class="fas fa-crown text-warning fw-bold"></i></p>
<ul class="list-group"> <ul class="list-group">
<li class="list-group-item"> <li class="list-group-item">
@@ -19,17 +19,14 @@
<a href="{% url 'manage_departments' %}">Manage Departments</a> <a href="{% url 'manage_departments' %}">Manage Departments</a>
</li> </li>
<li class="list-group-item"> <li class="list-group-item">
<i class="fas fa-exclamation-circle me-2 text-danger"></i>
<a href="{% url 'manage_issues' %}">Manage Issues</a> <a href="{% url 'manage_issues' %}">Manage Issues</a>
</li> </li>
<li class="list-group-item"> <li class="list-group-item">
<a href="#">Manage Roles & Permissions</a> <i class="fas fa-chart-line me-2 text-warning"></i>
</li>
<li class="list-group-item">
<a href="#">View Analytics & Reports</a> <a href="#">View Analytics & Reports</a>
</li> </li>
<li class="list-group-item">
<a href="#">System Settings</a>
</li>
</ul> </ul>
</div> </div>
</div> </div>
@@ -38,7 +38,7 @@
<input type="text" name="description" class="form-control" placeholder="Description (optional)"> <input type="text" name="description" class="form-control" placeholder="Description (optional)">
</div> </div>
<div class="col-md-2"> <div class="col-md-2">
<button type="submit" class="btn btn-success w-100">Add</button> <button type="submit" class="btn btn-success w-100"><i class="fas fa-plus me-2"></i>Add</button>
</div> </div>
</div> </div>
</form> </form>
+4 -5
View File
@@ -2,32 +2,31 @@ from django.contrib import messages
from django.contrib.auth import authenticate, login from django.contrib.auth import authenticate, login
from django.contrib.auth.decorators import login_required, user_passes_test from django.contrib.auth.decorators import login_required, user_passes_test
from django.contrib.auth.forms import AuthenticationForm from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.hashers import make_password
from django.db import IntegrityError from django.db import IntegrityError
from django.db.models import Exists, OuterRef from django.db.models import Exists, OuterRef
from django.http import JsonResponse from django.http import JsonResponse
from django.shortcuts import render, redirect, get_object_or_404 from django.shortcuts import render, redirect, get_object_or_404
from django.views.decorators.http import require_POST from django.views.decorators.http import require_POST
from .models import Issue, User, Vote, Comment, Department from .models import Issue, User, Vote, Comment, Department
from .forms import CitizenRegistrationForm, IssueForm, CommentForm, IssueAssignForm from .forms import CitizenRegistrationForm, IssueForm, CommentForm
def home(request): def home(request):
total_issues = Issue.objects.count() total_issues = Issue.objects.count()
resolved_issues = Issue.objects.filter(status='resolved').count() resolved_issues = Issue.objects.filter(status=Issue.STATUS_RESOLVED).count()
active_users = User.objects.filter(is_active=True).count() active_users = User.objects.filter(is_active=True).count()
total_departments = Department.objects.count()
recent_issues = Issue.objects.all().order_by('-created_at')[:3] recent_issues = Issue.objects.all().order_by('-created_at')[:3]
for issue in recent_issues: for issue in recent_issues:
issue.user_has_voted = issue.has_user_voted(request.user) if request.user.is_authenticated else False issue.user_has_voted = issue.has_user_voted(request.user) if request.user.is_authenticated else False
municipal_departments = 5
context = { context = {
'total_issues': total_issues, 'total_issues': total_issues,
'resolved_issues': resolved_issues, 'resolved_issues': resolved_issues,
'active_users': active_users, 'active_users': active_users,
'municipal_departments': municipal_departments, 'total_departments': total_departments,
'recent_issues': recent_issues, 'recent_issues': recent_issues,
} }
return render(request, 'core/index.html', context) return render(request, 'core/index.html', context)