234 lines
11 KiB
HTML
234 lines
11 KiB
HTML
{% extends 'base.html' %}
|
|
{% load static i18n %}
|
|
|
|
{% block title %}{% trans "Notifications" %} - ATS{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid py-4">
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<div>
|
|
<h1 class="h3 mb-1" style="color: var(--kaauh-teal-dark); font-weight: 700;">
|
|
<i class="fas fa-bell me-2"></i>
|
|
{% trans "Notifications" %}
|
|
</h1>
|
|
<p class="text-muted mb-0">
|
|
{% blocktrans count count=total_notifications %}
|
|
{{ count }} notification
|
|
{% plural %}
|
|
{{ count }} notifications
|
|
{% endblocktrans %}
|
|
{% if unread_notifications %}({{ unread_notifications }} unread){% endif %}
|
|
</p>
|
|
</div>
|
|
<div class="d-flex gap-2">
|
|
{% if unread_notifications %}
|
|
<a href="{% url 'notification_mark_all_read' %}" class="btn btn-outline-secondary">
|
|
<i class="fas fa-check-double me-1"></i> {% trans "Mark All Read" %}
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Filters -->
|
|
<div class="card mb-4">
|
|
<div class="card-body">
|
|
<form method="get" class="row g-3">
|
|
<div class="col-md-3">
|
|
<label for="status_filter" class="form-label">{% trans "Status" %}</label>
|
|
<select name="status" id="status_filter" class="form-select">
|
|
<option value="">{% trans "All Status" %}</option>
|
|
<option value="unread" {% if status_filter == 'unread' %}selected{% endif %}>{% trans "Unread" %}</option>
|
|
<option value="read" {% if status_filter == 'read' %}selected{% endif %}>{% trans "Read" %}</option>
|
|
<option value="sent" {% if status_filter == 'sent' %}selected{% endif %}>{% trans "Sent" %}</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label for="type_filter" class="form-label">{% trans "Type" %}</label>
|
|
<select name="type" id="type_filter" class="form-select">
|
|
<option value="">{% trans "All Types" %}</option>
|
|
<option value="in_app" {% if type_filter == 'in_app' %}selected{% endif %}>{% trans "In-App" %}</option>
|
|
<option value="email" {% if type_filter == 'email' %}selected{% endif %}>{% trans "Email" %}</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label"> </label>
|
|
<div class="d-flex gap-2">
|
|
<button type="submit" class="btn btn-main-action">
|
|
<i class="fas fa-filter me-1"></i> {% trans "Filter" %}
|
|
</button>
|
|
<a href="{% url 'notification_list' %}" class="btn btn-outline-secondary">
|
|
<i class="fas fa-times me-1"></i> {% trans "Clear" %}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Statistics -->
|
|
<div class="row mb-4">
|
|
<div class="col-md-4">
|
|
<div class="card border-primary">
|
|
<div class="card-body text-center">
|
|
<h5 class="card-title text-primary">{{ total_notifications }}</h5>
|
|
<p class="card-text">{% trans "Total Notifications" %}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="card border-warning">
|
|
<div class="card-body text-center">
|
|
<h5 class="card-title text-warning">{{ unread_notifications }}</h5>
|
|
<p class="card-text">{% trans "Unread" %}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="card border-info">
|
|
<div class="card-body text-center">
|
|
<h5 class="card-title text-info">{{ email_notifications }}</h5>
|
|
<p class="card-text">{% trans "Email Notifications" %}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Notifications List -->
|
|
{% if page_obj %}
|
|
<div class="card">
|
|
<div class="card-body p-0">
|
|
<div class="list-group list-group-flush">
|
|
{% for notification in page_obj %}
|
|
<div class="list-group-item list-group-item-action {% if notification.status == 'PENDING' %}bg-light{% endif %}">
|
|
<div class="d-flex justify-content-between align-items-start">
|
|
<div class="flex-grow-1">
|
|
<div class="d-flex align-items-center mb-2">
|
|
<span class="badge bg-{{ notification.get_status_bootstrap_class }} me-2">
|
|
{{ notification.get_status_display }}
|
|
</span>
|
|
<span class="badge bg-secondary me-2">
|
|
{{ notification.get_notification_type_display }}
|
|
</span>
|
|
<small class="text-muted">{{ notification.created_at|date:"Y-m-d H:i" }}</small>
|
|
</div>
|
|
<h6 class="mb-1">
|
|
<a href="{% url 'notification_detail' notification.id %}" class="text-decoration-none {% if notification.status == 'PENDING' %}fw-bold{% endif %}">
|
|
{{ notification.message|truncatewords:15 }}
|
|
</a>
|
|
</h6>
|
|
{% if notification.related_meeting %}
|
|
<small class="text-muted">
|
|
<i class="fas fa-video me-1"></i>
|
|
{% trans "Related to meeting:" %} {{ notification.related_meeting.topic }}
|
|
</small>
|
|
{% endif %}
|
|
</div>
|
|
<div class="d-flex flex-column gap-1">
|
|
{% if notification.status == 'PENDING' %}
|
|
<a href="{% url 'notification_mark_read' notification.id %}"
|
|
class="btn btn-sm btn-outline-success"
|
|
title="{% trans 'Mark as read' %}">
|
|
<i class="fas fa-check"></i>
|
|
</a>
|
|
{% else %}
|
|
<a href="{% url 'notification_mark_unread' notification.id %}"
|
|
class="btn btn-sm btn-outline-secondary"
|
|
title="{% trans 'Mark as unread' %}">
|
|
<i class="fas fa-envelope"></i>
|
|
</a>
|
|
{% endif %}
|
|
<a href="{% url 'notification_delete' notification.id %}"
|
|
class="btn btn-sm btn-outline-danger"
|
|
title="{% trans 'Delete notification' %}">
|
|
<i class="fas fa-trash"></i>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Pagination -->
|
|
{% if page_obj.has_other_pages %}
|
|
<nav aria-label="{% trans 'Notifications pagination' %}" class="mt-4">
|
|
<ul class="pagination justify-content-center">
|
|
{% if page_obj.has_previous %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ page_obj.previous_page_number }}&status={{ status_filter }}&type={{ type_filter }}">
|
|
<i class="fas fa-chevron-left"></i>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
|
|
{% for num in page_obj.paginator.page_range %}
|
|
{% if page_obj.number == num %}
|
|
<li class="page-item active">
|
|
<span class="page-link">{{ num }}</span>
|
|
</li>
|
|
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ num }}&status={{ status_filter }}&type={{ type_filter }}">{{ num }}</a>
|
|
</li>
|
|
{% endif %}
|
|
{% endfor %}
|
|
|
|
{% if page_obj.has_next %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ page_obj.next_page_number }}&status={{ status_filter }}&type={{ type_filter }}">
|
|
<i class="fas fa-chevron-right"></i>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
</nav>
|
|
{% endif %}
|
|
{% else %}
|
|
<div class="text-center py-5">
|
|
<i class="fas fa-bell-slash fa-3x text-muted mb-3"></i>
|
|
<h5 class="text-muted">{% trans "No notifications found" %}</h5>
|
|
<p class="text-muted">
|
|
{% if status_filter or type_filter %}
|
|
{% trans "Try adjusting your filters to see more notifications." %}
|
|
{% else %}
|
|
{% trans "You don't have any notifications yet." %}
|
|
{% endif %}
|
|
</p>
|
|
{% if status_filter or type_filter %}
|
|
<a href="{% url 'notification_list' %}" class="btn btn-main-action">
|
|
<i class="fas fa-times me-1"></i> {% trans "Clear Filters" %}
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block customJS %}
|
|
<script>
|
|
/*
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Auto-refresh notifications every 30 seconds
|
|
setInterval(function() {
|
|
fetch('/api/notification-count/')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
// Update notification badge if it exists
|
|
const badge = document.querySelector('.notification-badge');
|
|
if (badge) {
|
|
badge.textContent = data.count;
|
|
if (data.count > 0) {
|
|
badge.classList.remove('d-none');
|
|
} else {
|
|
badge.classList.add('d-none');
|
|
}
|
|
}
|
|
})
|
|
.catch(error => console.error('Error fetching notifications:', error));
|
|
}, 30000);
|
|
});
|
|
*/
|
|
</script>
|
|
{% endblock %}
|