feat(department): surface appreciations on the department dashboard

Per the workflow realignment, the point of appreciation is recognition —
managers should see the appreciations their department received alongside
other feedback. Adds an 'Appreciations Received' card (amber theme) after
the Pending Actions section, showing the count and the 10 most recent
SENT appreciations. The card only renders when the department has at
least one appreciation.
This commit is contained in:
ismail 2026-07-20 22:23:35 +03:00
parent 295ff298a8
commit 85980f232b
2 changed files with 54 additions and 0 deletions

View File

@ -2326,9 +2326,34 @@ def department_detail(request, pk):
.filter(Q(champion__isnull=False) | Q(manager__isnull=False))
.order_by("name")
),
# Appreciations received by this department (SENT = terminal/recognized).
# Surfaced so managers see recognition alongside other feedback.
"dept_appreciations": _dept_appreciations_qs(department),
"dept_appreciations_count": _dept_appreciations_count(department),
}
return render(request, "organizations/department_detail.html", context)
def _dept_appreciations_qs(department):
"""Recent SENT appreciations for the department detail dashboard."""
from apps.appreciation.models import Appreciation, AppreciationStatus
return (
Appreciation.objects.filter(
department=department,
status=AppreciationStatus.SENT,
).select_related("sender", "category").order_by("-sent_at")[:10]
)
def _dept_appreciations_count(department):
"""Total SENT appreciations for the department detail dashboard."""
from apps.appreciation.models import Appreciation, AppreciationStatus
return Appreciation.objects.filter(
department=department,
status=AppreciationStatus.SENT,
).count()
def _check_department_access(user, department):
if user.is_px_admin():
return True

View File

@ -239,6 +239,35 @@
</div>
{% endif %}
{% if dept_appreciations_count > 0 %}
<!-- Appreciations received by this department (recognition) -->
<div class="bg-gradient-to-br from-amber-50 to-yellow-50 border border-amber-200 rounded-2xl p-5 my-4">
<div class="flex items-center justify-between mb-3">
<div class="flex items-center gap-2">
<div class="w-8 h-8 rounded-full bg-amber-100 flex items-center justify-center">
<i data-lucide="award" class="w-4 h-4 text-amber-600"></i>
</div>
<h3 class="text-sm font-bold text-navy">{% trans "Appreciations Received" %}</h3>
</div>
<span class="text-2xl font-bold text-amber-600">{{ dept_appreciations_count }}</span>
</div>
<ul class="space-y-2">
{% for apr in dept_appreciations %}
<li class="text-xs text-slate-700 flex items-start gap-2 bg-white/60 rounded-lg p-2">
<i data-lucide="quote" class="w-3 h-3 mt-0.5 shrink-0 text-amber-500"></i>
<span class="flex-1">
{{ apr.message_en|default:apr.message_ar|truncatewords:18 }}
<span class="block text-[10px] text-slate-400 mt-0.5">
{{ apr.sent_at|date:"M d, Y" }}
{% if apr.sender %}· {{ apr.sender.get_full_name }}{% endif %}
</span>
</span>
</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if can_respond and pending_routing_involvements %}
<!-- Reject routing forms (for "Wrong Dept" buttons in the Pending Actions table) -->
{% for inv in pending_routing_involvements %}